Заполнитель для редактируемого JComboBox в JTable - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть 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);
            }
        });
    }
}

В таблице не очевидно, что пользователь может и должен вводить значения для пустых записей, поэтому я хотел бы включить текст-заполнитель, чтобы прояснить это.Я видел в другом месте , что пользовательский ListCellRenderer может быть предоставлен с setRenderer в случае нередактируемых комбинаций, но в случае редактируемых комбинаций (как объяснено в учебнике ) представляется, что ComboBoxEditor должен быть предоставлен с использованием setEditor.Есть ли простая реализация для этого или, возможно, даже лучший способ достичь тех же целей?

1 Ответ

0 голосов
/ 22 февраля 2019

На самом деле, входные компоненты внутри 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);  
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...