繁体   English   中英

在用作表编辑器时动态填充JComboBox

[英]Dynamically filling a JComboBox when it's used as a table editor

我有一个用例(在Java Swing中),其中某些JTable列必须可以通过JComboBox编辑器进行编辑,但是可选值列表取决于行的域对象(我使用的是自定义TableModel )。

CellEditor界面具有停止或取消编辑时要调用的事件,但是没有启动编辑的事件(我希望这是填充选择值列表的好地方)。

开始对单元格进行编辑时如何填充组合框?

ComboBox中可用的项目是其模型的责任。 自定义您的ComboBoxModel (尤其是getElementAt(int)方法),以便它查询有问题的域对象。

您可能要扩展DefaultComboBoxModel而不是从头开始实现接口。

这是一个问题,我必须在今年早些时候解决(下面的代码来自该项目)。 解决方案是为组合框创建专用模型:

mEntityListModel = getMyEntityModel();

T[] items = (T[]) Array.newInstance(type, mEntityListModel.getSize());

for (int i = 0; i < items.length; i++) {
    items[i] = mEntityListModel.getElementAt(i);
}
mComboBoxModel = new DefaultComboBoxModel<T>(items);    

并使用组合框模型均衡实体列表中的每个更改:

mEntityListModel.addListDataListener(new DataListener());// make a better MVC solution if you like

private class DataListener implements ListDataListener {

    @Override
    public void intervalAdded(ListDataEvent e) {
        mComboBoxModel.insertElementAt(mEntityListModel.getElementAt(e.getIndex0()), e.getIndex0());
    }

    @Override
    public void intervalRemoved(ListDataEvent e) {
        Object deletedElement = mComboBoxModel.getElementAt(e.getIndex0());

        // Clear the combobox selection, if the item is deleted!
        if (mSelectionManager.isSelected(deletedElement)) {
            mSelectionManager.setSelectedItem(null);
        }
        mComboBoxModel.removeElementAt(e.getIndex0());
    }

    @Override
    public void contentsChanged(ListDataEvent e) {
        intervalRemoved(e);
        intervalAdded(e);
    }

}

旁注:这是表的组合框中的更改被注册的方式:

tablecolumn.getCellEditor()
           .addCellEditorListener(new CellChangeListener());


private class CellChangeListener implements CellEditorListener {

    @Override
    public void editingStopped(ChangeEvent e) {
        DefaultCellEditor editor;
        Object newValue;
        if (e.getSource() instanceof DefaultCellEditor) {
            editor = (DefaultCellEditor) e.getSource();

            newValue = editor.getCellEditorValue();

            if (newValue != null) {
                //set the newValue for the combobox selection manager
            }
        }
    }

    @Override
    public void editingCanceled(ChangeEvent e) {
    }
}

如您所见,组合框项目列表在编辑器开始工作之前已更新。 编辑者不对该工作负责。

一种方法是重写JTable的getCellEditor(...)方法:

import java.awt.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;

public class TableComboBoxByRow extends JPanel
{
    List<String[]> editorData = new ArrayList<String[]>(3);

    public TableComboBoxByRow()
    {
        setLayout( new BorderLayout() );

        // Create the editorData to be used for each row

        editorData.add( new String[]{ "Red", "Blue", "Green" } );
        editorData.add( new String[]{ "Circle", "Square", "Triangle" } );
        editorData.add( new String[]{ "Apple", "Orange", "Banana" } );

        //  Create the table with default data

        Object[][] data =
        {
            {"Color", "Red"},
            {"Shape", "Square"},
            {"Fruit", "Banana"},
            {"Plain", "Text"}
        };
        String[] columnNames = {"Type","Value"};

        DefaultTableModel model = new DefaultTableModel(data, columnNames);
        JTable table = new JTable(model)
        {
            //  Determine editor to be used by row
            public TableCellEditor getCellEditor(int row, int column)
            {
                int modelColumn = convertColumnIndexToModel( column );

                if (modelColumn == 1 && row < 3)
                {
                    JComboBox<String> comboBox1 = new JComboBox<String>( editorData.get(row));
                    return new DefaultCellEditor( comboBox1 );
                }
                else
                    return super.getCellEditor(row, column);
            }
        };

        JScrollPane scrollPane = new JScrollPane( table );
        add( scrollPane );
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("Table Combo Box by Row");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new TableComboBoxByRow() );
        frame.setSize(200, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

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

暂无
暂无

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

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