简体   繁体   English

JTable中可编辑JComboBox的占位符

[英]Placeholder for editable JComboBox in JTable

I have a JTable in which one column (Column 1) is a JComboBox that allows options to be made from a list, and to which new options can be entered. 我有一个JTable ,其中一个列(第1列)是一个JComboBox,它允许从列表中进行选项,并可以在其中输入新的选项。 MWE: MWE:

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableColumn;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.HashSet;

public class ComboTableDemo extends JPanel {

    public ComboTableDemo() {
        super(new GridLayout(1,0));
        final String[] headings = {"Name", "Option"};
        final String string1 = "Foo";
        final String string2 = "Bar";
        Object[][] data = {
                {"Albert", string1},
                {"Bob", null},
                {"Clare", null},
                {"David", null}
        };

        final JTable table = new JTable(data, headings);
        table.setPreferredScrollableViewportSize(new Dimension(300, 100));
        table.setFillsViewportHeight(true);

        final String[] optionsInit = new String[] {string1, string2};
        HashSet<String> options = new HashSet<String>(Arrays.asList(optionsInit));
        JComboBox<String> optionsCombo = new JComboBox<String>(optionsInit);

        optionsCombo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ev) {
                String newSelection = (String)optionsCombo.getSelectedItem();
                if(!options.contains(newSelection)) {
                    options.add(newSelection);
                    optionsCombo.addItem(newSelection);
                }
            }

        });
        optionsCombo.setEditable(true);
        TableColumn column = table.getColumnModel().getColumn(1);
        column.setCellEditor(new DefaultCellEditor(optionsCombo));

        add(new JScrollPane(table));
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("ComboTableDemo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                ComboTableDemo pane = new ComboTableDemo();
                pane.setOpaque(true);
                frame.setContentPane(pane);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

In the table it isn't obvious that the user can and should enter values for the empty entries, so I'd like to include placeholder text to make this clear. 在表中,用户可以并且应该为空条目输入值并不明显,因此我想添加占位符文本以使这一点变得清楚。 I've seen elsewhere that a custom ListCellRenderer can be provided with setRenderer in the case of uneditable combos, but in the case of editable combos (as explained in the tutorial ) it appears that a ComboBoxEditor must be supplied using setEditor . 我在其他地方看到过,在无法编辑的连击情况下,可以为setRenderer提供自定义ListCellRenderer ,但是在可编辑的连击情况下(如本教程中所述),看来必须使用setEditor提供ComboBoxEditor Is there a simple implementation for this, or perhaps even a better way to achieve the same ends? 为此是否有一个简单的实现,或者甚至是达到相同目的的更好方法?

Actually, input components within a JTable present a special case, since they are only active when the cell is edited. 实际上, JTable输入组件代表一种特殊情况,因为它们仅在单元格被编辑时才处于活动状态。 So as well as setting the editor to control how a value is edited, you also need to change the renderer to control how the chosen value is presented, with 因此,除了设置编辑器以控制值的编辑方式外,还需要更改渲染器以控制如何显示所选值。

    // As before:
    TableColumn column = table.getColumnModel().getColumn(1);
    column.setCellEditor(new DefaultCellEditor(optionsCombo));
    // Additional line to set renderer:
    column.setCellRenderer(new PlaceholderRenderer("<choose or add option>"));

Here the PlaceholderRenderer should be a TableCellRenderer implementation that displays the placeholder string when no value is selected. 这里PlaceholderRenderer应该是一个TableCellRenderer实现,当没有选择任何值时,该实现将显示占位符字符串。 Eg: 例如:

import java.awt.Component;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class PlaceholderRenderer extends DefaultTableCellRenderer {

    final private String placeholder;

    public PlaceholderRenderer(String placeholder) {
        super();
        this.placeholder = placeholder;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table,
            Object value,
            boolean isSelected,
            boolean hasFocus,
            int row,
            int column) {
        if ((value == null) || (value.equals(""))) { 
            return super.getTableCellRendererComponent(table, this.placeholder, isSelected, hasFocus, row, column);  
        } else { 
            return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);  
        }
    }

}

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

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