Java JTable值更改时更改整个列的颜色-Swing
我在这里花了很长时间试图找到我问题的答案,但没有得到我预期的确切结果 我有一个JTable,每当我改变整列中的值时(每次只改变一列中的值)。 我想监听一个表的变化,当列中的数据发生变化时,列中的颜色也将发生变化,所有其他列都将使用默认颜色 以下是表侦听器的代码:Java JTable值更改时更改整个列的颜色-Swing,java,swing,jtable,tablecellrenderer,Java,Swing,Jtable,Tablecellrenderer,我在这里花了很长时间试图找到我问题的答案,但没有得到我预期的确切结果 我有一个JTable,每当我改变整列中的值时(每次只改变一列中的值)。 我想监听一个表的变化,当列中的数据发生变化时,列中的颜色也将发生变化,所有其他列都将使用默认颜色 以下是表侦听器的代码: Class CustomCellRenderer extends DefaultTableCellRenderer { public Component getTableCellRendererComponent(JTable
Class CustomCellRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component rendererComp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
table.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
if(***here i want to know which column changed or something like that***){
rendererComp.setBackground(Color.CYAN);
}
}
});
return rendererComp ;
}
}
这是创建表的代码:
private void createTable() {
tablePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
DefaultTableModel tableModel = new DefaultTableModel(){
@Override
public boolean isCellEditable(int row, int column) {
//all cells false
return false;
}
};
contentTable = new JTable(tableModel);
contentTable.setGridColor(Color.LIGHT_GRAY);
for(int i=0; i<columnSize; i++) {
tableModel.addColumn("0");
}
for(int i=0; i<rawSize; i++) {
tableModel.addRow(new Object[] { "" });
}
for(int i=0; i<rawSize; i++) {
for(int j=0; j<tableModel.getRowCount(); j++) {
tableModel.setValueAt("0", j, i);
}
}
for(int i=0; i<ramSize; i++) {
contentTable.getColumnModel().getColumn(i).setCellRenderer(new CustomCellRenderer());
}
JScrollPane scrollPane = new JScrollPane(contentTable);
scrollPane.setPreferredSize(new Dimension(400, 150));
tablePanel.add(scrollPane);
}
private void createTable(){
tablePanel.setLayout(新的FlowLayout(FlowLayout.LEFT));
DefaultTableModel tableModel=新的DefaultTableModel(){
@凌驾
公共布尔值可编辑(int行,int列){
//所有单元格均为假
返回false;
}
};
contentTable=新的JTable(tableModel);
contentTable.setGridColor(颜色:浅灰色);
对于(int i=0;i将所需状态存储在TableModel
中;让TableCellRenderer
使用状态相应地调整视图。在下面的示例中,只要setValueAt()
更新任何单元格,edited
标记为true
。应用于第0列的呈现会相应地更改显示。请注意clearEdited()
如何调用fireTableDataChanged()
以强制在清除处理程序中调用该表时呈现所有单元格
附录:下面的更新显示了一种独立处理多个列的方法。CustomModel
现在包含一个Map
来存储应用了CustomRenderer
的每个列的编辑状态。CustomRenderer
现在调用convertColumnIndexToModel()
并正确设置选择颜色
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Component;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.event.ActionEvent;
导入java.util.HashMap;
导入java.util.Map;
导入javax.swing.AbstractAction;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.table.DefaultTableCellRenderer;
导入javax.swing.table.DefaultTableModel;
/**
*@见http://stackoverflow.com/a/37439731/230513
*/
公开课考试{
专用void display(){
JFrame f=新JFrame(“测试”);
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CustomModel model=新CustomModel();
setColumnIdentifiers(新字符串[]{“A”,“B”});
对于(int i=0;i<16;i++){
addRow(新字符串[]{“A:+i”,B:+i});
}
JTable表格=新JTable(型号){
@凌驾
公共维度getPreferredScrollableViewportSize(){
返回新维度(100,getRowHeight()*getRowCount()/2);
}
};
table.getColumnModel().getColumn(0).setCellRenderer(新的CustomRenderer(模型));
table.getColumnModel().getColumn(1).setCellRenderer(新的CustomRenderer(模型));
f、 添加(新JScrollPane(表));
JPanel p=新的JPanel();
p、 添加(newjbutton(newupdateaction(“updatea”,model,0));
p、 添加(新的JButton(新的UpdateAction(“更新B”,model,1));
p、 添加(新JButton(新抽象操作(“清除”){
@凌驾
已执行的公共无效操作(操作事件e){
模型.clearEdited(0);
模型1;
}
}));
f、 添加(p,边界布局。南部);
f、 包装();
f、 setLocationRelativeTo(空);
f、 setVisible(真);
}
私有静态类CustomModel扩展了DefaultTableModel{
已编辑的私有最终映射=新HashMap();
公共布尔值已编辑(int列){
return edited.get(column)!=null&&edited.get(column);
}
公共无效清除编辑(int列){
编辑。放置(列,假);
fireTableDataChanged();
}
@凌驾
公共布尔值可编辑(int行,int列){
返回false;
}
@凌驾
public void setValueAt(对象有效、整行、整列){
super.setValueAt(aValue、row、column);
编辑。放置(列,真);
}
}
私有静态类CustomRenderer扩展了DefaultTableCellRenderer{
私有最终定制模型;
公共CustomRenderer(CustomModel模型){
this.model=模型;
}
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、,
布尔值(已选择,布尔值为焦点,整数行,整数列){
组件c=super.getTableCellRenderComponent(
表、值、isSelected、hasFocus、行、列);
if(model.isEdited(table.convertColumnIndexToModel(col))){
c、 挫折背景(颜色:青色);
}否则,如果(当选){
c、 挫折背景(table.getSelectionBackground());
}否则{
c、 挫折背景(table.getBackground());
}
返回c;
}
}
私有静态类UpdateAction扩展了AbstractAction{
私有最终定制模型;
私有的最后一个int列;
公共更新操作(字符串名称、CustomModel模型、int列){
超级(姓名);
this.model=模型;
this.column=列;
}
@凌驾
已执行的公共无效操作(操作事件e){
对于(int i=0;iimport java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
/**
* @see http://stackoverflow.com/a/37439731/230513
*/
public class Test {
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CustomModel model = new CustomModel();
model.setColumnIdentifiers(new String[]{"A", "B"});
for (int i = 0; i < 16; i++) {
model.addRow(new String[]{"A:" + i, "B:" + i});
}
JTable table = new JTable(model) {
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(100, getRowHeight() * getRowCount() / 2);
}
};
table.getColumnModel().getColumn(0).setCellRenderer(new CustomRenderer(model));
table.getColumnModel().getColumn(1).setCellRenderer(new CustomRenderer(model));
f.add(new JScrollPane(table));
JPanel p = new JPanel();
p.add(new JButton(new UpdateAction("Update A", model, 0)));
p.add(new JButton(new UpdateAction("Update B", model, 1)));
p.add(new JButton(new AbstractAction("Clear") {
@Override
public void actionPerformed(ActionEvent e) {
model.clearEdited(0);
model.clearEdited(1);
}
}));
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class CustomModel extends DefaultTableModel {
private final Map<Integer, Boolean> edited = new HashMap<>();
public boolean isEdited(int column) {
return edited.get(column) != null && edited.get(column);
}
public void clearEdited(int column) {
edited.put(column, false);
fireTableDataChanged();
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
@Override
public void setValueAt(Object aValue, int row, int column) {
super.setValueAt(aValue, row, column);
edited.put(column, true);
}
}
private static class CustomRenderer extends DefaultTableCellRenderer {
private final CustomModel model;
public CustomRenderer(CustomModel model) {
this.model = model;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int col) {
Component c = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, col);
if (model.isEdited(table.convertColumnIndexToModel(col))) {
c.setBackground(Color.cyan);
} else if (isSelected) {
c.setBackground(table.getSelectionBackground());
} else {
c.setBackground(table.getBackground());
}
return c;
}
}
private static class UpdateAction extends AbstractAction {
private final CustomModel model;
private final int column;
public UpdateAction(String name, CustomModel model, int column) {
super(name);
this.model = model;
this.column = column;
}
@Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < model.getRowCount(); i++) {
model.setValueAt(model.getValueAt(i, column), i, column);
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Test()::display);
}
}