我正在尝试使用按钮来启用/禁用自身,具体取决于JTable是否选择了任何行。
所以我相信我需要按钮作为ListSelectionListener,监听JTable的SelectionModel,如Oracle tutorial所述。
我应该如何使用JFormDesigner 5执行此操作?
似乎我应该将以下代码添加到我的JButton中,但我不知道如何在JFormDesigner中这样做。
// Implementing this method to be a ListSelectionListener.
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
boolean anyRowsSelected = !(lsm.isSelectionEmpty());
this.setEnabled( anyRowsSelected );
}
根据我使用JFormDesigner添加actionPerformed处理程序的经验,JFormDesigner在JFrame上创建了一个方法。但是我对Swing& amp;的理解OOP说ListSelectionListener的代码应该在监听小部件本身内部(在我的例子中是JButton)。
我正在使用:JFormDesigner 5.0.0.1,IntelliJ 10.5,Java 1.6.0_24,Mac OS X 10.6.7。
--------解决-----------
感谢“Hovercraft Full Of Eels”回答我的问题。
解决方案:我将向JFrame添加代码以创建ListSelectionListener。这样可以在不干扰JFormDesigner工具的情况下完成工作。
我增强了“Hovercraft Full Of Eels”给出的示例代码,使其更具互动性。我在按钮上添加了一个ActionListener来清除用户的选择。现在,用户可以看到按钮在启用和禁用之间切换。
我的版本显示了一个微妙的错误:清除表格选择后,所选单元格变为黑色。我不是为什么。但这超出了StackOverflow问题的范围。无论这个错误如何,这段代码都是这个问题的一个很好的演示。
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
public class TableAndButton extends JPanel {
private static final String[] COLUMN_NAMES = {"Mon", "Tues", "Wed", "Thurs", "Fri"};
private JButton button = new JButton("Clear user's selection");
private DefaultTableModel model = new DefaultTableModel(COLUMN_NAMES, 10);
private JTable table = new JTable(model);
public TableAndButton() {
JPanel btnPanel = new JPanel();
btnPanel.add(button);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
boolean anyRowSelected = !(lsm.isSelectionEmpty());
button.setEnabled(anyRowSelected);
}
});
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
table.getSelectionModel().clearSelection();
}
});
button.setEnabled(false);
setLayout(new BorderLayout());
add(new JScrollPane(table), BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
private static void createAndShowUI() {
JFrame frame = new JFrame("TableAndButton");
frame.getContentPane().add(new TableAndButton());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
答案 0 :(得分:2)
不,JButton本身不应该是ListSelectionListener,而是JTable需要添加一个单独的ListSelectionListener来启用/禁用JButton。不要把它想象成按钮正在监听JTable,因为它不是。相反,一个单独的实体正在进行监听并根据是否选择了行来更改程序的状态。
如,
import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
public class TableAndButton extends JPanel {
private static final String[] COLUMN_NAMES = {"Mon", "Tues", "Wed", "Thurs", "Fri"};
private JButton button = new JButton("Button");
private DefaultTableModel model = new DefaultTableModel(COLUMN_NAMES, 10);
private JTable table = new JTable(model);
public TableAndButton() {
JPanel btnPanel = new JPanel();
btnPanel.add(button);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
boolean anyRowSelected = !(lsm.isSelectionEmpty());
button.setEnabled(anyRowSelected);
}
});
button.setEnabled(false);
setLayout(new BorderLayout());
add(new JScrollPane(table), BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
private static void createAndShowUI() {
JFrame frame = new JFrame("TableAndButton");
frame.getContentPane().add(new TableAndButton());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}