我正在渲染一个带有图像的JButton,基本上是为了模拟JCheckBox的行为。为什么我不让JTable渲染JCheckbox?仅仅因为我需要更大的复选框,我无法调整它们的大小(据我所知)。
所以,我有自己的表格单元格渲染器和编辑器。两者都呈现JButton和它们上面的复选框图像。我想要做的是将图像从选中的图像更改为未检查的图像(反之亦然)并更新单元格值(布尔值true或false)。但是,由于某种原因,getCellEditorValue()不会更新我的表。因此,只要我发布鼠标,它们的值就会回到原来的状态。
任何帮助将不胜感激!非常感谢!
public class TableExample extends JFrame {
JScrollPane pane;
JPanel panel;
JTable table;
Object[][] data;
MyTableModel tm;
Renderer buttonColumn;
public TableExample(Object[][] data) throws IOException {
String[] columns = {"Column#1", "Column#2", "Column#3", "Column#4", "Column#5", "Column#6"};
this.data = data;
this.setPreferredSize(new Dimension(700, 500));
this.setMinimumSize(new Dimension(700, 500));
this.setMaximumSize(new Dimension(700, 500));
tm = new MyTableModel(this.data, columns);
this.table = new JTable(tm);
this.table.setRowHeight(50);
table.setDefaultRenderer(Boolean.class, new Renderer(this, table, 5));
table.setDefaultEditor(Boolean.class, new Editor(this, table, 5));
this.pane = new JScrollPane(this.table);
this.add(this.pane);
}
/**
*
* TABLE MODEL
*/
public class MyTableModel extends AbstractTableModel {
private Object[][] data;
private String[] columns;
public MyTableModel(Object[][] data, String[] columns) {
this.data = data;
this.columns = columns;
}
public void setColumns(String[] columns1) {
this.columns = columns1;
}
@Override
public int getRowCount() {
return this.data.length;
}
@Override
public int getColumnCount() {
return this.columns.length;
}
@Override
public String getColumnName(int columnIndex) {
return columns[columnIndex];
}
@Override
public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
public void setValueAt(String value, int row, int col) {
if (DEBUG) {
System.out.println("Setting value at " + row + "," + col
+ " to " + value
+ " (an instance of "
+ value.getClass() + ")");
}
data[row][col] = value;
fireTableCellUpdated(row, col);
if (DEBUG) {
System.out.println("New value of data:");
printDebugData();
}
}
private void printDebugData() {
int numRows = getRowCount();
int numCols = getColumnCount();
for (int i = 0; i < numRows; i++) {
System.out.print(" row " + i + ":");
for (int j = 0; j < numCols; j++) {
System.out.print(" " + data[i][j]);
}
System.out.println();
}
System.out.println("--------------------------");
}
}
/**
*
* CELL RENDERER
*/
private class Renderer extends JButton implements TableCellRenderer {
ImageIcon check;
ImageIcon uncheck;
boolean isChecked;
public Renderer(JFrame frame, JTable table, int column) throws IOException {
Image checkI = ImageIO.read(getClass().getResource("ukbuttonblue.png"));
Image unCheckI = ImageIO.read(getClass().getResource("ukbuttonrev.png"));
this.setBorderPainted(false);
check = new ImageIcon(checkI);
uncheck = new ImageIcon(unCheckI);
}
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
this.isChecked = (boolean) value;
if (isChecked) {
setIcon(check);
} else {
setIcon(uncheck);
}
return this;
}
}
/**
*
* CELL EDITOR
*/
private class Editor extends AbstractCellEditor implements TableCellEditor, ActionListener {
private JButton editButton;
ImageIcon check;
ImageIcon uncheck;
boolean isChecked;
public Editor(JFrame frame, JTable table, int column) throws IOException {
editButton = new JButton();
editButton.addActionListener(this);
editButton.setBorderPainted(false);
Image checkI = ImageIO.read(getClass().getResource("check.png"));
Image unCheckI = ImageIO.read(getClass().getResource("uncheck.png"));
check = new ImageIcon(checkI);
uncheck = new ImageIcon(unCheckI);
}
@Override
public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
this.isChecked = (boolean) value;
if (this.isChecked) {
editButton.setIcon(uncheck);
} else {
editButton.setIcon(check);
}
System.out.println("Edit " + isChecked);
return editButton;
}
@Override
public Object getCellEditorValue() {
System.out.println("giden " + isChecked);
return this.isChecked;
}
@Override
public void actionPerformed(ActionEvent e) {
if (this.isChecked) {
this.isChecked = false;
} else {
this.isChecked = true;
}
fireEditingStopped();
}
}
public static void main(String[] args) throws IOException {
Object[][] data = {
{"1", "Allan", "Smith", false, true, false},
{"2", "Jerry", "Tucker", true, false, true}
};
TableExample app = new TableExample(data);
app.setVisible(true);
}
}
答案 0 :(得分:0)
经过一段时间的努力后,我意识到myTableModel的isCellEditable方法无法正常工作。我只是切换到DetafultTableModel重写get列类。
@Override
public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
使用DefaultTableModel的一个问题是布尔类会自动呈现给常规JCheckBoxes。因此,我使用Integer类来代替使用布尔类,只使用0和1来模拟true和false。
这是使用按钮和图像模拟JTable中JCheckBox行为的最终程序。这为渲染不同的图像提供了极大的灵活性,并且仍然可以获得JCheckBox行为。所以,享受!
public class TableExample extends JFrame {
JScrollPane pane;
JPanel panel;
JTable table;
Object[][] data;
DefaultTableModel tm;
Renderer buttonColumn;
public TableExample(Object[][] data) throws IOException {
String[] columns = {"Column#1", "Column#2", "Column#3", "Column#4", "Column#5", "Column#6"};
this.data = data;
this.setPreferredSize(new Dimension(700, 500));
this.setMinimumSize(new Dimension(700, 500));
this.setMaximumSize(new Dimension(700, 500));
//tm = new DefaultTableModel(this.data, columns);
DefaultTableModel tm = new DefaultTableModel(this.data, columns) {
@Override
public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
};
this.table = new JTable(tm);
this.table.setRowHeight(50);
table.setDefaultRenderer(Integer.class, new Renderer(this, table, 5));
table.setDefaultEditor(Integer.class, new Editor(this, table, 5));
this.pane = new JScrollPane(this.table);
this.add(this.pane);
}
/**
*
* RENDERER
*/
private class Renderer extends JButton implements TableCellRenderer {
ImageIcon check;
ImageIcon uncheck;
int isChecked;
public Renderer(JFrame frame, JTable table, int column) throws IOException {
Image checkI = ImageIO.read(getClass().getResource("check.png"));
Image unCheckI = ImageIO.read(getClass().getResource("uncheck.png"));
this.setBorderPainted(false);
check = new ImageIcon(checkI);
uncheck = new ImageIcon(unCheckI);
}
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
this.isChecked = (int) value;
if (isChecked == 1) {
setIcon(check);
} else {
setIcon(uncheck);
}
return this;
}
}
/**
*
* EDITOR
*/
private class Editor extends AbstractCellEditor implements TableCellEditor, ActionListener {
private JButton editButton;
ImageIcon check;
ImageIcon uncheck;
int isChecked;
public Editor(JFrame frame, JTable table, int column) throws IOException {
editButton = new JButton();
editButton.addActionListener(this);
editButton.setBorderPainted(false);
Image checkI = ImageIO.read(getClass().getResource("check.png"));
Image unCheckI = ImageIO.read(getClass().getResource("uncheck.png"));
check = new ImageIcon(checkI);
uncheck = new ImageIcon(unCheckI);
}
@Override
public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
this.isChecked = (int) value;
if (this.isChecked == 1) {
editButton.setIcon(uncheck);
this.isChecked = 0;
} else {
editButton.setIcon(check);
this.isChecked = 1;
}
return editButton;
}
@Override
public Object getCellEditorValue() {
return this.isChecked;
}
@Override
public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
public void updateValue() {
}
}
public static void main(String[] args) throws IOException {
Object[][] data = {
{"1", "Allan", "Smith", false, false, 0},
{"2", "Jerry", "Tucker", true, true, 1}
};
TableExample app = new TableExample(data);
app.setVisible(true);
}
}