java - JTable change color for entire column when values changed - Swing -
i tried find here long time answer question without exact result expected.
i have jtable every time changing values in entire column (only in 1 column every time). want listen table changes , when data changes in column, color in column changed , other columns in default color.
this code table listener:
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 want know column changed or that***){ renderercomp.setbackground(color.cyan); } } }); return renderercomp ; } }
and code table creation:
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); }
store desired state in tablemodel
; let tablecellrenderer
use state condition view accordingly. in example below, setvalueat()
updates cell, edited
marked true
. render, applied column zero, changes display accordingly. note how clearedited()
invokes firetabledatachanged()
force table render cells when called in clear handler.
addendum: update below shows 1 approach handling multiple columns independently. custommodel
contains map<integer, boolean>
store edited state each column customrenderer
applied. aside, customrenderer
invokes convertcolumnindextomodel()
, sets selection color correctly.
import 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"}); (int = 0; < 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) { (int = 0; < model.getrowcount(); i++) { model.setvalueat(model.getvalueat(i, column), i, column); } } } public static void main(string[] args) { eventqueue.invokelater(new test()::display); } }
Comments
Post a Comment