Java 如何使JTable单元格中的JButton可单击?
我有一个带有自定义单元格渲染器的JTable。该单元格是一个JPanel,包含一个JTextField和一个JButton。JTextField包含一个整数,当用户单击JButton时,整数应该增加 问题是当JTable单元格中有JButton时,无法单击它。我怎样才能使它可以点击 以下是我的测试代码:Java 如何使JTable单元格中的JButton可单击?,java,swing,jtable,Java,Swing,Jtable,我有一个带有自定义单元格渲染器的JTable。该单元格是一个JPanel,包含一个JTextField和一个JButton。JTextField包含一个整数,当用户单击JButton时,整数应该增加 问题是当JTable单元格中有JButton时,无法单击它。我怎样才能使它可以点击 以下是我的测试代码: public class ActiveTable extends JFrame { public ActiveTable() { RecordModel model
public class ActiveTable extends JFrame {
public ActiveTable() {
RecordModel model = new RecordModel();
model.addRecord(new Record());
JTable table = new JTable(model);
EditorAndRenderer editorAndRenderer = new EditorAndRenderer();
table.setDefaultRenderer(Object.class, editorAndRenderer);
table.setDefaultEditor(Object.class, editorAndRenderer);
table.setRowHeight(38);
add(new JScrollPane(table));
setPreferredSize(new Dimension(600, 400));
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Active Table");
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ActiveTable();
}
});
}
class RecordModel extends AbstractTableModel {
private final List<Record> records = new ArrayList<Record>();
@Override
public int getColumnCount() {
return 1;
}
@Override
public int getRowCount() {
return records.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return records.get(rowIndex);
}
public void addRecord(Record r) {
records.add(r);
fireTableRowsInserted(records.size()-1, records.size()-1);
}
}
class Record {
private int count = 1;
public int getCount() { return count; }
public void increase() { count = count + 1; }
}
class CellPanel extends JPanel {
private Record record;
private final JTextField field = new JTextField(8);
private final Action increaseAction = new AbstractAction("+") {
public void actionPerformed(ActionEvent e) {
record.increase();
field.setText(record.getCount()+"");
JTable table = (JTable) SwingUtilities.getAncestorOfClass(JTable.class, (Component) e.getSource());
table.getCellEditor().stopCellEditing();
}
};
private final JButton button = new JButton(increaseAction);
public CellPanel() {
add(field);
add(button);
}
public void setRecord(Record r) {
record = r;
field.setText(record.getCount()+"");
}
public Record getRecord() {
return record;
}
}
class EditorAndRenderer extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private final CellPanel renderer = new CellPanel();
private final CellPanel editor = new CellPanel();
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
renderer.setRecord((Record) value);
return renderer;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
editor.setRecord((Record) value);
return editor;
}
@Override
public Object getCellEditorValue() {
return editor.getRecord();
}
@Override
public boolean isCellEditable(EventObject ev) {
return true;
}
@Override
public boolean shouldSelectCell(EventObject ev) {
return false;
}
}
}
公共类ActiveTable扩展了JFrame{
公共活动表(){
RecordModel model=新的RecordModel();
model.addRecord(新记录());
JTable table=新的JTable(模型);
EditorAndRenderer EditorAndRenderer=新的EditorAndRenderer();
table.setDefaultRenderer(Object.class、editorAndRenderer);
table.setDefaultEditor(Object.class、editorAndRenderer);
表3.设置行高(38);
添加(新JScrollPane(表));
setPreferredSize(新尺寸(600400));
包装();
setDefaultCloseOperation(关闭时退出);
setTitle(“活动表”);
setVisible(真);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
新ActiveTable();
}
});
}
类RecordModel扩展了AbstractTableModel{
私有最终列表记录=新ArrayList();
@凌驾
public int getColumnCount(){
返回1;
}
@凌驾
public int getRowCount(){
返回记录。大小();
}
@凌驾
公共对象getValueAt(int行索引、int列索引){
返回记录。获取(行索引);
}
公共无效添加记录(记录r){
记录。添加(r);
fireTableRowsInserted(records.size()-1,records.size()-1);
}
}
课堂记录{
私有整数计数=1;
public int getCount(){return count;}
public void increase(){count=count+1;}
}
类CellPanel扩展了JPanel{
私人记录;
私有最终JTextField=新JTextField(8);
私有最终操作递增操作=新抽象操作(“+”){
已执行的公共无效操作(操作事件e){
记录。增加();
field.setText(record.getCount()+);
JTable table=(JTable)SwingUtilities.getAncestorOfClass(JTable.class,(Component)e.getSource());
table.getCellEditor().stopCellEditing();
}
};
私有最终JButton按钮=新JButton(递增操作);
公共小组委员会(){
添加(字段);
添加(按钮);
}
公共无效设置记录(记录r){
记录=r;
field.setText(record.getCount()+);
}
公共记录getRecord(){
返回记录;
}
}
类EditorAndRenderer扩展AbstractCellEditor实现TableCellEditor、TableCellRenderer{
私有最终CellPanel渲染器=新建CellPanel();
私有最终CellPanel编辑器=新建CellPanel();
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、,
布尔值(已选择,布尔值为焦点,整数行,整数列){
renderer.setRecord((记录)值);
返回渲染器;
}
@凌驾
公共组件getTableCellEditorComponent(JTable表、对象值、,
布尔值(选定,int行,int列){
editor.setRecord((记录)值);
返回编辑器;
}
@凌驾
公共对象getCellEditorValue(){
返回editor.getRecord();
}
@凌驾
公共布尔值isCellEditable(EventObject ev){
返回true;
}
@凌驾
公共布尔值shouldSelectCell(EventObject ev){
返回false;
}
}
}
渲染器只是用于绘制单元格的显示器。您需要一个允许您进行更改的编辑器组件
看看:
这里有一种使用方法
公共类TableTest扩展JFrame{
公共表格测试(){
此.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTable table=newjtable(newtestmodel());
table.getColumnModel().getColumn(1).setPreferredWidth(3);
table.getColumnModel().getColumn(2).setPreferredWidth(3);
添加(新的JScrollPane(表));
动作增加=新的抽象动作(“+”){
@凌驾
已执行的公共无效操作(操作事件e){
JTable table=(JTable)e.getSource();
int row=Integer.valueOf(例如getActionCommand());
TestModel=(TestModel)table.getModel();
模型.增量(行,0);
}
};
ButtonColumn inc=新的ButtonColumn(表,增加,1);
动作减少=新的抽象动作(“-”){
@凌驾
已执行的公共无效操作(操作事件e){
JTable table=(JTable)e.getSource();
int row=Integer.valueOf(例如getActionCommand());
TestModel=(TestModel)table.getModel();
模型。减量(行,0);
}
};
ButtonColumn dec=新的ButtonColumn(表,减少,2);
包装();
}
公共静态void main(字符串[]args){
新建TableTest().setVisible(true);
}
}
类TestModel扩展了AbstractTableModel{
列表记录=新建LinkedList();
私有静态类TestRecord{
私有int val=0;
}
公共无效增量(整数行、整数列){
records.get(row).val++;
fireTableCellUpdated(第0行);
}
公共无效递减率(整数行,整数列){
记录.get(row).val--;
fireTableCellUpdated(第0行);
}
公共测试模型
public class TableTest extends JFrame {
public TableTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTable table = new JTable(new TestModel());
table.getColumnModel().getColumn(1).setPreferredWidth(3);
table.getColumnModel().getColumn(2).setPreferredWidth(3);
this.add(new JScrollPane(table));
Action increase = new AbstractAction("+") {
@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);
}
};
ButtonColumn inc = new ButtonColumn(table, increase, 1);
Action decrease = new AbstractAction("-") {
@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);
pack();
}
public static void main(String[] args) {
new TableTest().setVisible(true);
}
}
class TestModel extends AbstractTableModel {
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, 0);
}
public void decrement(int row, int col) {
records.get(row).val--;
fireTableCellUpdated(row, 0);
}
public TestModel() {
records.add(new TestRecord());
records.add(new TestRecord());
}
@Override
public Class<?> getColumnClass(int col) {
if (col == 0) {
return Integer.class;
} else {
return ButtonColumn.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 "-";
}
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}