将显示jComboBox的渲染器链接到jTable中的单元格

时间:2013-07-17 12:19:00

标签: java swing jtable jcombobox tablecelleditor

问题是,当用户点击具有线条样式的单元格,并选择4个选项中的一个,然后点击其他具有线条样式的单元格之后,其他单元格显示线条样式,在之前选择的单元格中选择。如何在“线条样式”列中为每个单元格(不同单元格中的不同线条样式)创建唯一的线条样式? “线条颜色”列中的单元格工作正常,它们的实现方式相似。

这是SSCCE:

主类:

import javax.swing.JFrame;

public class PanelMain {
    public static void main(String[] args) {
        String[] tab = { "abc", "cde", "efg" };
        Panel panel = new Panel(tab);
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.setVisible(true);
    }
}

面板:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

@SuppressWarnings("serial")
public class Panel extends JPanel {

    private JScrollPane scrollPane_properties;
    private JTable table_properties;
    private Object[][] dataToTable;

    public Panel(String[] tab) {
        setPreferredSize(new Dimension(293, 416));
        setLayout(null);

        scrollPane_properties = new JScrollPane();
        scrollPane_properties.setBounds(10, 11, 273, 393);
        add(scrollPane_properties);

        dataToTable = new Object[tab.length][3];

        for (int i = 0; i < tab.length; i++) {
            dataToTable[i][0] = tab[i];
            dataToTable[i][1] = LineStyle.values()[0].getStroke();
            dataToTable[i][2] = ColorGenerator.generateColor();
        }

        table_properties = new JTable(new MyTableModel());
        table_properties.setAutoCreateRowSorter(true);

        table_properties.setDefaultRenderer(Color.class, new TableCellColorRenderer(true));
        table_properties.setDefaultEditor(Color.class, new TableCellColorEditor());

        table_properties.setDefaultRenderer(BasicStroke.class, new TableCellLineRenderer(true));
        table_properties.setDefaultEditor(BasicStroke.class, new TableCellLineEditor());

        scrollPane_properties.setViewportView(table_properties);
    }

    class MyTableModel extends AbstractTableModel {
        private String[] columnNames = { "Name", "LineStyle", "LineColor" };
        private Object[][] data = dataToTable;

        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
            return data.length;
        }

        public String getColumnName(int col) {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col) {
            return data[row][col];
        }

        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        public boolean isCellEditable(int row, int col) {
            if (col < 1) {
                return false;
            } else {
                return true;
            }
        }

        public void setValueAt(Object value, int row, int col) {
            data[row][col] = value;
            fireTableCellUpdated(row, col);
        }
    }

}

TableCellColorEditor:

import javax.swing.AbstractCellEditor;
import javax.swing.table.TableCellEditor;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JTable;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TableCellColorEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {
    Color currentColor;
    JButton button;
    JColorChooser colorChooser;
    JDialog dialog;
    protected static final String EDIT = "edit";

    public TableCellColorEditor() {
        button = new JButton();
        button.setActionCommand(EDIT);
        button.addActionListener(this);
        button.setBorderPainted(false);

        colorChooser = new JColorChooser();
        dialog = JColorChooser.createDialog(button, "Pick a Color", true, colorChooser, this, null);
    }

    public void actionPerformed(ActionEvent e) {
        if (EDIT.equals(e.getActionCommand())) {

            button.setBackground(currentColor);
            colorChooser.setColor(currentColor);
            dialog.setVisible(true);

            fireEditingStopped();

        } else {
            currentColor = colorChooser.getColor();
        }
    }

    public Object getCellEditorValue() {
        return currentColor;
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        currentColor = (Color) value;
        return button;
    }
}

TableCellColorRenderer:

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.border.Border;
import javax.swing.table.TableCellRenderer;
import java.awt.Color;
import java.awt.Component;

public class TableCellColorRenderer extends JLabel implements TableCellRenderer {
    Border unselectedBorder = null;
    Border selectedBorder = null;
    boolean isBordered = true;

    public TableCellColorRenderer(boolean isBordered) {
        this.isBordered = isBordered;
        setOpaque(true);
    }

    public Component getTableCellRendererComponent(JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column) {
        Color newColor = (Color) color;
        setBackground(newColor);
        if (isBordered) {
            if (isSelected) {
                if (selectedBorder == null) {
                    selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getSelectionBackground());
                }
                setBorder(selectedBorder);
            } else {
                if (unselectedBorder == null) {
                    unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getBackground());
                }
                setBorder(unselectedBorder);
            }
        }

        setToolTipText("RGB value: " + newColor.getRed() + ", " + newColor.getGreen() + ", " + newColor.getBlue());
        return this;
    }
}

