java - JTextfield 默认操作后 JButton 变为启用

标签 java swing jbutton

我正在重新掌握 Java 并使用 Swing。目前正在尝试了解 JList。

在 JList 中选择项目时,我启用一个按钮(“删除”按钮)。当没有选择时,应该禁用该按钮(如果没有选择项目,则无法删除该项目,如果没有项目索引,JVM 往往会呕吐)。

通过 JTextField 默认操作(输入)添加列表项时,该按钮启用,但 JList 中没有选择。启用该按钮的代码甚至没有运行。这是怎么发生的?也许我在某个地方缺少一个听众?

所有的监听器都在主类中,但是其他的似乎没有问题。我看不到该类实例化两次,所以不是那样的。有什么想法会很棒吗?

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class GUI extends JFrame implements Runnable, ActionListener, DocumentListener, ListDataListener, ListSelectionListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    //declare and instantiate interface components
    DefaultListModel<String> lm=new DefaultListModel<String>();
    JList<String> jl=new JList<String>(lm);

    JTextField jt=new JTextField(50);

    JButton b_add=new JButton("Add");
    JButton b_del=new JButton("Remove");    

    @Override
    public void run() {
        //FROM RUNNABLE INTERFACE

        //set GUI (JFrame) attributes
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setLocationByPlatform(true);
        setName("List of Lists");
        setSize(1280, 500);
        setLayout(new FlowLayout());

        //set component attributes
        jl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //single selection list

        jt.getDocument().addDocumentListener(this);

        //other interface components
        JScrollPane sp=new JScrollPane(jl);
        JButton b_exit=new JButton("Exit");


        //other component attributes
        sp.setSize(500, 500);

        b_add.setEnabled(false);
        b_del.setEnabled(false);


        //set component listeners
        b_add.addActionListener(this);
        b_del.addActionListener(this);
        b_exit.addActionListener(this);

        jt.setActionCommand("TXT");
        jt.addActionListener(this);

        lm.addListDataListener(this);
        jl.addListSelectionListener(this);


        //add GUI components
        add(jt);
        add(sp);
        add(b_add);
        add(b_del);
        add(b_exit);

        //set GUI visible
        setVisible(true);
    }

    //FROM ACTIONLISTENER INTERFACE
    @Override
    public void actionPerformed(ActionEvent ae) {

        //default action on text field (enter key)
        if (ae.getActionCommand()=="TXT") {     
            lm.addElement(jt.getText());
            jt.setText(null);

        } else {

            //actions from buttons
            switch (ae.getActionCommand()) {

            //add button
            case "Add":
                lm.addElement(jt.getText());
                jt.setText(null);
                break;

            //remove button
            case "Remove":
                if (jl.getSelectedIndex()>=0) {
                    lm.remove(jl.getSelectedIndex());

                }
                break;

            //exit button   
            case "Exit":
                setVisible(false);
                dispose();
                break;

            //just in case
            default:
                break;

            }
        }
    }

    //FROM DOCUMENTEVENTLISTENER INTERFACE
    @Override
    public void changedUpdate(DocumentEvent de) {

        b_add.setEnabled(de.getDocument().getLength()>0);
    }


    @Override
    public void insertUpdate(DocumentEvent de) {

        b_add.setEnabled(de.getDocument().getLength()>0);
    }


    @Override
    public void removeUpdate(DocumentEvent de) {

        b_add.setEnabled(de.getDocument().getLength()>0);
    }

    //FROM LISTDATALISTENER INTERFACE
    @Override
    public void contentsChanged(ListDataEvent ld) {

        b_del.setEnabled(lm.getSize()>0);
    }


    @Override
    public void intervalAdded(ListDataEvent ld) {

        b_del.setEnabled(lm.getSize()>0);
    }


    @Override
    public void intervalRemoved(ListDataEvent ld) {

        b_del.setEnabled(lm.getSize()>0);

    }

    //FROM LISTSELECTIONLISTENER INTERFACE
    @Override
    public void valueChanged(ListSelectionEvent ls) {

        b_del.setEnabled(jl.getSelectedIndex()>=0);
    }

}

应该发生的是,“删除”按钮仅应在 JList 中的项目突出显示(选择)时启用。

最佳答案

What should happen is that the "Remove" button should only enable when an item in the JList is highlighted (selected).

那么您的代码中有太多监听器。

不需要 DocumentListener。文本字段中的数据是否更改并不重要。当您将文本字段中的数据添加到 JList 时,选择不会自动更改。

不需要ListDataListener。同样,您并不关心数据是否发生变化。

与此要求相关的唯一监听器是ListSelectionListener。当选择更改时,此监听器将触发一个事件。然后,在监听器代码中,您可以根据列表中的选择启用/禁用按钮。

监听器中的基本代码可能是:

int index = list.getSelectedIndex();
button.setEnabled( index = -1 ? false : true );

阅读 Swing 教程中关于 How to Write a ListSelectionListener 的部分了解更多信息和工作示例。

关于java - JTextfield 默认操作后 JButton 变为启用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53980218/

相关文章:

java - JPanels 不会显示在 JFrame 中

java - 将鼠标悬停在 JButton 上并显示一条消息

java - Addactionlistener 不带参数

java - 找不到 Izpack 'src' 文件夹

java - 使用 java 8 流查找 2 个列表中匹配的元素并从另一个列表更新一个列表值

java - 作为 war 分发后的 Tess4J 错误 NoClassDefFoundError : Could not initialize class net. sourceforge.tess4j.TessAPI

java - 使用 JComboBox(类别) 更改/更新 JTable 内容

java - 如何实现通用bean

java - 字符串变量中的\t 和\n 不显示在 JOptionPane.showMessageDialog 中

java - 图标与具有海玻璃外观和感觉的 JButton 不匹配