java - Using PropertyChangeListener to refresh JFrame (without triggering infinite loop) -
using java, have jframe containing several jpanels include various jcomboboxes, jtextfields, etc... connect entries in xml files, organized , viewed date. syncs , working i've been having trouble getting jframe update/refresh when changes being made entries (i.e. adding/removing etc), although refresh when change date. i've got point have propertychangelistener gets triggered (prints console) when try use listener refresh frame think i'm revalidating listener?
here's code jframe (i've used comments indicate failed segments):
package interfacecomponents; import java.beans.*; import javax.swing.*; import org.jdesktop.swingx.jxdatepicker; import java.awt.*; import java.awt.event.*; import java.text.*; import java.io.ioexception; import java.util.*; import java.time.*; import java.time.format.*; public class dailyview extends frame { private static final long serialversionuid = 7827570917642254745l; private final jxdatepicker calendar = new jxdatepicker(); private jlabel focuspoint; public dailyview(localdate d) throws ioexception { defaultdatemodel model = new defaultdatemodel(d); operatormenus menus = new operatormenus(); setjmenubar(menus); jpanel body = new jpanel(); body.setlayout(new boxlayout(body, boxlayout.y_axis)); dayview anchorday = new dayview(0); anchorday.setmodel(model); dayview nextday = new dayview(1); nextday.setmodel(model); body.addpropertychangelistener(new propertychangelistener() { public void propertychange(propertychangeevent evt) { system.out.println("operatorview.propertychange"); //***this i'm trying trigger refresh*** refreshframe(); } }); body.add(anchorday); body.add(nextday); add(new jscrollpane(body), borderlayout.center); jpanel footer = new jpanel(); navbuttons navpanel = new navbuttons(model); focuspoint = new jlabel(datetimeformatter.ofpattern("e, dd mmm yyyy").format(model.getdate())); focuspoint.setforeground(color.red); footer.setlayout(new borderlayout()); footer.add(focuspoint, borderlayout.center); footer.add(navpanel, borderlayout.east); footer.setbackground(color.black); add(footer, borderlayout.south); pack(); } public dailyview() throws ioexception { this(localdate.now()); } //interfaces public interface datemodel { public localdate getdate(); public void addobserver(observer o); public void removeobserver(observer o); } public interface mutabledatemodel extends datemodel { public void setdate(localdate date); } //methods public void refreshframe() { //***this i'm trying trigger refresh*** this.revalidate(); this.repaint(); } //inner classes public class defaultdatemodel extends observable implements mutabledatemodel { private localdate date; public defaultdatemodel(localdate d) { date = d; } @override public void setdate(localdate d) { date = d; setchanged(); notifyobservers(); } @override public localdate getdate() { return date; } @override public void removeobserver(observer o) { deleteobserver(o); } } public class shiftfocus extends abstractaction implements observer { private static final long serialversionuid = 680383526965967229l; private mutabledatemodel model; private int shift; public shiftfocus(mutabledatemodel m, int i) { setmodel(m); shift = i; } public void actionperformed(actionevent event) { mutabledatemodel model = getmodel(); if (model != null) { model.setdate(model.getdate().plusdays(shift)); calendar.setdate(date.from(model.getdate().atstartofday().atzone(zoneid.systemdefault()).toinstant())); pack(); } } public void setmodel(mutabledatemodel value) { if (model != null) { model.removeobserver(this); } this.model = value; if (model != null) { model.addobserver(this); } } public mutabledatemodel getmodel() { return model; } @override public void update(observable o, object arg) { focuspoint.settext(datetimeformatter.ofpattern("e, dd mmm yyyy").format(model.getdate())); } } class navbuttons extends jpanel implements observer { private static final long serialversionuid = 914087518688373731l; //instance variables private jtoolbar toolbar = new jtoolbar("navigation"); private jbutton weekback = new jbutton("<<"); private jbutton dayback = new jbutton("<"); private jbutton returntoday = new jbutton("today"); private jbutton nextday = new jbutton(">"); private jbutton nextweek = new jbutton(">>"); private mutabledatemodel model; //constructor public navbuttons(mutabledatemodel model) { weekback.addactionlistener(new shiftfocus(model, -7)); dayback.addactionlistener(new shiftfocus(model, -1)); returntoday.addactionlistener(new actionlistener() { public void actionperformed(actionevent event) { mutabledatemodel m = getmodel(); m.setdate(localdate.now()); setmodel(m); pack(); } }); nextday.addactionlistener(new shiftfocus(model, 1)); nextweek.addactionlistener(new shiftfocus(model, 7)); toolbar.add(weekback); toolbar.add(dayback); toolbar.add(returntoday); toolbar.add(nextday); toolbar.add(nextweek); calendar.seteditable(true); calendar.setformats("e, dd mmm yyyy"); calendar.setdate(date.from(model.getdate().atstartofday().atzone(zoneid.systemdefault()).toinstant())); calendar.addactionlistener(new actionlistener() { public void actionperformed(actionevent event) { mutabledatemodel model = getmodel(); if (model != null) { model.setdate(localdate.parse(new simpledateformat("yyyy-mm-dd").format(calendar.getdate()))); pack(); } } }); toolbar.add(calendar); toolbar.add(new galileomode()); add(toolbar); setmodel(model); } public void setmodel (mutabledatemodel value) { if (model != null) { model.removeobserver(this); } this.model = value; if (model != null) { model.addobserver(this); } } public mutabledatemodel getmodel() { return model; } @override public void update(observable o, object arg) {/* models data changes */} } } edit
after feedback, have tried far:
thisframe = this; body.addpropertychangelistener(new propertychangelistener() { public void propertychange(propertychangeevent evt) { system.out.println("operatorview.propertychange"); // thisframe.removeall(); // thisframe.dispose(); // thisframe.remove(body); // thisframe.add(new jscrollpane(body), borderlayout.center); thisframe.getcontentpane().validate(); // thisframe.revalidate(); thisframe.getcontentpane().repaint(); // thisframe.refreshframe(); } }); with dailyview thisframe; declared instance variable @ top.
edit
in case there's out there reading this, getting propertychangelistener trigger events refresh underlying panels, causes infinite loop propertychangelistener gets called again. (re)validate() , repaint() don't seem have issue they're not refreshing panels' content...anyone point me in right direction/link similar question, etc appreciated.
when use 'this' pointer, refers class in. believe problem coming because 'this' pointer refer listener , not jpanel. perhaps problem can solved by
frame thisframe = this; body.addpropertychangelistener(new propertychangelistener() { public void propertychange(propertychangeevent evt) { system.out.println("operatorview.propertychange"); //***this i'm trying trigger refresh*** thisframe.refreshframe(); } });
Comments
Post a Comment