Контролируемое редактирование выделения строки в JTable - PullRequest
3 голосов
/ 06 февраля 2012

У меня есть JTable, отображающий строки из базы данных SQL. Таблица сравнительно небольшая (всего 4 столбца и до 1000 строк).

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

Я пробовал несколько разных способов управления выборками редактирования, используя метод valueChanged моего JTable, но мне не очень повезло.

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

Кто-нибудь может подсказать, как мне этого добиться?

//  Create table with database data
   table = new JTable(new DefaultTableModel(data, columnNames)) {
        public Class getColumnClass(int column) {
            for (int row = 0; row < getRowCount(); row++) {
                Object o = getValueAt(row, column);
                if (o != null){
                    return o.getClass();
                }
            }
            return Object.class;
        }

        @Override
        public boolean isCellEditable(int row, int col){
            return true; 
        }

        @Override
        public boolean editCellAt(int row, int column) {
            boolean ans = super.editCellAt(row, column);
            if (ans) { 
                Component editor = table.getEditorComponent();
                editor.requestFocusInWindow();
            }
            return ans;
        }

        @Override
        public void valueChanged(ListSelectionEvent source) {
            super.valueChanged(source);
            if (table!=null)
                table.changeSelection(getSelectedRow(), getSelectedColumn()+1, false, false);
        }

    };

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

public class ExchangeTableCellEditor  extends AbstractCellEditor implements TableCellEditor {

private JTable table;

JComponent component = new JTextField();

public ExchangeTableCellEditor(JTable table) {
    this.table = table;
}

public boolean stopCellEditing() {
    boolean ans = super.stopCellEditing();
    //now we want to increment the cell count
    table.editCellAt(table.getSelectedRow(), table.getSelectedColumn()+1);
    return ans;
}

@Override
public void cancelCellEditing() {
    //do nothing... must accept cell changes 
}

@Override
public Object getCellEditorValue() {
    return ((JTextField)component).getText();
}

@Override
public Component getTableCellEditorComponent(JTable arg0, Object value,
        boolean arg2, int arg3, int arg4) {
    ((JTextField)component).setText((String)value);
    return component;
}

}

Ответы [ 2 ]

4 голосов
/ 06 февраля 2012

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

Приложение: я не знаком с подходом, показанным в вашем фрагменте.Вместо этого, зарегистрируйте TableModelListener в вашей модели, как показано ниже, и обновите базу данных с любой степенью детализации.См. Также Как использовать таблицы: прослушивание изменений данных .

Приложение: @kleopatra верна для вашего TableCellEditor.Один удобный способ уведомить слушателей - вызвать супер реализацию, как показано здесь .Обратите внимание, что delegate вызывает fireEditingStopped().

/** @see https://stackoverflow.com/questions/9155596 */
public class NewJavaGUI extends JPanel {

    private final JTable table;

    public NewJavaGUI() {
        String[] colNames = {"C1", "C2", "C3"};
        DefaultTableModel model = new DefaultTableModel(colNames, 0) {

            @Override
            public boolean isCellEditable(int row, int col) {
                // return your actual criteria
                return true;
            }

            @Override
            public Class getColumnClass(int col) {
                // return your actual type tokens
                return getValueAt(0, col).getClass();
            }
        };
        // Add data; note auto-boxing
        model.addRow(new Object[]{"A1", "A2", 42});
        model.addRow(new Object[]{"B1", "B2", 42d});
        model.addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                // DML as indicated
            }
        });
        table = new JTable(model);
        this.add(table);
    }

    private void display() {
        JFrame f = new JFrame("NewJavaGUI");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new NewJavaGUI().display();
            }
        });
    }
}
0 голосов
/ 06 февраля 2012

Упомянутое вами поведение может быть достигнуто путем принудительного возобновления редактирования таблицы.

Сначала убедитесь, что вы теперь используете yourRow и Column и добавили свой собственный tablecelleditor, который расширяется из AbstractCellEditor, а затем добавьте его в свойМетод stopCellEditing:

EventQueue.invokeLater(new Runnable()
    {

      public void run()
      {
        yourTable.editCellAt( yourRow, yourColumn+1);
      }
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...