问题是,当用户单击具有线条样式的单元格并选择 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);
}
}
}
表格单元颜色编辑器:
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;
}
}
表格单元线编辑器:
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);
}
}
枚举线条样式:
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();
}
颜色发生器:
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;
}
}