Java JTable更改列顺序,然后编辑单元格
我对JTable有一个奇怪的问题 我所拥有的 两列JTable。第二列使用JComboBox作为单元格编辑器 问题 当我用origin列顺序编辑JComboBox单元格时,它工作得很好。但是,当我首先更改列时,例如将2列JComboBox列切换为fist,然后我编辑了JComboBox单元格。我必须单击该单元格两次才能触发编辑事件,否则JComboBox不会被激活 我试过的 我尝试使用,但它引发了异常,例如列索引为-1 我的SSCCE:Java JTable更改列顺序,然后编辑单元格,java,swing,user-interface,jtable,tablecelleditor,Java,Swing,User Interface,Jtable,Tablecelleditor,我对JTable有一个奇怪的问题 我所拥有的 两列JTable。第二列使用JComboBox作为单元格编辑器 问题 当我用origin列顺序编辑JComboBox单元格时,它工作得很好。但是,当我首先更改列时,例如将2列JComboBox列切换为fist,然后我编辑了JComboBox单元格。我必须单击该单元格两次才能触发编辑事件,否则JComboBox不会被激活 我试过的 我尝试使用,但它引发了异常,例如列索引为-1 我的SSCCE: import java.awt.BorderLayout;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.AbstractAction;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import java.awt.GridLayout;
import javax.swing.JTable;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JScrollPane;
public class MainTable extends JDialog {
private static final long serialVersionUID = 156332386872772726L;
private final JPanel contentPanel = new JPanel();
private DefaultTableModel tableModel;
private JTable table;
public static void main(String[] args) {
try {
MainTable dialog = new MainTable();
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
public MainTable() {
setBounds(100, 100, 450, 300);
getContentPane().setLayout(new BorderLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
contentPanel.setLayout(new GridLayout(1, 0, 0, 0));
{
JScrollPane scrollPane = new JScrollPane();
contentPanel.add(scrollPane);
{
table = new JTable();
table.setAutoCreateRowSorter(true);
tableModel = new DefaultTableModel(new String[]{"first","second"},0);
table.setModel(tableModel);
{
//set comboBox to table
JComboBox<String> comboBox = new JComboBox<String>();
comboBox.addItem("Input");
comboBox.addItem("Output");
table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(comboBox));
table.getColumnModel().addColumnModelListener(new TableColumnModelListener(){
@Override
public void columnAdded(TableColumnModelEvent arg0) {
}
@Override
public void columnMarginChanged(ChangeEvent arg0) {
}
@Override
public void columnMoved(TableColumnModelEvent arg0) {
table.requestFocusInWindow();
comboBox.setFocusable(true);
comboBox.requestFocus();
comboBox.grabFocus();
comboBox.requestFocusInWindow();//try to get focus, not worked.
}
@Override
public void columnRemoved(TableColumnModelEvent arg0) {
}
@Override
public void columnSelectionChanged(ListSelectionEvent arg0) {
}
});
}
// TableCellListener tcl = new TableCellListener(table, new AbstractAction(){
// @Override
// public void actionPerformed(ActionEvent e) {
// }
// });
tableModel.addRow(new Object[]{"1","Input"});
tableModel.addRow(new Object[]{"2","Output"});//init. add 2 rows
scrollPane.setViewportView(table);
}
}
{
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane, BorderLayout.SOUTH);
{
JButton okButton = new JButton("Add");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int row = tableModel.getRowCount();
tableModel.addRow(new Object[]{row,"Input"});//click button to add a row
}
});
buttonPane.add(okButton);
getRootPane().setDefaultButton(okButton);
}
}
}
}
我必须单击该单元格两次才能触发编辑事件,否则JComboBox不会被激活
这仅在更改列顺序后第一次尝试编辑列时发生。如果将柱切换回其原始位置,也会发生这种情况
这就像桌子没有焦点一样,所以第一次鼠标点击就是给桌子焦点
因此,您可以尝试将TableColumnModelListener添加到TableColumnModel。然后在columnMoved事件中,您可以尝试使用table.requestFocusInWindow谢谢您的帮助!我尝试了你的方法,我发现在重新排序之后,组合框失去了焦点,在第一次单击之后,表获得了焦点。在columnMoved中,我添加了table.requestFocusInWindow和comboBox.requestFocus,但它不起作用。我已经解决了它。使用table.updateUI;我相信你会成功的@lution,您不应该使用updateUI。在进行LAF更改时在内部调用。尝试将table.requestFocusInWindow包装到SwingUtilities.invokeLater中。那就是确保代码在所有列排序逻辑完成后执行。感谢您的帮助!我试试看。