简体   繁体   English

JComboBox作为自定义TableCellEditor

[英]JComboBox as a Custom TableCellEditor

I have a table. 我有一张桌子。 Changes on that table update database. 对该表更新数据库的更改。 One column is edited by a JComboBox in that table. 一列由该表中的JComboBox编辑。 Clicks to any cell in that column fires a tableChanged event. 单击该列中的任何单元格将触发tableChanged事件。 However it needs to be fired after selecting an item of a JComboBox. 但是,在选择JComboBox的项目后需要触发它。 How can i make tableChanged occur after selection? 如何在选择后使tableChanged出现?

public class JIDCellEditor extends AbstractCellEditor implements TableCellEditor {

    JComboBox jComboBox;

    @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();
        vector.add(0);
        for (int i = 0; i < table.getRowCount(); i++) {
            if (!vector.contains(table.getValueAt(i, 0)) && table.getValueAt(i, 3).toString().equals("Female")) {
                vector.add(table.getValueAt(i, 0));
            }
        }
        vector.remove(table.getValueAt(row, 0));
        jComboBox = new JComboBox(vector);
        jComboBox.setSelectedItem(value);
        return jComboBox;
    }
}

I would highly recommend using SwingX which has a ComboBoxCellEditor component. 我强烈建议使用具有ComboBoxCellEditor组件的SwingX It's essentially Sun's incubator for features Swing components should have. 它本质上是Sun的Swing组件应具备的功能的孵化器。 I have no idea if the project is still actively developed, but its mature, and I've used it in many projects. 我不知道该项目是否仍在积极开发,但它已经成熟,我已经在很多项目中使用过它。

If, for whatever reason, you can't or don't want to use an external library, here is their code (with parts modified to remove custom SwingX features), comments intact: 如果由于某种原因,您不能或不想使用外部库,这里是他们的代码(修改了部分以删除自定义SwingX功能),注释完好无损:

Note: the library is GPL'ed code. 注意:该库是GPL代码。

/*
 * $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>
 * </pre>
 * 
 * </p>
 */
public class ComboBoxCellEditor extends DefaultCellEditor {

    /**
     * Creates a new ComboBoxCellEditor.
     * 
     * @param comboBox the comboBox that should be used as the cell editor.
     */
    public ComboBoxCellEditor(final JComboBox comboBox) {
        super(comboBox);

        comboBox.removeActionListener(this.delegate);

        this.delegate = new EditorDelegate() {
            @Override
            public void setValue(final Object value) {
                comboBox.setSelectedItem(value);
            }

            @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;
                }
                return true;
            }

            @Override
            public boolean stopCellEditing() {
                if (comboBox.isEditable()) {
                    // Commit edited value.
                    comboBox.actionPerformed(new ActionEvent(ComboBoxCellEditor.this, 0, ""));
                }
                return super.stopCellEditing();
            }

            @Override
            public void actionPerformed(final ActionEvent e) {
                ComboBoxCellEditor.this.stopCellEditing();
            }
        };
        comboBox.addActionListener(this.delegate);
    }
}

Now it works. 现在它有效。 JComboBox needs to be reinitialized every time getTableCellEditorComponent method invoked. 每次调用getTableCellEditorComponent方法时,都需要重新初始化JComboBox。 And in the itemstatechange of this JComboBox stopCellEditing() method must notify listeners that editing done when item is selected. 并且在此JComboBox的itemstatechange中,stopCellEditing()方法必须通知侦听器在选择项目时完成编辑。 That make the TableModelListener fireTableChanged event. 这使得TableModelListener成为fireTableChanged事件。 (Fixed) However it also fires that event when you click a JComboBox after clicking another JComboBox without making a selection. (已修复)但是,在单击另一个JComboBox而未进行选择后单击JComboBox时,它也会触发该事件。 (/Fixed) (/固定)

Edit: Following code is the last version. 编辑:以下代码是最后一个版本。 By this TableModelListener is notified only when an item is selected. 通过此TableModelListener仅在选择项目时通知。 The problem mentioned above is fixed. 上面提到的问题是固定的。 It was because of default stopCellEditing() method always returned true. 这是因为默认的stopCellEditing()方法总是返回true。 This cause cell editing stop in an unexpected way. 这会导致单元格编辑以意外方式停止。 It must be overriden as needed and fireEditingStopped(); 必须根据需要覆盖它并使用fireEditingStopped(); must be used to notify TableModelListener 必须用于通知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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM