好吧,这很难解释,但我会尽力的。
我在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中包含任一组件的单元格):
>
当我使用tab键或箭头键导航到JTextField,然后开始键入时,我键入的字符会自动输入单元格。然而,当我以同样的方式导航到JComboBox,然后开始键入时,除了出现组合下拉按钮外,什么也不会发生。除非我先按F2键,否则我键入的字符都不会被输入。
所以我的问题是:在上面描述的两个实例中,我需要做什么才能让JComboBox的行为完全像JTextFields?
请不要问我为什么要做我正在做的事情,或者建议替代方案(就是这样,我需要这样做),是的,我已经阅读了所有有问题的组件的应用编程接口......问题是,这是一个摇摆应用编程接口。
bullet 2的另一种选择是将keyEvents的所有传递移动到定制的JComboBox实现中:在那里,实现其processKeyBinding,类似于table。进程键绑定。比如:
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);
}
};
进一步的谷歌搜索让我看到了以下文章:
http://www.jroller.com/santhosh/entry/keyboard_handling_in_tablecelleditor
虽然它没有描述与我相同的问题,但它肯定有一些共同的特点。
使用这篇文章中的一些建议,我能够(至少)解决我问题中的键盘位(我问题的第2点中描述的那个)。我通过覆盖JTable
的ProcKeyBinding
方法做到了这一点,如下所示:
protected boolean processKeyBinding( KeyStroke key_stroke, KeyEvent e, int condition, boolean pressed ) {
Object source = e.getSource();
if ( source instanceof JTable ) {
JTable table = (JTable) source;
Component comp = table.getEditorComponent();
if ( comp instanceof JComboBox ) {
JComboBox combo_box = (JComboBox) comp;
// this bit is quite hacky. Since I want comboboxes to behave exactly like textfields,
// simply check to see how a textfield would handle this event.
JTextField tmp_field = new JTextField();
InputMap input_map = tmp_field.getInputMap( condition );
ActionMap action_map = tmp_field.getActionMap();
if( input_map != null && action_map != null && isEnabled() ) {
Object binding = input_map.get( key_stroke );
Action action = ( binding == null ) ? null : action_map.get( binding );
if( action != null ) {
combo_box.requestFocus();
ComboBoxEditor combo_editor = combo_box.getEditor();
JTextField text_field = (JTextField) combo_editor.getEditorComponent();
if ( e.getKeyChar() == ' ' ) { // backspace
String cur_val = text_field.getText();
if ( ! cur_val.equals( "" ) )
text_field.setText( cur_val.substring( 0, cur_val.length() - 1 ) );
}
else
text_field.setText( text_field.getText() + e.getKeyChar() );
return false;
}
}
}
}
return super.processKeyBinding( key_stroke, e, condition, pressed );
}
这种方法对我来说似乎有点像黑客,但它又是摇摆的,所以它可能是合理的。
在我问题的第1点描述的场景中(即使用鼠标时),让JComboxes表现得像JTextFields一样的问题仍然存在,如果有人想尝试一下的话。
灰
现在,在第一行第三列(“OK”)中,您可以在JComboBox中选择表示一行的不同条目。因此一行有三个引用另一行的JComboBoxes。如果您在这样的JComboBox中单击,您会注意到它总是选择第一个条目,而不是您在单击之前看到的带有数字的条目。 也许现在你明白我想做什么了?
问题内容: 我不知道如何在特定行中设置一个jcombobox …现在我已经为所有行设置了这个jcombobox,但是我只希望在一行中设置它: 问题答案: 更新: 在测试我的(可能是不完整的)答案时,我遇到了一个非常好的SO问题,我认为它将比我能提供的更好:将JComboBox放入JTable 另一个更新: 我再次阅读了您的问题,并且意识到您要求输入 特定的行 。我能想到的唯一方法是创建一个自定义C
我创建了一个表单,其中添加了一个,它有3列。第二列和第三列有编辑器。 我希望当我们选择第二列组合框的第一项时,第三列组合框的第一个组合框也应该被选择,反之亦然。 我该怎么做?
我有一个在运行时加载行的表。加载后,用户需要在每一行的第一列中从中选择一个项目。然后他需要在每行的同一行上从另一个中选择一个项目。第二个的内容取决于第一个的选择。 我现在的编码方式是更改整个第二列的combobox内容。 有没有一种方法可以让每一行的组合框对象都不一样,这样我就可以在第一个组合框中选择一个值的时候处理它?
我有一个JTable对象,我会在一个列上添加5个不同的JComboBox。 我已经尽力了: 但这会将相同的JComboBox添加到该列的所有单元格中。如何在同一列中添加不同的内容? 非常感谢。
我试图在JTable的某个列中放置一个JComboBox。我有这个代码,它正在工作: 我的问题是,在选中该列中的一个单元格之前,它不会显示为JComboBox。加载JFrame时,整个表看起来都一样,好像所有单元格中只有文本。单击时,它会显示组合框的箭头和选项,但再次取消选择时,它看起来像一个常规单元格。 有办法绕过它吗?