繁体   English   中英

Java:将文本字段添加到ChangeEvent

[英]Java: Adding a text field to a ChangeEvent

我有一个家庭作业,我必须更改颜色选择器(它具有3个滑块,RGB并显示颜色),以便有文本字段,并且在该字段中键入值时,它也会更改滑块。 我有基本的想法,但是我很难找到更改文本字段的解决方案,它们只能与Action Event一起使用。 这是我的代码

package colorchooser;
import java.util.Vector;
import java.awt.Color;
import javax.swing.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;

/**
 *
 * @author -
 */
public class ColorChooser extends javax.swing.JPanel implements ChangeListener, ActionListener{

    private Vector listeners;

    /**
     * Creates new form ColorChooser
     */
    public ColorChooser() {
        initComponents();
        listeners = new Vector();
        sldRed.addChangeListener(this);
        sldGreen.addChangeListener(this);
        sldBlue.addChangeListener(this);
        txtRed.addActionListener(this);

    // Variables declaration - do not modify                     
    private javax.swing.JButton btnSetColor;
    private javax.swing.JLabel lblBlue;
    private javax.swing.JLabel lblGreen;
    private javax.swing.JLabel lblRed;
    private javax.swing.JSlider sldBlue;
    private javax.swing.JSlider sldGreen;
    private javax.swing.JSlider sldRed;
    private javax.swing.JTextField txtBlue;
    private javax.swing.JTextField txtGreen;
    private javax.swing.JTextField txtRed;
    // End of variables declaration                   

    @Override
    public void stateChanged(ChangeEvent ce) {
         int r = sldRed.getValue();
         int g = sldGreen.getValue();
         int b = sldBlue.getValue();
         Color color = new Color(r,g,b);
         fireColorEvent(new ColorEvent(this,color));
         txtRed.setText(Integer.toString(r));
         txtGreen.setText(Integer.toString(g));
         txtBlue.setText(Integer.toString(b));
    }

    public void addColorListener(ColorListener colorListener){
        listeners.addElement(colorListener);
    }

    public void actionPerformed(ActionEvent ae) {

        if(ae.getSource()==btnSetColor){
            try
            {
                if(Integer.parseInt(txtRed.getText()) <= 255){
                sldRed.setValue(Integer.parseInt(txtRed.getText()));
                }
                else
                {
                    txtRed.setText("0");
                    JOptionPane.showMessageDialog(this,"Error: Please enter a value equal to or less than 255");
                }            


                if(Integer.parseInt(txtBlue.getText()) <= 255){
                sldBlue.setValue(Integer.parseInt(txtBlue.getText()));
                }
                else
                {
                    txtBlue.setText("0");
                    JOptionPane.showMessageDialog(this,"Error: Please enter a value equal to or less than 255");
                }                

                if(Integer.parseInt(txtGreen.getText()) <= 255){
                sldGreen.setValue(Integer.parseInt(txtGreen.getText()));
                }
                else
                {
                    txtGreen.setText("0");
                    JOptionPane.showMessageDialog(this,"Error: Please enter a value equal to or less than 255");
                }                
            }
            catch (Exception ex)
            {
                JOptionPane.showMessageDialog(this,"Error: Please Enter Numbers");
                txtRed.setText("0");
                txtGreen.setText("0");
                txtBlue.setText("0");
                sldRed.setValue(Integer.parseInt(txtRed.getText()));
                sldGreen.setValue(Integer.parseInt(txtGreen.getText()));
                sldBlue.setValue(Integer.parseInt(txtBlue.getText()));
            }
        }
    }

您可以看到我正在向滑块添加更改侦听器,但是我必须向txtRed添加操作侦听器,因为它不接受addChangeListener。 有什么想法可以解决吗?

谢谢!

创建一个可以处理已更改字段的方法...

protected void fieldWasChanged(JTextField field) {
    try {
        int value = Integer.parseInt(field.getText());
        JSlider slider = null;
        if (field == txtBlue) {
            slider = sldBlue;
        } else if (field == txtRed) {
            slider = sldRed;
        } else if (field == txtGreen) {
            slider = sldGreen;
        }
        if (slider != null) {
            slider.setValue(value);
        }
    } catch (NumberFormatException exp) {
        exp.printStackTrace(); 
        // Display error message
    }
}

接下来,创建一个实现DocumentListener接口的内部类...

public class DocumentHandler implements DocumentListener {

    private JTextField field;

    public DocumentHandler(JTextField field) {
        this.field = field;
    }

    protected void documentUpdated() {
        fieldWasChanged(field);
    }

    @Override
    public void insertUpdate(DocumentEvent e) {
        documentUpdated();
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        documentUpdated();
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        documentUpdated();
    }

}

这将监视对Document底层字段的更改,并调用您的fieldWasChanged方法...

接下来,向此处理程序注册每个字段...

protected void registerDocumentHandler(JTextField field) {
    DocumentHandler handler = new DocumentHandler(field);
    field.getDocument().addDocumentListener(handler);
}

//...

registerDocumentHandler(txtBlue);
registerDocumentHandler(txtRed);
registerDocumentHandler(txtGreen);

现在,如果您实际尝试过此操作,您会发现键入内容的那一刻,您的UI会变得无响应,并且您的程序最终会因StackOverflowException崩溃,这是因为DocumentHandler正在更新JSlider ,后者正在更新字段,它会通知DocumentHandler等等。

一个简单的解决方案是放入一个标志,而为true阻止DocumentHandler通知fieldWasChanged方法...

public class DocumentHandler implements DocumentListener {

    private JTextField field;
    private boolean isUpdating;

    public DocumentHandler(JTextField field) {
        this.field = field;
    }

    protected void documentUpdated() {
        if (!isUpdating) {
            try {
                fieldWasChanged(field);
            } finally {
                isUpdating = false;
            }
        }
    }

    //...

现在您可以键入并获取实时反馈,可以将文本粘贴到字段中,它们将更新滑块。

现在,说了这么多,我鼓励您尝试使用JFormattedTextFieldJSlider而不是JTextField因为它们可以帮助自己验证数据。 有关更多详细信息,请参见如何使用格式化的文本字段如何使用微调框

如果您不想使用它们,但仍然希望限制用户只能输入数字,请查看实现文档过滤器DocumentFilter示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM