【问题标题】:Double-click wrong behaviour at jtable双击 jtable 的错误行为
【发布时间】: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);




    }
}

【问题讨论】:

  • 我不知道这是否是您的问题的原因,但是……您忽略了convertRowIndexToModelconvertColumnIndexToModel 返回的值。这意味着这些调用基本上什么也没做。
  • @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


【解决方案1】:

在 coderanch 论坛上得到了答案,决定在那里提交。 也许将来有人会需要它。

解决方法是在创建表的时候添加MouseListener(不是在ActionListener的actionPerformed()方法中)。

所以我已经将DoubleClicker.whattodo(); // class of double-click behavior logic 从 ExecButtonPressed.java 转移到 Form.java:

table = new JTable();
scrollPane.setViewportView(Form.table);
DoubleClicker.whattodo(); // class of double-click behavior logic

【讨论】:

    猜你喜欢
    • 2015-02-09
    • 2016-07-27
    • 2014-05-08
    • 1970-01-01
    • 2023-04-07
    • 2021-07-31
    • 1970-01-01
    • 2013-01-28
    • 2020-07-21
    相关资源
    最近更新 更多