TableCellLineEditor:

import java.awt.BasicStroke;
import java.awt.Component;

import javax.swing.AbstractCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;

public class TableCellLineEditor extends AbstractCellEditor implements TableCellEditor {

    JComboBox combobox;

    public TableCellLineEditor() {

        combobox = new JComboBox(LineStyle.values());
        combobox.setRenderer(new ListCellLineRenderer());
    }

    @Override
    public Object getCellEditorValue() {
        return (BasicStroke) LineStyle.values()[combobox.getSelectedIndex()].getStroke();
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        BasicStroke stroke = (BasicStroke) LineStyle.values()[combobox.getSelectedIndex()].getStroke();
        return combobox;
    }

}

TableCellLineRenderer:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class TableCellLineRenderer extends JPanel implements TableCellRenderer {

    private BasicStroke value;

    public TableCellLineRenderer(boolean isBordered) {
        setOpaque(true);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        if (value != null) {
            g2d.setStroke(value);
            g.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);
        }

    }

    private void setLineType(BasicStroke value) {
        this.value = value;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        setBackground(Color.white);
        if (value instanceof BasicStroke) {
            setLineType((BasicStroke) value);
        } else {
            setLineType(null);
        }
        return this;
    }

}

ListCellLineRenderer:

import java.awt.Component;

@SuppressWarnings({ "rawtypes", "serial" })
public class ListCellLineRenderer extends JPanel implements ListCellRenderer {
    public ListCellLineRenderer() {
    }

    private LineStyle value;

    @Override
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        if (value instanceof LineStyle) {
            setLineType((LineStyle) value);
        } else {
            setLineType(null);
        }
        return this;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        if (value != null) {
            g2d.setStroke(value.getStroke());
            g.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);
        }

    }

    private void setLineType(LineStyle value) {
        this.value = value;
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(50, 20);
    }

}

枚举LineStyle:

import java.awt.BasicStroke;
import java.awt.Stroke;

public enum LineStyle {

    one {
        @Override
        public Stroke getStroke() {
            return new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 4.0f);
        }
    },
    two {
        @Override
        public Stroke getStroke() {
            return new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 4.0f, pattern[1], 0.0f);
        }

    },
    three {
        @Override
        public Stroke getStroke() {
            return new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 4.0f, pattern[2], 0.0f);
        }

    },
    four {
        @Override
        public Stroke getStroke() {
            return new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER, 4.0f, pattern[3], 0.0f);
        }

    };

    private static float[][] pattern = { { 10.0f }, { 10.0f, 10.0f }, { 10.0f, 10.0f, 2.0f, 10.0f }, { 1.0f, 20.0f } };

    public abstract Stroke getStroke();
}

ColorGenerator:

import java.awt.Color;
import java.util.Random;

public class ColorGenerator {

    public static Color generateColor() {

        Random rand = new Random();

        float r = rand.nextFloat();
        float g = rand.nextFloat();
        float b = rand.nextFloat();

        Color randomColor = new Color(r, g, b);

        return randomColor;
    }

}

1 个答案:

答案 0 :(得分:1)

好的,最后我解决了我的问题。这类似于替换每个单元的“独特”组合框。在TableCellLineEditor类中进行此修改后,它可以正常工作:

import java.awt.BasicStroke;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;

public class TableCellLineEditor extends AbstractCellEditor implements TableCellEditor, ActionListener {

    JComboBox combobox;
    private BasicStroke val;
    protected static final String EDIT = "edit";

    public TableCellLineEditor() {

        combobox = new JComboBox(LineStyle.values());
        combobox.setRenderer(new ListCellLineRenderer());
        combobox.setActionCommand(EDIT);
        combobox.addActionListener(this);
    }

    @Override
    public Object getCellEditorValue() {
        return (BasicStroke) ((LineStyle) combobox.getSelectedItem()).getStroke();
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        val = (BasicStroke) value;

        for (int i = 0; i < LineStyle.values().length; i++) {
            if (val.equals(((BasicStroke) (LineStyle.values()[i]).getStroke()))) {
                combobox.setSelectedItem(LineStyle.values()[i]);
            }
        }
        return combobox;
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if (EDIT.equals(e.getActionCommand())) {
            val = (BasicStroke) ((LineStyle) combobox.getSelectedItem()).getStroke();
            fireEditingStopped();
        } else {
            val = (BasicStroke) combobox.getSelectedItem();
        }
    }

}

谢谢大家,感谢您的建议和答案:)