Java 如何在JTable中设置CellEditor?
我想为Java 如何在JTable中设置CellEditor?,java,swing,jtable,tablecelleditor,Java,Swing,Jtable,Tablecelleditor,我想为JTable中的一个单元格设置CellEditor。它是一个单元格而不是all列,我在JDK中找不到名为cell的类 这个代码不能满足我的要求 table.getColumnModel().getColumn(columnIndex).setCellEditor(new DefaultCellEditor(new JComboBox)); 很简单。您只需要重写JTable的方法getCellRenderer。这里有一个例子 import java.awt.Component; imp
JTable
中的一个单元格设置CellEditor
。它是一个单元格而不是all列,我在JDK中找不到名为cell
的类
这个代码不能满足我的要求
table.getColumnModel().getColumn(columnIndex).setCellEditor(new DefaultCellEditor(new JComboBox));
很简单。您只需要重写
JTable
的方法getCellRenderer
。这里有一个例子
import java.awt.Component;
import java.awt.font.TextAttribute;
import java.util.Collections;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
@SuppressWarnings("unchecked")
public class TableRendererTest {
public static void main(String[] args) {
JFrame frm = new JFrame("Renderer test");
DefaultTableModel model = new DefaultTableModel(new String[] {"First", "Second", "Third" }, 3);
model.setValueAt("First row cell", 0, 1);
model.setValueAt("Striked out string", 1, 1);
model.setValueAt("Last row cell", 2, 1);
TableCellRenderer strikeOutRenderer = new StrikeOutRenderer();
// table with strike-out renderer (last cell is not stroked out)
// create a custom table with possibility to change renderer for a single cell.
JTable tbl = new JTable(model) {
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
if (row == 1 && column == 1) {
return strikeOutRenderer;
}
return super.getCellRenderer(row, column);
}
};
frm.add(new JScrollPane(tbl));
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private static class StrikeOutRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component res = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
res.setFont(res.getFont().deriveFont(Collections.singletonMap(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON)));
return res;
}
}
}
下面是完整解决方案的代码,因此您可以在任何地方使用该表,并可以为任何单元格定义渲染器
// defined in JCellStyleTable.java
public class JCellStyleTable extends JTable {
private final Map<Cell, TableCellRenderer> renderersMap = new HashMap<>();
private final Map<Cell, TableCellEditor> editorsMap = new HashMap<>();
public JCellStyleTable() {
super();
}
public JCellStyleTable(TableModel dm) {
super(dm);
}
public void putRenderer(Cell cell, TableCellRenderer renderer) {
renderersMap.put(Objects.requireNonNull(cell), renderer);
}
public TableCellRenderer getRenderer(Cell cell) {
return renderersMap.get(Objects.requireNonNull(cell));
}
public void putEditor(Cell cell, TableCellEditor editor) {
editorsMap.put(Objects.requireNonNull(cell), editor);
}
public TableCellEditor getEditor(Cell cell) {
return editorsMap.get(Objects.requireNonNull(cell));
}
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
TableCellRenderer result = renderersMap.get(new Cell(row, column));
return result == null ? super.getCellRenderer(row, column) : result;
}
@Override
public TableCellEditor getCellEditor(int row, int column) {
return editorsMap.get(new Cell(row, column)); // when null - no editing
}
}
// defined in CellBasedTableModel.java
public class CellBasedTableModel extends DefaultTableModel {
private Collection<Cell> editableCells = new HashSet<>();
public CellBasedTableModel() {
// TODO Auto-generated constructor stub
}
@Override
public boolean isCellEditable(int row, int column) {
return editableCells.contains(new Cell(row, column));
}
public void addEditableCell(Cell cell) {
editableCells.add(cell);
}
public void removeEditableCell(Cell cell) {
editableCells.remove(cell);
}
}
// defined in Cell.java
public class Cell {
private final int row, col;
public Cell(int row, int col) {
this.row = row;
this.col = col;
}
public int getRow() {
return row;
}
public int getCol() {
return col;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Cell) {
Cell another = (Cell) obj;
return another.col == col && another.row == row;
}
return false;
}
@Override
public int hashCode() {
return Arrays.hashCode(new int[] {row, col});
}
}
//在JCellStyleTable.java中定义
公共类JCellStyleTable扩展了JTable{
私有最终映射渲染器Map=newhashmap();
私有最终映射编辑器Map=newhashmap();
公共JCellStyleTable(){
超级();
}
公共JCellStyleTable(TableModel dm){
超级(dm);
}
公共单元格渲染器(单元格、TableCellRenderer渲染器){
RendersMap.put(Objects.requirennull(单元格),renderer);
}
公共TableCellRenderer getRenderer(单元格){
返回rendersmap.get(Objects.requirennull(单元格));
}
公共void编辑器(单元格、TableCellEditor编辑器){
editorsMap.put(Objects.requirennull(单元格),editor);
}
公共表格单元格编辑器getEditor(单元格){
返回editorsMap.get(Objects.requirennull(单元格));
}
@凌驾
公共TableCellRenderer getCellRenderer(int行,int列){
TableCellRenderer结果=rendersMap.get(新单元格(行、列));
返回结果==null?super.getCellRenderer(行、列):结果;
}
@凌驾
公共表CellEditor getCellEditor(int行,int列){
return editorsMap.get(新单元格(行、列));//为null时-无编辑
}
}
//在CellBasedTableModel.java中定义
公共类CellBasedTableModel扩展了DefaultTableModel{
私有集合editableCells=new HashSet();
public CellBasedTableModel(){
//TODO自动生成的构造函数存根
}
@凌驾
公共布尔值可编辑(int行,int列){
返回editableCells.contains(新单元格(行、列));
}
公共无效可添加单元格(单元格){
可编辑单元格。添加(单元格);
}
公共无效removeEditableCell(单元格){
可编辑单元格。删除(单元格);
}
}
//在Cell.java中定义
公共类单元{
私有最终整数行,col;
公共单元格(整数行,整数列){
this.row=行;
this.col=col;
}
public int getRow(){
返回行;
}
公共int getCol(){
返回列;
}
@凌驾
公共布尔等于(对象obj){
if(单元的obj实例){
另一个单元格=(单元格)obj;
返回other.col==col&&other.row==row;
}
返回false;
}
@凌驾
公共int hashCode(){
返回Arrays.hashCode(新的int[]{row,col});
}
}
这很简单。您只需要重写JTable
的方法getCellRenderer
。这里有一个例子
import java.awt.Component;
import java.awt.font.TextAttribute;
import java.util.Collections;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
@SuppressWarnings("unchecked")
public class TableRendererTest {
public static void main(String[] args) {
JFrame frm = new JFrame("Renderer test");
DefaultTableModel model = new DefaultTableModel(new String[] {"First", "Second", "Third" }, 3);
model.setValueAt("First row cell", 0, 1);
model.setValueAt("Striked out string", 1, 1);
model.setValueAt("Last row cell", 2, 1);
TableCellRenderer strikeOutRenderer = new StrikeOutRenderer();
// table with strike-out renderer (last cell is not stroked out)
// create a custom table with possibility to change renderer for a single cell.
JTable tbl = new JTable(model) {
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
if (row == 1 && column == 1) {
return strikeOutRenderer;
}
return super.getCellRenderer(row, column);
}
};
frm.add(new JScrollPane(tbl));
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private static class StrikeOutRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component res = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
res.setFont(res.getFont().deriveFont(Collections.singletonMap(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON)));
return res;
}
}
}
下面是完整解决方案的代码,因此您可以在任何地方使用该表,并可以为任何单元格定义渲染器
// defined in JCellStyleTable.java
public class JCellStyleTable extends JTable {
private final Map<Cell, TableCellRenderer> renderersMap = new HashMap<>();
private final Map<Cell, TableCellEditor> editorsMap = new HashMap<>();
public JCellStyleTable() {
super();
}
public JCellStyleTable(TableModel dm) {
super(dm);
}
public void putRenderer(Cell cell, TableCellRenderer renderer) {
renderersMap.put(Objects.requireNonNull(cell), renderer);
}
public TableCellRenderer getRenderer(Cell cell) {
return renderersMap.get(Objects.requireNonNull(cell));
}
public void putEditor(Cell cell, TableCellEditor editor) {
editorsMap.put(Objects.requireNonNull(cell), editor);
}
public TableCellEditor getEditor(Cell cell) {
return editorsMap.get(Objects.requireNonNull(cell));
}
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
TableCellRenderer result = renderersMap.get(new Cell(row, column));
return result == null ? super.getCellRenderer(row, column) : result;
}
@Override
public TableCellEditor getCellEditor(int row, int column) {
return editorsMap.get(new Cell(row, column)); // when null - no editing
}
}
// defined in CellBasedTableModel.java
public class CellBasedTableModel extends DefaultTableModel {
private Collection<Cell> editableCells = new HashSet<>();
public CellBasedTableModel() {
// TODO Auto-generated constructor stub
}
@Override
public boolean isCellEditable(int row, int column) {
return editableCells.contains(new Cell(row, column));
}
public void addEditableCell(Cell cell) {
editableCells.add(cell);
}
public void removeEditableCell(Cell cell) {
editableCells.remove(cell);
}
}
// defined in Cell.java
public class Cell {
private final int row, col;
public Cell(int row, int col) {
this.row = row;
this.col = col;
}
public int getRow() {
return row;
}
public int getCol() {
return col;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Cell) {
Cell another = (Cell) obj;
return another.col == col && another.row == row;
}
return false;
}
@Override
public int hashCode() {
return Arrays.hashCode(new int[] {row, col});
}
}
//在JCellStyleTable.java中定义
公共类JCellStyleTable扩展了JTable{
私有最终映射渲染器Map=newhashmap();
私有最终映射编辑器Map=newhashmap();
公共JCellStyleTable(){
超级();
}
公共JCellStyleTable(TableModel dm){
超级(dm);
}
公共单元格渲染器(单元格、TableCellRenderer渲染器){
RendersMap.put(Objects.requirennull(单元格),renderer);
}
公共TableCellRenderer getRenderer(单元格){
返回rendersmap.get(Objects.requirennull(单元格));
}
公共void编辑器(单元格、TableCellEditor编辑器){
editorsMap.put(Objects.requirennull(单元格),editor);
}
公共表格单元格编辑器getEditor(单元格){
返回editorsMap.get(Objects.requirennull(单元格));
}
@凌驾
公共TableCellRenderer getCellRenderer(int行,int列){
TableCellRenderer结果=rendersMap.get(新单元格(行、列));
返回结果==null?super.getCellRenderer(行、列):结果;
}
@凌驾
公共表CellEditor getCellEditor(int行,int列){
return editorsMap.get(新单元格(行、列));//为null时-无编辑
}
}
//在CellBasedTableModel.java中定义
公共类CellBasedTableModel扩展了DefaultTableModel{
私有集合editableCells=new HashSet();
public CellBasedTableModel(){
//TODO自动生成的构造函数存根
}
@凌驾
公共布尔值可编辑(int行,int列){
返回editableCells.contains(新单元格(行、列));
}
公共无效可添加单元格(单元格){
可编辑单元格。添加(单元格);
}
公共无效removeEditableCell(单元格){
可编辑单元格。删除(单元格);
}
}
//在Cell.java中定义
公共类单元{
私有最终整数行,col;
公共单元格(整数行,整数列){
this.row=行;
this.col=col;
}
public int getRow(){
返回行;
}
公共int getCol(){
返回列;
}
@凌驾
公共布尔等于(对象obj){
if(单元的obj实例){
另一个单元格=(单元格)obj;
返回other.col==col&&other.row==row;
}
返回false;
}
@凌驾
公共int hashCode(){
返回Arrays.hashCode(新的int[]{row,col});
}
}
um…谢谢您的帮助,可能我的表达式不正确,我的需求,例如,当我单击单元格(1,1)时,JTable将在该单元格上弹出一个JcomboBox组件,当我单击单元格(n,1)时,JTable将不弹出任何内容,n表示其他行number@huyangqing这很容易。您可以覆盖JTable
中的方法getCellEditor(int行,int列)
。我已经为你修改了第二个例子