2

我正在尝试JTable使用默认组件为可编辑实现撤消(和重做)功能。JTable有一个额外的类来指定它的属性,称为SpecifiedJTable.

为此,我想抓住双击单元格的时刻(即选择/标记要编辑的单元格的时刻)以将单元格中的信息及其坐标推送到堆栈上。

这应该由MouseListener……至少这是我的想法。我试过这个(站在我SpecifiedJTable班的构造函数中)

class JTableSpecified extends JTable {
    private static final long serialVersionUID = 1L;
    private int c; // the currently selected column
    private int r; // the currently selected row

    public JTableSpecified(String[][] obj, String[] columnNames) {
        super(obj, columnNames); // constructs the real table
        // makes that you can only select one row at a time
        this.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        // makes that columns are not squeezed
        this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        // forbids to rearrange the columns
        getTableHeader().setReorderingAllowed(false);
        // adds action listener
        this.getModel().addTableModelListener(new TableModelListener() {
            public void tableChanged(TableModelEvent e) {
                r = getSelectedRow();
                c = getSelectedColumn();
                // get the String at row r and column c
                String s = (String) getValueAt(r, c);
                if (jobDisplayed) jobSwitch(c, s);
                else resSwitch(c, s);
            }
        });    
        this.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    System.out.println("test");
                }
            }
        });
    }
} 

但不知何故,clickCounter 不想达到任何高于 1 的值。

我很高兴得到任何答案和帮助。谢谢。

4

4 回答 4

2

您遇到的问题与使用有关,mouseClicked()而不是使用mousePressed(). 在这种情况下,似乎很难增加点击计数器,但仍然是可能的。我花了很多点击和鼠标移动来增加点击计数器超过 1。你可以在你的代码中自己尝试。要使计数器超过 1,您需要在同时将鼠标从一个单元格移动到另一个单元格时快速按下和释放鼠标(或者我只是幸运地在单元格之间单击?)。

正如您在这个完全工作的示例中所看到的,由您的代码制作,两次鼠标按下,使用该mousePressed()方法被检测得很好。

public class JTableSpecified extends JTable {
    private static final long serialVersionUID = 1L;

    public JTableSpecified(String[][] obj, String[] columnNames) {
        super(obj, columnNames); // constructs the real table
        // makes that you can only select one row at a time
        this.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        // makes that columns are not squeezed
        this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        // forbids to rearrange the columns
        getTableHeader().setReorderingAllowed(false);
        // adds action listener
        this.getModel().addTableModelListener(new TableModelListener() {
            @Override
            public void tableChanged(TableModelEvent e) {
            }
       });        
        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    System.out.println("test");
                }
                System.out.println("e.getClickCount() = " + e.getClickCount());
            }
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JPanel panel = new JPanel();
                panel.add(new JTableSpecified(new String[][]{{"oi", "oi2"}, {"oi3", "oi4"}}, new String[]{"Col1", "Col2"}));
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setContentPane(panel);
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

结论:也许您实际上想使用该mousePressed()方法?

于 2012-06-20T11:56:00.653 回答
1

BasicTableUI 通过进入被双击的单元格上的编辑模式来响应双击。它做了很多复杂的事情,其中​​一部分涉及创建一个 JTextField(或其他组件)以允许编辑数据,然后防止鼠标单击事件进一步传播。

如果您的表格或该表格单元格不可编辑,您可以使用点击计数 2、3、4、...轻松捕获鼠标事件。但由于您希望表格可编辑,您需要一种不同的方法。

一种想法是覆盖 JTable。编辑CellAt()

一个更好的主意是忘记弄乱 JTable,而是监听表模型本身的数据变化。

于 2012-06-20T19:04:51.920 回答
1

这个答案扩展了 Boro 的答案。
为了捕捉允许用户编辑表格的所有情况,我还需要为 F2 添加一个 KeyListener(其效果与双击单元格相同)并通过按任意键禁用自动单元格编辑。
我刚刚将它添加到 mouseListener 后面的构造函数中(见上文)

// 通过按键禁止编辑
this.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);

// keyListener 对按下 F2 做出反应(键码 113)
this.addKeyListener(new KeyAdapter(){

公共无效keyPressed(KeyEvent e){

if (e.getKeyCode() == 113) System.out.println("test");
}
});

于 2012-06-20T22:12:44.587 回答
-1

代码中的错误是 mouseClicked 方法在第一次单击时被调用。当双击发生时,mouseClicked 方法被再次调用。您可以为较早的单击事件放置一个静态变量(或类变量)来存储时间(使用 e.getWhen() 方法)。检查时差,如果它足够小,请执行您的操作(我建议调用 doubleClick 方法)。

您可能必须在您的类 JTableSpecified 中实现鼠标侦听器,因为静态变量可能不会放置在您现有的代码中。

于 2012-06-20T08:12:45.483 回答