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