JTextField与JTable中的JComboBox行为

时间:2012-10-05 03:35:55

标签: swing jtable jcombobox jtextfield

好的,这很难解释,但我会尽我所能。

我在JTable中有一个JTextField和一个JComboBox,其getCellEditor方法已被覆盖,如下所示:

public TableCellEditor getCellEditor( int row, int column ) {
        if ( column == 3 ) {
              // m_table is the JTable

              if ( m_table.getSelectedRowCount() == 1 ) {             
                JComboBox choices = new JComboBox();
                choices.setEditable( true );
                choices.addItem( new String( "item 1" ) );

                return new DefaultCellEditor( choices );
         }

         return super.getCellEditor( row, column );
}

以下是行为差异(注意,从这一点开始,当我说JTextField或JComboBox时,我的意思是JTable中包含任一组件的CELL):

  1. 当我在JTextField上单击一次时,单元格会突出显示。双击打开插入符号,我可以输入文本。然而,使用JComboBox,单击会调出插入符号以输入文本,以及组合下拉按钮。

  2. 当我选中或使用箭头键导航到JTextField然后开始输入时,我输入的字符会自动输入到单元格中。然而,当我以相同的方式导航到JComboBox然后开始输入时,除了出现的组合下拉按钮之外没有任何反应。除非我先点击F2,否则我输入的所有字符都不会输入。

  3. 所以这是我的问题:在上述两个实例中,JComboBoxes的行为与JTextFields完全相同,我需要做什么?

    请不要问为什么我正在做我正在做的事情或建议替代方案(这是它的方式,我需要这样做)并且是的,我已经阅读了所有相关组件的API。 ......问题是,它是一个摇摆API。

2 个答案:

答案 0 :(得分:2)

进一步的谷歌搜索让我看到了以下文章:

http://www.jroller.com/santhosh/entry/keyboard_handling_in_tablecelleditor

虽然它没有描述与我相同的问题,但它肯定有一些共同的特征。

使用该文章中的一些建议,我能够(至少)解决我的问题的键盘位(我的问题的第2点中描述的那个)。我通过覆盖processKeyBinding的{​​{1}}方法完成了此操作,如下所示:

JTable

这种方法对我来说似乎有些骇人听闻,但又一次又好转,所以这可能是合理的。

在我的问题的第1点(即使用鼠标)中描述的场景中,让JComboBox的行为像JTextFields的问题仍然是开放的,如果有人想要去做它。

答案 1 :(得分:2)

bullet 2的替代方法是将keyEvents的所有传递移动到自定义JComboBox实现中:在那里,实现类似于table.processKeyBinding的processKeyBinding。类似的东西:

public static class JTableEditorComboBox extends JComboBox {

    @Override
    protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
            int condition, boolean pressed) {
        boolean result = super.processKeyBinding(ks, e, condition, pressed);
        if (!result) 
            result = processKeyBindingForTextField(ks, e, condition, pressed);
        return result;
    }

    private boolean processKeyBindingForTextField(KeyStroke ks, KeyEvent e,
            int condition, boolean pressed) {
        // sanity check: really used as cellEditor
        if (!Boolean.TRUE.equals(getClientProperty("JComboBox.isTableCellEditor")) 
               || !isEditable() 
               || !(getEditor().getEditorComponent() instanceof JTextField)) return false;
        JTextField field = (JTextField) getEditor().getEditorComponent();
        // basically c&p JComponent.processKeyBinding (it's protected so
        // can't call directly from here)
        InputMap map = field.getInputMap(WHEN_FOCUSED);
        ActionMap am = field.getActionMap();

        if(map != null && am != null && isEnabled()) {
            Object binding = map.get(ks);
            Action action = (binding == null) ? null : am.get(binding);
            if (action != null) {
                return SwingUtilities.notifyAction(action, ks, e, field,
                                                   e.getModifiers());
            }
        }

        return false;
    }

}

然后,在您的cellEditor中使用该实例,例如:

JTable table = new JTable(new AncientSwingTeam()) {

    @Override
    public TableCellEditor getCellEditor(int row, int column) {
        if (column == 1) {
            // m_table is the JTable

            JComboBox choices = new JTableEditorComboBox();
            choices.setEditable(true);
            choices.addItem(new String("item 1"));

            DefaultCellEditor editor = new DefaultCellEditor(choices);
            editor.setClickCountToStart(2);
            return editor;
        }

        return super.getCellEditor(row, column);
    }

};