【问题标题】:Key Listener for JTable containing JCheckBoxes包含 JCheckBoxes 的 JTable 的关键侦听器
【发布时间】:2012-05-07 15:56:29
【问题描述】:

我有一个包含复选框的 JTable。我的应用程序的构建方式是,每当编辑任何条目时,背景都会发生变化,以显示条目处于编辑状态。我已经用鼠标设置好了,但是当添加一个 KeyListener 来捕捉键盘上按下空格的时候,keyReleased 方法只有在 Space 被按住更长时间时才会触发,并且复选框快速选择和取消选择。

当我使用 keyTyped 和 keyPressed 方法时,一切都很好,只是它落后了一步,因为输入到表中的新数据没有被捕获。

那么,我的问题是,我怎样才能在表格上按下空间时捕捉并收集表格的所有当前值?

我正在使用 MVC 架构;这是我的控制:

public class UserInternalFrameController {

    UserInternalFrame gui = new UserInternalFrame();

    public UserInternalFrameController(ManagementGUI mainGui) {
        gui.getTableUserTransactionPermissions().addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {
                System.out.println("typed");
                // TODO Auto-generated method stub
                if (e.getKeyChar() == ' ') {
                    if (stateMachine == 2 || stateMachine == 4) {
                        JTable permTable = gui.getTableUserTransactionPermissions();
                        int noOfColumns = gui.getUserTransactionPermissionsHeader().length;
                        permListEdit = false;
                        for (int i = 0; i < permList.length; i++) {
                            for (int j = 0; j < noOfColumns; j++) {
                                if (!permList[i][j].equals(permTable.getValueAt(i, j))) {
                                    System.out.println("row" + i + "; column" + j + "; perList:" + permList[i][j] + "; transList: " + permTable.getValueAt(i, j));
                                    permListEdit = true;
                                }
                            }
                        }
                        if ((employeeCodeEdit || usernameEdit || passwordEdit || userIdEdit || subjectIdEdit || userStatusEdit || userRoleEdit || permListEdit) == false) {
                            gui.getPanelUser().setBackground(defaultBackgroundPanelUser);
                            gui.getTableUserTransactionPermissions().setBackground(Color.WHITE);
                            stateMachine = 2;
                            gui.getBtnSave().setEnabled(false);
                        } else {
                            gui.getPanelUser().setBackground(Color.decode("#f5deb3"));
                            gui.getTableUserTransactionPermissions().setBackground(Color.decode("#f5deb3"));
                            stateMachine = 4;
                            gui.getBtnSave().setEnabled(true);
                        }
                    }
                }
            }
        });
    }
}

相同的代码块可以很好地与鼠标 actionListener 配合使用,并且在添加到 keyPressed 方法时具有相同的延迟效果。 keyReleased 似乎适用于除空格以外的所有其他按钮。

我的键盘很好。

任何帮助将不胜感激。

【问题讨论】:

    标签: java swing combobox jtable keylistener


    【解决方案1】:

    如example 中所示和tutorial 中所讨论的,Boolean.class 类型的表列的默认渲染器和编辑器是JCheckBox。复选框的默认鼠标处理程序正常工作,默认Key Binding 是space 键。 UIManager 属性 Table.selectionBackground 将以设计者偏好和用户期望的方式突出显示选定的单元格。

    我鼓励您放弃显示的方法并使用默认值。

    【讨论】:

    • 请原谅我的无能。您是否建议我使用 TableModelListener 来监听表的更改?我尝试了以下方法:gui.getTableUserTransactionPermissions().getModel().addTableModelListener(new TableModelListener() { @Override public void tableChanged(TableModelEvent arg0) { // TODO Auto-generated method stub System.out.println("TableModelListener"); } }); 但 tableChanged 方法永远不会被调用......这就是为什么我一开始就使用鼠标和键监听器。
    • 我之所以使用这种方法是因为 JTable 在一个选项卡中……记录的详细信息分布在所有选项卡中。如果在记录的任何选项卡上进行了更改,我希望更改所有选项卡的背景,以便通知用户该记录处于编辑状态。另外,我必须通知我的 stateMachine(这是正确的方法)并启用/禁用 CRUD 按钮。
    • 对不起,如果我暗示无能;我的意思是解决单纯的无知,包括我自己的。我无法解释您的TableModelListener 问题;有一个例子here。相关选项卡应该观察表的模型而不是 JTable 视图本身。 CellEditor 生命周期在 here 中说明。
    • 不,我很抱歉。我能够通过使用 setDataVector 方法填充我的 TableModel 来解决这个问题。我错误地填充了我的 JTables(新的 DefaultTableModel),因此在此过程中弄乱了侦听器。感谢您为我指明正确的方向。非常感谢!
    • 优秀;很高兴你把事情解决了。不要犹豫,酌情更新您的问题或添加答案。
    【解决方案2】:

    这个问题的答案相当简单。新手错误。这是我如何更新数据检索表的 sn-p(来自 MVC 模式的控制器;gui 是视图实例)。

    // update tableUserSearchResult
    gui.setUserSearchTableData(tempList); 
    gui.setUserSearchResultTableModel(new DefaultTableModel(
        gui.getUserSearchTableData(), gui.getUserSearchTableHeader()));
    gui.getTableUserSearchResult().setModel(gui.getUserSearchResultTableModel());
    

    我真的不知道为什么创建一个新的DefaultTableModel 实例会导致此错误,因为我将表的模型定义并设置为新实例。我想...

    但是,通过使用DefaultTableModel 的setDataVector 方法,我能够正确(不创建)更新DefaultTableModel 一个新实例,并且它工作得很好:

    gui.setUserRolePermissionsData(userRolePermissionList);
    gui.getUserRolePermissionsTableModel().setDataVector(
        gui.getUserRolePermissionsData(), gui.getUserRolePermissionsHeader());
    gui.getTableUserRolePermissions().setModel(gui.getUserRolePermissionsTableModel());
    

    这就是我在视图中声明对象的方式:

    public class UserRoleInternalFrame extends JInternalFrame {
    DefaultTableModel userRoleDocumentsPermissionsTableModel;
        Object [][] userRoleDocumentsPermissionsData;
        String[] userRoleDocumentsPermissionsHeader = {
            "Document", "Edit", "View", "Process", "Update"
        };
        private JTable tableDocumentPermissions;
        private JScrollPane scrollPaneDocumentPermissions;
    
    ...
    
    this.userRolePermissionsTableModel = new DefaultTableModel(
        this.userRolePermissionsData, this.userRolePermissionsHeader);
    tableUserRolePermissions = new JTable(this.userRolePermissionsTableModel){
        @Override // in order to render JCheckBox
        public Class getColumnClass(int c) {
            if (c == 1 || c == 2 || c == 3 || c == 4){
                return Boolean.class;
            } else {
                return String.class;
            }
        }
    };
    
    scrollPaneEntryTypePermissions.setColumnHeaderView(tableUserRolePermissions);
        scrollPaneEntryTypePermissions.setViewportView(tableUserRolePermissions);
    

    【讨论】:

      猜你喜欢
      • 2012-09-04
      • 2012-10-30
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 2013-01-28
      • 2017-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多