Combining JXTable with RXTable

2019-02-19 20:01发布

问题:

Problem

I want the capabilities of JXTable with the "select all on edit" behavior of RXTable. Doing a simple override would be fine but the double click function of the RXTable doesn't work with JXTable. When using the Button Action mode it's fine, but when using F2 or a double click something in JXTable clashes with RXTable and remove the selection so I'm left with default behavior. Is it because of the GenericEditor that it uses internally or is it something else?

How can I get JXTable to select all on F2 or double click edit?

EDIT: It looks like this only happens when the model has the column defined for type Integer. It works as expected when it is defined for a String or Object column.

Solution

Thanks to kleopatra's fix I was able to alter the selectAll method so it handles JFormattedTextFields and all cases of editing. Since the original code worked on type to edit I just used the fix for other cases. Here is what I ended up with.

Replace selectAll in RXTable with the following:

/*
 * Select the text when editing on a text related cell is started
 */
private void selectAll(EventObject e)
{
    final Component editor = getEditorComponent();

    if (editor == null
        || ! (editor instanceof JTextComponent 
                || editor instanceof JFormattedTextField))
        return;

    if (e == null)
    {
        ((JTextComponent)editor).selectAll();
        return;
    }

    //  Typing in the cell was used to activate the editor

    if (e instanceof KeyEvent && isSelectAllForKeyEvent)
    {
        ((JTextComponent)editor).selectAll();
        return;
    }

    // If the cell we are dealing with is a JFormattedTextField
    //    force to commit, and invoke selectall

    if (editor instanceof JFormattedTextField) {
           invokeSelectAll((JFormattedTextField)editor);
           return;
    }

    //  F2 was used to activate the editor

    if (e instanceof ActionEvent && isSelectAllForActionEvent)
    {
        ((JTextComponent)editor).selectAll();
        return;
    }

    //  A mouse click was used to activate the editor.
    //  Generally this is a double click and the second mouse click is
    //  passed to the editor which would remove the text selection unless
    //  we use the invokeLater()

    if (e instanceof MouseEvent && isSelectAllForMouseEvent)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                ((JTextComponent)editor).selectAll();
            }
        });
    }
}

private void invokeSelectAll(final JFormattedTextField editor) {
    // old trick: force to commit, and invoke selectall
    editor.setText(editor.getText());
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            editor.selectAll();
        }
    });
}

回答1:

a quick hack working for two of the three selection types

       // in selectAll(EventObject) special case the formatted early
       if (editor instanceof JFormattedTextField) {
           invokeSelectAll(editor);
           return;
       }


        private void invokeSelectAll(final JFormattedTextField editor) {
            // old trick: force to commit, and invoke selectall
            editor.setText(editor.getText());
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    editor.selectAll();
                }
            });
        }

was remembered of the trick by How to select all text in a JFormattedTextField when it gets focus? - doesn't handle the case when starting edit by typing, in this case the content is not deleted (as for a normal textfield) but the new key is added.