我将再次使用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中的项目时,才应启用“删除”按钮。
答案 0 :(得分:1)
应该发生的是,仅当突出显示(选中)JList中的项目时,才应启用“删除”按钮。
然后,您的代码中的侦听器过多。
不需要DocumentListener。文本字段中的数据是否更改都没有关系。当您将数据从文本字段添加到JList时,选择不会自动更改。
不需要ListDataListener。同样,您不必担心数据是否更改。
与此要求相关的唯一侦听器是ListSelectionListener
。选择更改时,此侦听器将触发一个事件。然后,在侦听器代码中,根据列表中的选择启用/禁用按钮。
侦听器中的基本代码可能是:
int index = list.getSelectedIndex();
button.setEnabled( index = -1 ? false : true );
阅读How to Write a ListSelectionListener的Swing教程中的部分,以获取更多信息和工作示例。
答案 1 :(得分:0)
只需在添加大小写中添加b_del.setEnabled(false);
。
//add button
case "Add":
lm.addElement(jt.getText());
jt.setText(null);
b_del.setEnabled(false);
break;
此外,我建议使用system.exit(0)
而不是dispose ()
。仅出于内存原因(显然,这取决于您的需求:))。