【问题标题】:Placeholder for editable JComboBox in JTableJTable 中可编辑 JComboBox 的占位符
【发布时间】:2019-02-22 01:22:09
【问题描述】:

我有一个JTable,其中一列(第 1 列)是一个 JComboBox,它允许从列表中创建选项,并且可以在其中输入新选项。 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);
            }
        });
    }
}

在表格中,用户可以而且应该为空条目输入值并不明显,因此我想包含占位符文本以明确这一点。我已经看到elsewhere 在不可编辑的组合的情况下可以为setRenderer 提供自定义ListCellRenderer,但在可编辑组合的情况下(如tutorial 中所述)似乎ComboBoxEditor必须使用setEditor 提供。有没有一个简单的实现,或者甚至更好的方法来达到同样的目的?

【问题讨论】:

    标签: java swing jtable jcombobox


    【解决方案1】:

    实际上,JTable 中的输入组件是一种特殊情况,因为它们仅在单元格被编辑时才处于活动状态。因此,除了设置编辑器来控制值的编辑方式外,您还需要更改渲染器以控制所选值的呈现方式,使用

        // 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>"));
    

    这里的PlaceholderRenderer 应该是TableCellRenderer 实现,当没有选择值时显示占位符字符串。例如:

    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);  
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-04
      • 1970-01-01
      • 2015-01-27
      • 1970-01-01
      • 2016-08-29
      • 2010-12-19
      • 1970-01-01
      • 2020-02-22
      • 1970-01-01
      相关资源
      最近更新 更多