JTable:TableCellEditor未显示所选颜色

时间:2017-02-24 09:19:14

标签: java swing jtable tablecelleditor

我有一个有3列的JTable,第一列是简单文本,另外2列是JComboBox。列名和列电子邮件都有自定义TableCellEditor和TableCellRenderer。

enter image description here

有时,当我单击未选中的行中的组合框时,将不会使用正确的选定颜色(蓝色)绘制单元格。

为了便于说明,TableCellRenderer绘制粉红色单元格,TableCellEditor绘制橙色单元格。

enter image description here

JTable为isCellSelected()返回false,更具体地说,在JTable editCellAt()处为isRowSelected()返回false。但是,当渲染器调用isCellSelected()时,它返回true,因此渲染器颜色正确。

enter image description here

我无法弄清楚这里出了什么问题。 我的SSCCE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumnModel;
import org.iii.snsi.streamcenter.main.Main;

public class EditorNotSelectedColorFrame {

    public JComponent makeUI() {
        JTable table = new JTable();
        DefaultTableModel model = new DefaultTableModel(new String[]{"COL 1", "COL 2", "COL 3"}, 0);
        table.setModel(model);
        for (int i = 0; i < 5; i++) {
            Object[] row = new Object[3];
            row[0] = new MyListItem(new String[]{"item a", "item b", "item c"});
            row[1] = new MyListItem(new String[]{"item d", "item e", "item f"});
            row[2] = new MyListItem(new String[]{"item g", "item h", "item i"});
            model.addRow(row);
        }

        MyTableCellEditor editor = new MyTableCellEditor(Color.orange, Color.BLACK);
        MyTableCellRenderer renderer = new MyTableCellRenderer(Color.pink, Color.BLACK);
        TableColumnModel columnModel = table.getColumnModel();
        columnModel.getColumn(0).setCellEditor(editor);
        columnModel.getColumn(1).setCellEditor(editor);
        columnModel.getColumn(2).setCellEditor(editor);
        columnModel.getColumn(0).setCellRenderer(renderer);
        columnModel.getColumn(1).setCellRenderer(renderer);
        columnModel.getColumn(2).setCellRenderer(renderer);

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(new JScrollPane(table));
        return panel;
    }

    public static void main(String... args) {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Windows".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                f.getContentPane().add(new EditorNotSelectedColorFrame().makeUI());
                f.setSize(320, 240);
                f.setLocationRelativeTo(null);
                f.setVisible(true);
            }
        });
    }
}

class MyListItem<T> {

    private ArrayList<T> items = new ArrayList<>();
    private Integer selectedIndex = -1;

    public MyListItem(T[] items) {
        selectedIndex = -1;
        this.items.addAll(Arrays.asList(items));
    }

    public ArrayList<T> getItems() {
        return items;
    }

    public void setSelectedIndex(Integer selectedIndex) {
        this.selectedIndex = selectedIndex;
    }

    public Integer getSelectedIndex() {
        return selectedIndex;
    }
}

class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor {

    private Color unselectedBackground;
    private Color unselectedForeground;
    private JMyComboBox comboBox;
    private MyListItem myListItem;

    public MyTableCellEditor(Color bg, Color fg) {
        unselectedBackground = bg;
        unselectedForeground = fg;
        comboBox = new JMyComboBox(bg, fg);
        comboBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                stopCellEditing();
            }
        });
    }

    @Override
    public Object getCellEditorValue() {
        int idx = comboBox.getSelectedIndex();
        if (idx > -1) {
            myListItem.setSelectedIndex(comboBox.getSelectedIndex());
        }
        return myListItem;
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value,
            boolean isSelected, int row, int column) {
        comboBox.removeAllItems();
        if (value instanceof MyListItem) {
            myListItem = (MyListItem) value;
            for (Object item : myListItem.getItems()) {
                comboBox.addItem(item.toString());
            }
            comboBox.setSelectedIndex(myListItem.getSelectedIndex());
        } else {
            myListItem = null;
        }

        if (isSelected) {
            comboBox.setForeground(table.getSelectionForeground());
            comboBox.setBackground(table.getSelectionBackground());
        } else {
            comboBox.setForeground(unselectedForeground);
            comboBox.setBackground(unselectedBackground);
        }

        return comboBox;
    }
}

class MyTableCellRenderer extends DefaultTableCellRenderer {

    private Color unselectedBackground;
    private Color unselectedForeground;
    private JMyComboBox comboBox;

    public MyTableCellRenderer(Color bg, Color fg) {
        super();
        unselectedBackground = bg;
        unselectedForeground = fg;
        comboBox = new JMyComboBox(bg, fg);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        comboBox.removeAllItems();
        if (value instanceof MyListItem) {
            MyListItem cellItem = (MyListItem) value;
            for (Object item : cellItem.getItems()) {
                comboBox.addItem(item.toString());
            }
            comboBox.setSelectedIndex(cellItem.getSelectedIndex());
        }

        if (isSelected) {
            comboBox.setForeground(table.getSelectionForeground());
            comboBox.setBackground(table.getSelectionBackground());
        } else {
            comboBox.setForeground(unselectedForeground);
            comboBox.setBackground(unselectedBackground);
        }

        return comboBox;
    }
}

class JMyComboBox extends JComboBox<String> {

    private MyComboBoxEditor editor = new MyComboBoxEditor();
    private MyComboBoxRenderer renderer = new MyComboBoxRenderer();

    public JMyComboBox(Color bg, Color fg) {
        super();
        setEditable(true);
        setEditor(editor);
        setRenderer(renderer);
        editor.setColors(bg, fg);
        renderer.setColors(bg, fg);
    }

    @Override
    public void setBackground(Color bg) {
        super.setBackground(bg);
        if (editor != null) {
            editor.setColors(bg, getForeground());
        }
    }

    @Override
    public void setForeground(Color fg) {
        super.setForeground(fg);
        if (editor != null) {
            editor.setColors(getBackground(), fg);
        }
    }
}

class MyComboBoxEditor extends BasicComboBoxEditor {

    private JLabel label = new JLabel();

    public MyComboBoxEditor() {
        super();
        label.setOpaque(true);
    }

    public void setColors(Color background, Color foreground) {
        label.setBackground(background);
        label.setForeground(foreground);
    }

    @Override
    public void setItem(Object anObject) {
        super.setItem(anObject);
        label.setText(((JTextField) super.getEditorComponent()).getText());
    }

    @Override
    public Component getEditorComponent() {
        return label;
    }
}

class MyComboBoxRenderer extends DefaultListCellRenderer {

    private Color unselectedBackground;
    private Color unselectedForeground;

    public void setColors(Color background, Color foreground) {
        this.unselectedBackground = background;
        this.unselectedForeground = foreground;
    }

    @Override
    public Component getListCellRendererComponent(JList<?> list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {
        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        if (!isSelected) {
            if (unselectedBackground != null) {
                setBackground(unselectedBackground);
            }
            if (unselectedForeground != null) {
                setForeground(unselectedForeground);
            }
        }
        return this;
    }
}

0 个答案:

没有答案
相关问题