我想实现一个用作选项列表的组件,用户可以选择是否选择
在视觉上我认为它最好在UI中呈现(如果有更好的方法,请告诉我)如下:
无论如何,我认为这可以通过JTable
(单列)并使用JCheckBox
作为单元格编辑器来实现。
我尝试了但是没有用。
代码示例:
public class ListRenderer extends JFrame {
JCheckBox checkbox = new JCheckBox("Test");
DefaultCellEditor dce1 = new DefaultCellEditor(checkbox);
public ListRenderer(){
Object[][] data = { {"Test"} };
String[] columnNames = {"Options"};
DefaultTableModel model = new DefaultTableModel(data,columnNames);
JTable table = new JTable(model){
public TableCellEditor getCellEditor(int row, int column)
{
return dce1;
}
};
JScrollPane scrollPane = new JScrollPane( table );
getContentPane().add( scrollPane );
}
当框架出现时,我看到表格中的“测试”,但它看起来不像一个复选框(如示例图片中所示)。
如果我单击单元格,它会变成一个复选框(左侧单击按钮而不是右侧),但文本更改为显示 true 或 false !它没有继续显示“测试”
更多文字取决于我是否继续按下牢房
如果我将JCheckBox
更改为JComboBox
,就我所知,行为是正确的
任何人都可以告诉我,我在这里做错了什么?
谢谢!
答案 0 :(得分:2)
要按default呈现为JCheckBox
,表格的模型必须返回Boolean.class
作为该列的类型。如果您使用的是DefaultTableModel
,则必须相应地覆盖getColumnClass()
。这是一个相关的example。
附录:请注意example编辑的ValueRenderer
私有实例可以直接应用ItemEvent
,而不是setValueAt()
。
附录:example已更新,以反映正确的模型 - 视图工作流程。
无论如何,
setValueAt()
被召唤。通过调试验证
如果您进入setValueAt()
,您会看到“此空实现已提供,因此如果用户的数据模型不可编辑,则不必实施此方法。”
答案 1 :(得分:2)
在这里你可以找到答案为什么(JButtons JComponents)JCheckBox和JRadioButton ...在TableCell中作为另一个JComponents渲染有点不同(你必须使用JTable行选择,因为我改变了Opacity)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class CheckboxInCellTest {
private String[] columnNames = {"Boolean(Default)", "Boolean"};
private Object[][] data = {{false, true}, {true, false}, {false, true}};
private DefaultTableModel model = new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public Class<?> getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
};
public JComponent makeUI() {
JTable table = new JTable(model);
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
JTable t = (JTable) e.getComponent();
Point pt = e.getPoint();
int row = t.rowAtPoint(pt), col = t.columnAtPoint(pt);
if (t.convertColumnIndexToModel(col) == 1) {
t.getCellEditor(row, col).stopCellEditing();
}
}
});
table.setRowHeight(20);
CheckBoxEditorRenderer1 cer = new CheckBoxEditorRenderer1();
table.getColumnModel().getColumn(1).setCellRenderer(cer);
table.getColumnModel().getColumn(1).setCellEditor(cer);
JPanel p = new JPanel(new BorderLayout());
p.add(new JScrollPane(table));
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new CheckboxInCellTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class CheckBoxPanel1 extends JPanel {
private static final long serialVersionUID = 1L;
public final JCheckBox button = new JCheckBox();
CheckBoxPanel1() {
super(new GridBagLayout());
add(button);
button.setOpaque(false);
setOpaque(false);
}
}
class CheckBoxEditorRenderer1 extends AbstractCellEditor implements TableCellRenderer, TableCellEditor {
private static final long serialVersionUID = 1L;
private final CheckBoxPanel1 editor = new CheckBoxPanel1();
private final CheckBoxPanel1 renderer = new CheckBoxPanel1();
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean is, boolean hf, int row, int column) {
renderer.button.setSelected(Boolean.TRUE.equals(value));
renderer.button.setOpaque(is);
return renderer;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
editor.button.setSelected(Boolean.TRUE.equals(value));
renderer.button.setOpaque(isSelected);
return editor;
}
@Override
public Object getCellEditorValue() {
return editor.button.isSelected();
}
}
和TableCell中的JButton ...与Nimbus L&amp; F(需要Java&gt; 1.6.17 ???现在我有xxx.25)
import com.sun.java.swing.Painter;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.util.LinkedList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import sun.swing.table.DefaultTableCellHeaderRenderer;
public class TableButtonTest extends JFrame {
private static final long serialVersionUID = 1L;
public TableButtonTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTable table = new JTable(new TestModel());
table.getTableHeader().setReorderingAllowed(false);
table.setRowHeight(20);
table.getColumnModel().getColumn(1).setPreferredWidth(3);
table.getColumnModel().getColumn(2).setPreferredWidth(3);
table.getTableHeader().setDefaultRenderer(new WrappingRenderer(table.getTableHeader()));
this.add(new JScrollPane(table));
Action increase = new AbstractAction("+") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
JTable table = (JTable) e.getSource();
int row = Integer.valueOf(e.getActionCommand());
TestModel model = (TestModel) table.getModel();
model.increment(row, 0);
//model.fireTableCellUpdated(row, 0);
}
};
ButtonColumn inc = new ButtonColumn(table, increase, 1);
Action decrease = new AbstractAction("-") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
JTable table = (JTable) e.getSource();
int row = Integer.valueOf(e.getActionCommand());
TestModel model = (TestModel) table.getModel();
model.decrement(row, 0);
}
};
ButtonColumn dec = new ButtonColumn(table, decrease, 2);
JTableHeader tbh = table.getTableHeader();
tbh.setOpaque(false);
Painter painter = new com.sun.java.swing.Painter() {
public void paint(Graphics2D g, Object o, int w, int h) {
}
};
javax.swing.UIDefaults defaults = new javax.swing.UIDefaults();
defaults.put("TableHeader:\"TableHeader.renderer\"[Pressed].backgroundPainter", painter);
defaults.put("TableHeader:\"TableHeader.renderer\"[Pressed].backgroundPainter",
defaults.get(("TableHeader:\"TableHeader.renderer\"[Pressed].backgroundPainter")));
tbh.putClientProperty("Nimbus.Overrides", defaults);
tbh.putClientProperty("Nimbus.State", "Pressed");
tbh.putClientProperty("JTree.lineStyle", "Angled");
setLocation(200, 200);
pack();
}
private static class WrappingRenderer implements TableCellRenderer {
private DefaultTableCellHeaderRenderer delegate;
private JTableHeader header;
public WrappingRenderer(JTableHeader header) {
this.header = header;
this.delegate = (DefaultTableCellHeaderRenderer) header.getDefaultRenderer();
header.setDefaultRenderer(this);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component comp = delegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
TableColumn draggedColumn = table.getTableHeader().getDraggedColumn();
if (isSelected) {
comp.setBackground(table.getSelectionBackground());
} else {
comp.setBackground(table.getBackground());
}
if (draggedColumn != null) {
if (table.convertColumnIndexToModel(column) == draggedColumn.getModelIndex()) {
setNimbusState("Pressed");
} else {
setNimbusState(null);
}
} else {
setNimbusState(null);
}
// do similar for resizing column
return comp;
}
public void setNimbusState(String state) {
delegate.putClientProperty("Nimbus.State", state);
}
}
public static void main(String[] args) {
try {
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if (info.getName().equals("Nimbus")) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e1) {
e1.printStackTrace();
}
new TableButtonTest().setVisible(true);
}
}
class TestModel extends AbstractTableModel {
private static final long serialVersionUID = 1L;
private List<TestRecord> records = new LinkedList<TestRecord>();
private static class TestRecord {
private int val = 0;
}
public void increment(int row, int col) {
records.get(row).val++;
fireTableCellUpdated(row, col);
}
public void decrement(int row, int col) {
records.get(row).val--;
fireTableCellUpdated(row, col);
}
public TestModel() {
records.add(new TestRecord());
records.add(new TestRecord());
}
@Override
public Class<?> getColumnClass(int col) {
switch (col) {
case 0:
return Integer.class;
case 1:
return ButtonColumn.class;
case 2:
return Boolean.class;
default:
return String.class;
}
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
@Override
public int getColumnCount() {
return 3;
}
@Override
public int getRowCount() {
return records.size();
}
@Override
public Object getValueAt(int row, int col) {
if (col == 0) {
return records.get(row).val;
} else if (col == 1) {
return "+";
} else {
return "-";
}
}
}