我尝试制作布尔渲染器和布尔编辑器。
布尔渲染器应将布尔值渲染为颜色(两种颜色)。 布尔编辑器应返回JTextField并启用编辑为字符串“T”和“F”
因此,如果单击单元格并键入“T”或“F”,则单元格的颜色必须移动到相应的颜色。
基于this oracle tutorial我尝试制作渲染器和编辑器并将其包含在this oracle provided example中。
布尔渲染器和布尔编辑器下面。我将它们注册到this class。
....
....
table.setDefaultRenderer(Color.class,
new ColorRenderer(true));
table.setDefaultEditor(Color.class,
new ColorEditor());
table.setDefaultRenderer(Boolean.class, new BooleanRenderer()); // My
table.setDefaultEditor(Boolean.class, new BooleanEditor()); // My
//Add the scroll pane to this panel.
add(scrollPane);
....
....
根本不会渲染单元格,并且事情无法正常工作!。
我的代码出了什么问题?
我的渲染器:
import java.awt.Color;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class BooleanRenderer extends JLabel implements TableCellRenderer
{
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
if (hasFocus)
{
Boolean bol = (Boolean) value;
if (bol == Boolean.FALSE)
{
this.setBackground(Color.red);
this.setText("");
} else if (bol == Boolean.TRUE)
{
this.setBackground(Color.BLACK);
}
}
else
{
Boolean bol = (Boolean) value;
if (bol == Boolean.FALSE)
{
this.setBackground(Color.red);
this.setText("");
} else if (bol == Boolean.TRUE)
{
this.setBackground(Color.BLACK);
}
}
if (isSelected)
{
Boolean bol = (Boolean) value;
if (bol == Boolean.FALSE)
{
this.setBackground(Color.red);
this.setText("");
} else if (bol == Boolean.TRUE)
{
this.setBackground(Color.BLACK);
}
} else
{
Boolean bol = (Boolean) value;
if (bol == Boolean.FALSE)
{
this.setBackground(Color.red);
this.setText("");
} else if (bol == Boolean.TRUE)
{
this.setBackground(Color.BLACK);
}
}
return this;
}
}
我的编辑:
import java.awt.Component;
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellEditor;
public class BooleanEditor extends AbstractCellEditor
implements TableCellEditor
{
Boolean bool;
JTextField tf = new JTextField();
@Override
public Object getCellEditorValue()
{
return bool;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
{
if (isSelected)
{
bool = (Boolean) value;
if (tf.getText().equals("T"))
{
bool = new Boolean(true);
} else
{
if (tf.getText().equals("F"))
{
bool = new Boolean(false);
}
}
}
return tf;
}
}
答案 0 :(得分:4)
适用于您的渲染器:
你必须给它一个构造函数并在构造函数内部,将它设置为opaque:
public BooleanRenderer() {
setOpaque(true);
}
否则JLabel根本不会显示任何背景颜色。
对于您的JTable单元格编辑器:
if (isSelected)
块。编辑器将在需要时被调用,并且选中的代码可能会错误,导致代码无法正常运行。getCellEditorValue()
方法中,查询组件的值并根据此值返回相应的布尔值。例如:
public class BooleanEditor extends AbstractCellEditor implements TableCellEditor {
JComboBox<Boolean> combo = new JComboBox<Boolean>(new Boolean[] {
Boolean.TRUE, Boolean.FALSE });
public BooleanEditor() {
combo.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> list,
Object value, int index, boolean isSelected, boolean cellHasFocus) {
Boolean boolValue = (Boolean) value;
String displayString = "";
if (boolValue == null) {
displayString = "";
} else if (boolValue) {
displayString = "T";
} else {
displayString = "F";
}
return super.getListCellRendererComponent(list, displayString,
index, isSelected, cellHasFocus);
}
});
}
@Override
public Object getCellEditorValue() {
return combo.getSelectedItem();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
if (value == null) {
combo.setSelectedIndex(-1);
} else {
combo.setSelectedItem((Boolean) value);
}
return combo;
}
}
我的整个SSCCE:
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class BoolColorTable {
@SuppressWarnings("serial")
private static void createAndShowGui() {
// null just to test how code will react to this situation
// that hopefully won't occur
Boolean[][] data = { null, { true }, { false }, { true }, { false },
{ false }, { true } };
String[] colNames = { "Data" };
DefaultTableModel model = new DefaultTableModel(data, colNames);
JTable table = new JTable(model) {
@Override
public Class<?> getColumnClass(int column) {
if (column == 0) {
return Boolean.class;
}
return super.getColumnClass(column);
}
};
table.setDefaultRenderer(Boolean.class, new BooleanRenderer());
table.setDefaultEditor(Boolean.class, new BooleanEditor());
JScrollPane mainPanel = new JScrollPane(table);
JFrame frame = new JFrame("BoolColorTable");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
@SuppressWarnings("serial")
class BooleanRenderer extends JLabel implements TableCellRenderer {
public BooleanRenderer() {
setOpaque(true);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Boolean boolValue = (Boolean) value;
if (boolValue == null) {
setBackground(null);
} else {
if (!boolValue) {
this.setBackground(Color.red);
} else {
this.setBackground(Color.BLACK);
}
}
return this;
}
}
@SuppressWarnings("serial")
class BooleanEditor extends AbstractCellEditor implements TableCellEditor {
JComboBox<Boolean> combo = new JComboBox<Boolean>(new Boolean[] {
Boolean.TRUE, Boolean.FALSE });
public BooleanEditor() {
combo.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> list,
Object value, int index, boolean isSelected, boolean cellHasFocus) {
Boolean boolValue = (Boolean) value;
String displayString = "";
if (boolValue == null) {
displayString = "";
} else if (boolValue) {
displayString = "T";
} else {
displayString = "F";
}
return super.getListCellRendererComponent(list, displayString,
index, isSelected, cellHasFocus);
}
});
}
@Override
public Object getCellEditorValue() {
return combo.getSelectedItem();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
if (value == null) {
combo.setSelectedIndex(-1);
} else {
combo.setSelectedItem((Boolean) value);
}
return combo;
}
}
修改强>
如果您绝对需要允许用户输入“T”或“F”,那么您可以通过向编辑器的JTextField添加DocumentFilter来实现这一点,并使其大部分都是白痴证明只有三个不区分大小写的文本字段条目:“t”,“f”或空。
例如:
@SuppressWarnings("serial")
class BooleanStringEditor extends AbstractCellEditor implements TableCellEditor {
private JTextField textField = new JTextField();
public BooleanStringEditor() {
PlainDocument doc = (PlainDocument) textField.getDocument();
doc.setDocumentFilter(new MyDocFilter());
}
@Override
public Object getCellEditorValue() {
if (textField.getText().equalsIgnoreCase("t")) {
return Boolean.TRUE;
} else if (textField.getText().equalsIgnoreCase("f")) {
return Boolean.FALSE;
}
// default if user messes up
return null;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
Boolean boolValue = (Boolean) value;
if (boolValue == null) {
textField.setText("");
} else if (boolValue) {
textField.setText("T");
} else {
textField.setText("F");
}
return textField;
}
}
class MyDocFilter extends DocumentFilter {
private boolean test(String text) {
if (text.isEmpty()) {
return true;
}
if (text.equalsIgnoreCase("t") || text.equalsIgnoreCase("f")) {
return true;
}
return false;
}
@Override
public void insertString(FilterBypass fb, int offset, String string,
AttributeSet attr) throws BadLocationException {
Document doc = fb.getDocument();
StringBuilder sb = new StringBuilder();
sb.append(doc.getText(0, doc.getLength()));
sb.insert(offset, string);
if (test(sb.toString())) {
super.insertString(fb, offset, string, attr);
} else {
// warn the user and don't allow the insert
}
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text,
AttributeSet attrs) throws BadLocationException {
Document doc = fb.getDocument();
StringBuilder sb = new StringBuilder();
sb.append(doc.getText(0, doc.getLength()));
sb.replace(offset, offset + length, text);
if (test(sb.toString())) {
super.replace(fb, offset, length, text, attrs);
} else {
// warn the user and don't allow the insert
}
}
@Override
public void remove(FilterBypass fb, int offset, int length)
throws BadLocationException {
Document doc = fb.getDocument();
StringBuilder sb = new StringBuilder();
sb.append(doc.getText(0, doc.getLength()));
sb.delete(offset, offset + length);
if (test(sb.toString())) {
super.remove(fb, offset, length);
} else {
// warn the user and don't allow the insert
}
}
}