我正在开发图像处理软件(只是为了好玩),它的功能之一是图像调整大小选项。基本上会弹出一个窗口,其中包含两个JTextArea组件以获取所需的图像宽度和高度以进行大小调整。如果用户需要,还可以使用JCheckBox保持宽高比。问题是。选中复选框后,用户应该首先输入宽度或高度。我希望其他文本区域在每次更改时都相应地进行更新,以便保留AR。我已经开发了一些用于处理此问题的代码,但是由于缺乏对我应该真正分配哪个组件的了解,所以它不能提供我真正想要的。

码:

String height, width;
  if (checkBoxImage.isSelected()){
      // aspect ratio = width / height
      width = widthArea.getText();
      height = heightArea.getText();
      double aspectRatio = (double) images.get(tabbedPane.getSelectedIndex()).getWidth() / images.get(tabbedPane.getSelectedIndex()).getHeight();
      /**
       * to do, update width, height area
       * to the closest user input
       */
      if(heightArea.getText().length() != 0 && heightArea.getText().length() <= 5
              && heightArea.getText().charAt(0) != '0'){
          //parsing string to integer
          try{
              int heightNum = Integer.parseInt(height);
              int widthNum = (int) Math.round(aspectRatio * heightNum);
              widthArea.setText(String.valueOf(widthNum) );
              widthArea.updateUI();
              frameimgSize.repaint();
          }
          catch(NumberFormatException e1){JOptionPane.showMessageDialog(error,e1.getMessage(),"Error", JOptionPane.ERROR_MESSAGE);}
      }
      //width has been entered first
      else if(widthArea.getText().length() != 0 && widthArea.getText().length() <= 5 &&
              widthArea.getText().charAt(0) != '0'){
          try{
              int widthNum = Integer.parseInt(width);
              int heightNum = (int) Math.round(aspectRatio * widthNum);
              heightArea.setText(String.valueOf(heightNum) );
              heightArea.updateUI();
              frameimgSize.repaint();
          }
          catch(NumberFormatException e1){JOptionPane.showMessageDialog(error,e1.getMessage(),"Error", JOptionPane.ERROR_MESSAGE);}
      }
  }

最佳答案

在宽度和高度字段中使用非数字值是否有效?

如果不是,则使用JSpinnersJFormattedTextFields代替JTextFields。如果是这样,(例如,您允许输入“单位”以及宽度和高度),则应在JTextFields上附加DocumentListener以监视对基础文本文档内容的更改。这是一个例子:

widthField.getDocument().addDocumentListener(new DocumentListener() {
      public void changedUpdate(DocumentEvent e) {
          update();
      }
      public void removeUpdate(DocumentEvent e) {
          update();
      }
      public void insertUpdate(DocumentEvent e) {
          update();
      }

      // your method that handles any Document change event
      public void update() {
          if( aspectCheckBox1.isSelected() ) {

            // parse the width and height,
            // constrain the height to the aspect ratio and update it here
          }
      }

    });


然后,将类似的DocumentListener添加到heightTextField中。

请注意,如果使用JTextField,则需要解析它们的内容,在用户输入无效数字值的情况下,读取单位(在适用的情况下)并处理NumberFormatExceptions。

要回答有关在何处添加处理程序的问题...

当文档的高度GUI元素发生更改时,应发生宽度的更新。同样,当对Width GUI元素进行文档更改时,应该发生Height的更新。

您将需要适当地处理零误差除法(或将输入限制为始终大于0),使用双精度进行计算,最好使用Math.round()来获取最佳的整数值以保持宽高比。

即:

int calculateHeight(int width, double aspect) {

    if( aspect <= 0.0 ) {
        // handle this error condition
    }
    return (int)Math.round(width / aspect);
}


为了实际跟踪宽高比,我会将其存储在一个成员变量中,并在JCheckBox中添加一个ActionListener ...,因为在宽度和高度字段的每个值更改时更新目标宽高比都可能导致“宽高比”整数舍入”。

这是一个在每次宽高比检查状态更改时跟踪您的宽高比的示例:

private double aspect = 1.0;

aspectCheckBox.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
        preserveAspectActionPerformed(evt);
    }
});

private void preserveAspectActionPerformed(java.awt.event.ActionEvent evt) {

    try {
        double w = Double.parseDouble(widthField.getText());
        double h = Double.parseDouble(heightField.getText());
        aspect = w / h;
    }
    catch(NumberFormatException ex) {
        // ... error occurred due to non-numeric input
        // (use a JSpinner or JFormattedTextField to avoid this)
    }
}


最重要的是避免为作业使用错误的输入类型:


JTextAreas适用于多行文字
JTextFields适用于单行文字
JFormattedTextFields适用于限制为特定格式的文本
JSpinners适用于数字输入。


希望对您有帮助。

关于java - 设置两个JTextArea的事件监听器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24398107/

10-10 04:20