当前位置: 首页 > 知识库问答 >
问题:

JTextField和JSlider-DocumentListener之间的交互变得混乱

戈巴英
2023-03-14

我有一个包含文本字段(红色、绿色、蓝色)和滑块(红色、绿色、蓝色)的面板。用户应该能够使用他们喜欢的任何组件,相应的组件应该更新。(例如,在红色文本字段中输入100应将红色滑块移动到100)。

public class ColorChooser extends javax.swing.JPanel implements ChangeListener {
    private Vector listeners;

    public ColorChooser() {
        initComponents();
        listeners = new Vector();
        sldRed.addChangeListener(this);
        sldGreen.addChangeListener(this);
        sldBlue.addChangeListener(this);
        txtRed.setText("0");
        txtGreen.setText("0");
        txtBlue.setText("0");
        Document docRed = txtRed.getDocument();
        docRed.addDocumentListener(new MyDocumentListener(txtRed, sldRed));
        Document docGreen = txtGreen.getDocument();
        docGreen.addDocumentListener(new MyDocumentListener(txtGreen, sldGreen));
        Document docBlue = txtBlue.getDocument();
        docBlue.addDocumentListener(new MyDocumentListener(txtBlue, sldBlue));
}

    // Variables declaration - do not modify                     
    private javax.swing.JLabel labelBlue;
    private javax.swing.JLabel labelGreen;
    private javax.swing.JLabel labelRed;
    private javax.swing.JSlider sldBlue;
    private javax.swing.JSlider sldGreen;
    private javax.swing.JSlider sldRed;
    private jcolorchooser.JColorIntegerField txtBlue;
    private jcolorchooser.JColorIntegerField txtGreen;
    private jcolorchooser.JColorIntegerField txtRed;
    // End of variables declaration                   

    @Override
    public void stateChanged(ChangeEvent ce) {
        if (ce.getSource() == sldRed) {
            txtRed.setText(Integer.toString(sldRed.getValue()));
        }
        if (ce.getSource() == sldGreen) {
            txtGreen.setText(Integer.toString(sldGreen.getValue()));
        }
        if (ce.getSource() == sldBlue) {
            txtBlue.setText(Integer.toString(sldBlue.getValue()));
        }
        int r = sldRed.getValue();
        int g = sldGreen.getValue();
        int b = sldBlue.getValue();
        Color color = new Color(r,g,b);
        fireColorEvent(new ColorEvent(this,color));
    }
    private void fireColorEvent(ColorEvent colorEvent){
        Vector v;
        synchronized(this){
            v = (Vector)listeners.clone();
        }
        int size = v.size();
        for(int i=0; i<size; i++){
            ColorListener colorListener = (ColorListener)v.elementAt(i);
            colorListener.changeColor(colorEvent);
        }
    }
    public void addColorListener(ColorListener colorListener){
        listeners.addElement(colorListener);
    }
    public void removeColorListener(ColorListener colorListener){
        listeners.removeElement(colorListener);
   }

}

//DocumentListener Class
public class MyDocumentListener implements DocumentListener {
    private JColorIntegerField jColorIntegerField;
    private JSlider jColorSlider;

    public MyDocumentListener(JColorIntegerField jColorIntegerField,
        JSlider jColorSlider) {
        this.jColorIntegerField = jColorIntegerField;
        this.jColorSlider = jColorSlider;
    }

    public void insertUpdate(DocumentEvent de) {
        if (jColorIntegerField.getText().equals("")) {
            jColorSlider.setValue(0);
        }
        else {
            jColorSlider.setValue(Integer.parseInt(
                jColorIntegerField.getText()));
        }
    }

    @Override
    public void removeUpdate(DocumentEvent de) {
        if (jColorIntegerField.getText().equals("")) {
            jColorSlider.setValue(0);
        }
        else {
            jColorSlider.setValue(Integer.parseInt(
                jColorIntegerField.getText()));
        }
    }

    @Override
    public void changedUpdate(DocumentEvent de) {

    }
}

共有1个答案

凌运恒
2023-03-14

