【发布时间】:2020-05-23 21:08:25
【问题描述】:
美好的一天!
我有一个 jTable,我正在通过 JButton 侦听器填充它。 鼠标双击填充jTable后,我调用JOptionPane.showMessageDialog。 问题解决后。再次单击 JButton 后,再次填充 jTable。如果我再次双击行\单元格,它将通过 JOptionPane 向我显示 2 条消息,而不是 1 条。 据我了解,我需要刷新模型,但没有成功。
我的代码:
Form.java
btnExec = new JButton("Exec");
table = new JTable();
scrollPane.setViewportView(table);
// Create Button Listener
ActionListener startProcess = new ExecButtonPressed();
btnExec.addActionListener(startProcess);
ExecButtonPressed.java
public class ExecButtonPressed implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
try {
System.out.println("table rows:" + Form.table.getRowCount());
DefaultTableModel tableModel = new DefaultTableModel();
prepare(tableModel); // create headers
fill(tableModel); // add rows
Form.table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
Form.table.setModel(tableModel);
sortresize(Form.table); //resize width of columns + sort by id desc
Form.table.setDefaultEditor(Object.class, null);
DoubleClicker.whattodo(); // class of double-click behavior logic
}catch (Exception e1) {
e1.printStackTrace();
}
}
//
private void prepare(DefaultTableModel tableModel) throws Exception {
try {
tableModel.addColumn("id");
tableModel.addColumn("name");
tableModel.addColumn("age");
}catch (Exception e1) {
e1.printStackTrace();
}
}
//
private void fill(DefaultTableModel tableModel) {
Object [] line = {"01", "Qw" , "20"};
tableModel.addRow(line);
Object [] line2 = {"02", "As" , "21"};
tableModel.addRow(line2);
Object [] line3 = {"03", "Zx" , "22"};
tableModel.addRow(line3);
}
//
private void sortresize(JTable table) {
//Resize width
for (int column = 0; column < table.getColumnCount(); column++) {
TableColumn tableColumn = table.getColumnModel().getColumn(column);
if (column == 0) {
tableColumn.setPreferredWidth( 45 );
} else if (column == 1){
tableColumn.setPreferredWidth( 50 );
} else if (column == 2){
tableColumn.setPreferredWidth( 55 );
}
}
//Sort table.
if (table.getRowCount() > 1){
TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel());
table.setRowSorter(sorter);
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
int columnIndexToSort = 0;
sortKeys.add(new RowSorter.SortKey(columnIndexToSort, SortOrder.DESCENDING));
sorter.setSortKeys(sortKeys);
sorter.sort();
};
}
//
}
DoubleClicker.java
public class DoubleClicker {
public static void whattodo() {
Form.table.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent mouseEvent) {
try {
System.out.println("click:" + mouseEvent.getClickCount());
Form.table = (JTable) mouseEvent.getSource();
Point point = mouseEvent.getPoint();
int row = Form.table.rowAtPoint(point);
int columnid = Form.table.columnAtPoint(point);
Form.table.convertRowIndexToModel(row);
Form.table.convertColumnIndexToModel(columnid);
if (mouseEvent.getClickCount() == 2 && Form.table.getSelectedRow() != -1) {
if (Form.table.getColumnName(columnid).equalsIgnoreCase("name")) {
JOptionPane.showMessageDialog(null,
(String) Form.table.getValueAt(row,columnid), "Selected name", 1);
}
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
}
}
我尝试了不同的选项,例如
tableModel.setRowCount(0);
tableModel.getDataVector().removeAllElements();
tableModel.fireTableDataChanged();
也许我把它放错了地方? 因为每次鼠标点击都会在第二次按钮执行时注册两次。
更新: 我加了
System.out.println("table rows:" + Form.table.getRowCount());
在 public void actionPerformed(ActionEvent e) { 正如我在控制台中看到的,第二个按钮执行后 Form.table.getRowCount() == 3 。 还添加了
System.out.println("click:" + mouseEvent.getClickCount());
作为 public void mousePressed(MouseEvent mouseEvent) 的第一行 正如我所看到的,在每次点击表格的第二个按钮执行后完成两次 我有 : 点击:1 点击:1 在第一次执行时,只需点击:1
好像有一个又一个视图。
整个 Form.java 以防有人愿意编译
public class Form {
private JFrame frame;
public static JTable table;
public static JButton btnExec;
public static JScrollPane scrollPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Form window = new Form();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Form() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
btnExec = new JButton("Exec");
btnExec.setBounds(10, 11, 89, 23);
frame.getContentPane().add(btnExec);
scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setBounds(10, 45, 369, 174);
frame.getContentPane().add(scrollPane);
table = new JTable();
scrollPane.setViewportView(table);
// Create Button Listener
ActionListener startProcess = new ExecButtonPressed();
btnExec.addActionListener(startProcess);
}
}
【问题讨论】:
-
我不知道这是否是您的问题的原因,但是……您忽略了
convertRowIndexToModel和convertColumnIndexToModel返回的值。这意味着这些调用基本上什么也没做。 -
@VGR,事实并非如此,我什至可以写:
int row = Form.table.convertRowIndexToView(Form.table.convertRowIndexToModel(Form.table.rowAtPoint(point))); int columnid = Form.table.convertColumnIndexToView(Form.table.convertColumnIndexToModel(Form.table.columnAtPoint(point)));结果会是一样的 -
找到了解决方法,但不太确定它总体上有多好,但是。由于 Form.table.getRowCount() == 3 甚至在第二次单击按钮之前,我将
table = new JTable(); scrollPane.setViewportView(table);从 Form.java 转移到 ExecButtonPressed.java ,作为第一行:public void actionPerformed(ActionEvent e) { try { Form.table = new JTable(); Form.scrollPane.setViewportView(Form.table);。所以每次单击按钮后都会重新创建 jtable 对象。
标签: java swing jtable actionlistener double-click