JTable изменяет порядок столбцов, а затем редактирует ошибку поднятия ячейки - PullRequest
0 голосов
/ 20 мая 2018

У меня странная проблема с JTable.

  1. Что у меня есть

JTable с двумя столбцами.Во втором столбце в качестве редактора ячеек используется JComboBox.

Проблема

Когда я редактирую эту ячейку JComboBox с порядком столбца источника, он работает нормально. Но когда я сначала изменяю столбец, например, переключаю этот столбец 2 (столбец JComboBox становится первым), я редактировал ошибку создания ячейки JComboBox. Я должен дважды щелкнуть эту ячейку, чтобы вызвать событие редактирования, в противном случае,JComboBox не активирован.

То, что я пытался

Я пытался использовать TableCellListener , но возникает исключение, например, индекс столбца -1;

Мой SSCCE:

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);
            }
        }
    }

}

1 Ответ

0 голосов
/ 20 мая 2018

Я должен дважды щелкнуть эту ячейку, чтобы запустить событие редактирования, в противном случае JComboBox не активируется.

Это происходит только при первой попытке изменить столбец после изменения столбца.порядок.Это также произойдет, если вы вернете колонку в исходное положение.

Это похоже на то, что таблица не имеет фокуса, поэтому первый щелчок мышью дает фокус таблицы.

Так что вы можете попробовать добавить TableColumnModelListener к TableColumModel.Затем в событии columnMoved вы можете попробовать использовать table.requestFocusInWindow()

...