java - JFrame, JPanel, JButton, and Inheritance -
so, made jframe
class , jpanel
class (which pretty complicated beacuse there buttons in panel). in jframe
class, have make array of jpanel
class, goes this
public class frame extends jframe { //some variables , methods here int lines; public frame() { //some code here panelwithbutton[] pwb = new panelwithbutton[5]; //some code here } }
and problem is, buttons in jpanel
have different actionlisteners
each button should change variables in jframe
class
public class panelwithbutton extends jpanel { //some variables , method jbutton abutton = new jbutton(); jbutton bbutton = new jbutton(); jbutton cbutton = new jbutton(); public button() { //some code here add(abutton); abutton.addactionlistener(new actionlistener() { public void actionperformed(actionevent e) { frame.lines = 4; } }); add(bbutton); abutton.addactionlistener(new actionlistener() { public void actionperformed(actionevent e) { frame.lines = 5; } }); add(cbutton); abutton.addactionlistener(new actionlistener() { public void actionperformed(actionevent e) { frame.lines = 6; } }); //some code here } }
so, that's it. each button change variable of frame differently. it's not working. think problem code, don't know should change to:
frame.lines
here error: non-static variable lines cannot referenced static context.
please me. sorry broken english , if question not clear enough, ask. in advance. :)
"here error:
non-static variable lines cannot referenced static context
."
you're getting error because you're trying access lines
in static way, when lines
isn't static
variable, it's instance variable. want reference instance variable.
one way pass frame
reference panelwithbutton
through constructor injection, can access instance field lines
. like
public class frame extends jframe { private int lines; // private encapsulation. getter/setter below ... panelwithbutton panel = new panelwithbutton(frame.this); ... public void setlines(int lines) { this.lines = lines; } } public class panelwithbutton extends jpanel { private frame f; public panelwithbutton(final frame f) { this.f = f; } public void button() { ... public void actionperformed(actionevent e) { f.setlines(5); } } }
by passing same instance of frame
panelwithbutton
, it's able access instance members, method setlines
. used private field setter
not break rules of encapsulation.
there better solutions common scenario though. 1 1 simple fix (bu holes). method exposes frame
class unnecesarily. in particular situation use sort of mvc architecture. easier solution use interface
middleman , have frame
implement (example here, since want manipulate data, mvc design best approach.
side notes
- use java naming convention. class names begin capital letters.
update
here's example of simple mvc (model, view, controller) design, using of program ideas. i'll walk through it.
model linesmodel
class. property has int lines
. has setlines
method. special thing method fires property change event when ever method called, view can changed
public void setlines(int value) { int oldvalue = lines; lines = value; propertysupport.firepropertychange(lines_property, oldvalue, lines); }
controller panelwithbuttons
class. button , when pressed, calls setlines
method of linesmodel
, fires property change , notifies interested listener.
fivelines.addactionlistener(new actionlistener() { public void actionperformed(actionevent e) { linemodel.setlines(4); } });
view paintpanel
class. takes number of lines linesmodel
, paints number of lines.
@override protected void paintcomponent(graphics g) { super.paintcomponent(g); int y = 50; (int = 0; < linemodel.getlines(); i++) { g.drawline(50, y, 200, y); y += 20; } }
here's complete running program. can run through , try , learn what's going on.
import java.awt.borderlayout; import java.awt.dimension; import java.awt.graphics; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.beans.propertychangeevent; import java.beans.propertychangelistener; import java.beans.propertychangesupport; import java.io.serializable; import javax.swing.jbutton; import javax.swing.jframe; import javax.swing.jpanel; import javax.swing.swingutilities; public class frame extends jframe { private linesmodel linemodel; private paintpanel paintpanel; private panelwithbuttons panelwithbuttons; public frame() { linemodel = new linesmodel(); paintpanel = new paintpanel(); panelwithbuttons = new panelwithbuttons(linemodel); linemodel.addpropertychangelistener(new propertychangelistener(){ @override public void propertychange(propertychangeevent evt) { string prop = evt.getpropertyname(); if (linesmodel.lines_property.equals(prop)) { paintpanel.repaint(); } } }); add(paintpanel); add(panelwithbuttons, borderlayout.south); settitle("mvc example"); setdefaultcloseoperation(jframe.exit_on_close); setlocationrelativeto(null); pack(); setvisible(true); } public class paintpanel extends jpanel { @override protected void paintcomponent(graphics g) { super.paintcomponent(g); int y = 50; (int = 0; < linemodel.getlines(); i++) { g.drawline(50, y, 200, y); y += 20; } } @override public dimension getpreferredsize() { return new dimension(300, 300); } } public static void main(string[] args) { swingutilities.invokelater(new runnable(){ public void run() { new frame(); } }); } } class panelwithbuttons extends jpanel { private final jbutton fourlines = new jbutton("four"); private final jbutton fivelines = new jbutton("five"); private linesmodel linemodel; public panelwithbuttons(linesmodel linemodel) { this.linemodel = linemodel; fivelines.addactionlistener(new actionlistener() { public void actionperformed(actionevent e) { panelwithbuttons.this.linemodel.setlines(4); } }); fourlines.addactionlistener(new actionlistener() { public void actionperformed(actionevent e) { panelwithbuttons.this.linemodel.setlines(5); } }); add(fourlines); add(fivelines); } } class linesmodel implements serializable { public static final string lines_property = "linesproperty"; private int lines; private propertychangesupport propertysupport; public linesmodel() { propertysupport = new propertychangesupport(this); } public int getlines() { return lines; } public void setlines(int value) { int oldvalue = lines; lines = value; propertysupport.firepropertychange(lines_property, oldvalue, lines); } public void addpropertychangelistener(propertychangelistener listener) { propertysupport.addpropertychangelistener(listener); } public void removepropertychangelistener(propertychangelistener listener) { propertysupport.removepropertychangelistener(listener); } }
Comments
Post a Comment