JComboBox как пользовательский TableCellEditor - PullRequest
3 голосов
/ 29 сентября 2011

У меня есть стол.Изменения в этой таблице обновляют базу данных.Один столбец редактируется JComboBox в этой таблице.Щелчок по любой ячейке в этом столбце вызывает событие tableChanged.Однако он должен быть запущен после выбора элемента JComboBox.Как я могу заставить tableChanged произойти после выбора?

Ответы [ 2 ]

6 голосов
/ 29 сентября 2011

Я бы настоятельно рекомендовал использовать SwingX с компонентом ComboBoxCellEditor . По сути, это инкубатор Sun, который должен иметь компоненты Swing. Я понятия не имею, все еще ли активно разрабатывается проект, но он зрелый, и я использовал его во многих проектах.

Если по какой-либо причине вы не можете или не хотите использовать внешнюю библиотеку, вот их код (с частями, измененными для удаления пользовательских функций SwingX), комментарии не повреждены:

Примечание: библиотека написана под GPL.

<code>/*
 * $Id: ComboBoxCellEditor.java 3738 2010-07-27 13:56:28Z bierhance $
 * 
 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A. All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.util.EventObject;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;

/**
 * <p>
 * This is a cell editor that can be used when a combo box (that has been set up for automatic completion) is to be used in a JTable. The
 * {@link javax.swing.DefaultCellEditor DefaultCellEditor} won't work in this case, because each time an item gets selected it stops cell
 * editing and hides the combo box.
 * </p>
 * <p>
 * Usage example:
 * </p>
 * <p>
 * 
     * <pre>
 * <code>
 * JTable table = ...;
 * JComboBox comboBox = ...;
 * ...
 * TableColumn column = table.getColumnModel().getColumn(0);
 * column.setCellEditor(new ComboBoxCellEditor(comboBox));
 * </code>
 * 
* * * / открытый класс ComboBoxCellEditor extends DefaultCellEditor { / ** * Создает новый ComboBoxCellEditor. * * @param comboBox comboBox, который должен использоваться в качестве редактора ячеек. * / public ComboBoxCellEditor (окончательный JComboBox comboBox) { супер (COMBOBOX); comboBox.removeActionListener (this.delegate); this.delegate = new EditorDelegate () { @Override public void setValue (окончательное значение объекта) { comboBox.setSelectedItem (значение); } @Override public Object getCellEditorValue () { return comboBox.getSelectedItem (); } @Override public boolean shouldSelectCell (final EventObject anEvent) { if (anEvent instanceof MouseEvent) { final MouseEvent e = (MouseEvent) anEvent; return e.getID ()! = MouseEvent.MOUSE_DRAGGED; } вернуть истину; } @Override public boolean stopCellEditing () { if (comboBox.isEditable ()) { // Фиксировать отредактированное значение. comboBox.actionPerformed (новый ActionEvent (ComboBoxCellEditor.this, 0, "")); } return super.stopCellEditing (); } @Override public void actionPerformed (final ActionEvent e) { ComboBoxCellEditor.this.stopCellEditing (); } }; comboBox.addActionListener (this.delegate); } }
4 голосов
/ 30 сентября 2011

Теперь это работает.JComboBox необходимо повторно инициализировать каждый раз, когда вызывается метод getTableCellEditorComponent.И в itemtatechange этого метода JComboBox stopCellEditing () должен уведомить слушателей, что редактирование завершено, когда элемент выбран.Это делает событие TableModelListener fireTableChanged.(Исправлено) Однако это событие также запускается, когда вы щелкаете JComboBox после щелчка по другому JComboBox без выбора.(/ Исправлено)

Редактировать: следующий код является последней версией.Этим TableModelListener уведомляется только тогда, когда элемент выбран.Проблема, упомянутая выше, исправлена.Это было из-за того, что метод stopCellEditing () по умолчанию всегда возвращал true.Это приводит к неожиданному прекращению редактирования ячейки.Он должен быть переопределен по мере необходимости и fireEditingStopped ();должен использоваться для уведомления TableModelListener

public class JIDCellEditor extends AbstractCellEditor implements TableCellEditor {

    private JComboBox jComboBox = new JComboBox();
    boolean cellEditingStopped = false;

    @Override
    public Object getCellEditorValue() {
        return jComboBox.getSelectedItem();
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        Vector vector = new Vector();
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        arrayList.add(Integer.parseInt(value.toString()));
        vector.add(0);
        for (int i = 0; i < table.getRowCount(); i++) {
            if (!vector.contains(table.getValueAt(i, 0)) && table.getValueAt(i, 3).toString().equals("Sheep")) {
                vector.add(table.getValueAt(i, 0));
            }
        }
        vector.remove(table.getValueAt(row, 0));

        for (int i = 0; i < vector.size(); i++) {
        }
        jComboBox = new JComboBox(vector);
        jComboBox.setSelectedItem(value);

        jComboBox.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    fireEditingStopped();
                }
            }
        });
        jComboBox.addPopupMenuListener(new PopupMenuListener() {

            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                cellEditingStopped = false;
            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                cellEditingStopped = true;
                fireEditingCanceled();
            }

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {

            }
        });
        return jComboBox;
    }

    @Override
    public boolean stopCellEditing() {
        return cellEditingStopped;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...