这可能来得有点晚,但我本周正在做一个Java项目,我遇到了与您上面描述的问题相同的问题。

在寻找解决方案时,我偶然发现了你的问题。由于目前还没有答案,我想回到这里,描述一下我是如何解决这个问题的可能会有所帮助(也许这会在将来帮助你或其他人)。

因此,Swing API似乎通过提供一个名为getValueIsAdjusting的非常好的方法来帮助我们。此方法是JSlider类的一部分。

这如何解决问题?

我们从ChangeListener实现中修改stateChanged方法:

@Override
public void stateChanged(ChangeEvent ce) {
    JSlider source = (JSlider)ce.getSource();

    if (source.getValueIsAdjusting()) {
        if (source == sldRed)
            txtRed.setText(Integer.toString(sldRed.getValue()));
        else if (source == sldGreen)
            txtGreen.setText(Integer.toString(sldGreen.getValue()));
        else if (source == sldBlue)
            txtBlue.setText(Integer.toString(sldBlue.getValue()));
    }

    int r = sldRed.getValue();
    int g = sldGreen.getValue();
    int b = sldBlue.getValue();
    Color color = new Color(r, g, b);

    fireColorEvent(new ColorEvent(this, color));
}

if(source.getValueIsAdjusting())指令使setText仅在您仍在“调整”滑块时发生(这意味着您仍在用鼠标拖动滑块)。

将值写入JTextField将从滑块触发stateChanged方法,但它不会调用setText,因为滑块值不是“调整”的。

这样,就可以排除异常。

 类似资料:
  • 尝试在JTextField被更新时获取其值(插入字符、删除字符、更改字符),然后设置其值。 我遇到了“试图在通知中变异”的例外情况,导致我: 但是,决不能从文档侦听器中修改文本组件的内容。如果这样做,程序可能会死锁。相反,您可以使用格式化的文本字段或提供文档过滤器。从这里开始 我正在使用文档过滤器将JTextField的字符数限制为12,但我不知道如何在不使用文档侦听器的情况下检测JTextFie

  • 我试图做的是防止用户在我的输入中输入空字符串。现在,用户只能输入数字。然而,没有什么能阻止他们将文本字段留空。我想限制他们在程序空白时按我的按钮启动程序。 现在,我的文本字段最初是空白的,按钮最初是灰色的。但当我输入一些东西时,按钮保持灰色。请记住,所有这些代码都在构造函数中。

  • 所以,我完成了一个数独解算器,但我想改进它。要做到这一点,我需要从中找到我的。我正在使用实时读取我的,问题是在中。 我需要到达发生的。例如,如果输入无效,将变红等。 如果您需要知道,我将所有放在矩阵中。每个字段都处理数独中的一个数字。 (扩展)

  • 本文向大家介绍UIWebView和JavaScript之间是怎么交互的?相关面试题,主要包含被问及UIWebView和JavaScript之间是怎么交互的?时的应答技巧和注意事项,需要的朋友参考一下 UlWebView是i〇S SDK中渲染网面的控件,在显示网页的时候,我们可以hack网页 然后显示想显示的内容。其中就要用至JavaScript的知识,而UlWebView与javascript交互

  • 我正在从事一个运行java后端并具有web页面UI的项目。基本上,java系统运行在服务器上,并保存在web页面中创建的规则日志。我需要它做的是从web页面上的文本字段中获取输入,并调用一个函数将它们传递给java对象以创建一个新规则。我还需要能够调用一个函数来返回我创建的规则对象的数组,这样我就可以在web页面上构建它们的表。 谢了!

  • 在所有属于office支持库的控件中都可以调用com对象来完善功能,那在这些控件中如何调用com对象呢? 首先新建“易语言”我们以word支持库为例,在窗体上放入word程序集和word文档集 我们写入如下代码,把两个组件联系起来 这时,我们查看word文档集的命令中有“取某某对象”的命令,这些命令的返回值就是一个对象,使用这些命令的时候必须先创建一个对象类型的变量来保存这些命令的返回值。 这时一