java - How can I fix this code bug? -


i trying make image editing application in java using mvc design pattern. so, event handling in controller, state , operations relevant state stored in models, , user sees stored in views.

when open image, there zoom box displays zoom level of image being displayed. zoom automatically calculated when first rendered in paintcomponent() (see step #3). when open image, want zoom level set calculated be. the problem zoom level shows 0, , know why. let me explain:

1. the actionlistener for open menu item fired

in jpscontroller:

class menubarfileopenlistener implements actionlistener {     public void actionperformed(actionevent event) {         file filechooserreturnvalue = view.showandgetvalueoffilechooser();          if (filechooserreturnvalue != null) {             try {                 // irrelevant code omitted                 view.adddocument(newdocument);             } catch(ioexception ex) {                 ex.printstacktrace();             }         }     } } 

2. view.adddocument() is called

note: root of problem

in jpsview:

public void adddocument(documentmodel document) {     // irrelevant code omitted      // canvaspanelview extends jpanel     documentstabbedpane.add(newdocumentview.getcanvaspanelview());      // root of problem     double currentzoomfactor = getcurrentcanvaspanelview().getzoomfactor();      // formatting text     string zoomleveltext = statusbar_zoomleveltextfield_formatter.format(currentzoomfactor);     // setting text of text field     statusbar_zoomleveltextfield.settext(zoomleveltext); } 

3. time later, paintcomponent() is run

in canvaspanelview extends jpanel:

public void paintcomponent(graphics g) {     super.paintcomponent(g);      if (initialrender) {         initialrender = false;          // calculates zoom level         setzoomfit();     }      // irrelevant code omitted      g.drawimage(image, destinationx1, destinationy1, destinationx2,                 destinationy2, sourcex1, sourcey1, sourcex2, sourcey2, null);     } 

in part 2, have line of code:

double currentzoomfactor = getcurrentcanvaspanelview().getzoomfactor(); 

when getzoomfactor() called, current canvaspanelview must not have size, because returns 0. had problem before, , solution these lines of code in #3:

if (initialrender) {     initialrender = false;     setzoomfit(); } 

when paintcomponent() called, canvaspanelview must have been given size then, not when getzoomfactor() called. paintcomponent(), , therefore setzoomfit(), come after getzoomfactor().

how can correctly show zoom level of image when opened?

basically, have kind of race condition (as can in single thread).

what's happening adding new view, expecting laid out immediately. not how works in swing. when add new component container, request made update layouts of components in hierarchy, , layout containers have been marked invalid. won't happen until current call cycle has completed , event dispatching thread has had time process requests.

instead, can schedule @ later time adding request end of event dispatching thread. ensures request executed after current tasks on edt have been executed before (there may others follow, you've squeezed in).

the following example demonstrates point.

it adds new panel jtabbedpane, dumps it's current size, use swingutilities.invokelater request callback @ time in future , dumps panels size again. should find first request 0x0 , second valid value (depending on size of frame , , feel)

import java.awt.borderlayout; import java.awt.eventqueue; import java.awt.gridbaglayout; import java.awt.event.actionevent; import java.awt.event.actionlistener; import javax.swing.jbutton; import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.jpanel; import javax.swing.jtabbedpane; import javax.swing.swingutilities; import javax.swing.uimanager; import javax.swing.unsupportedlookandfeelexception;  public class testtabbedpane01 {      public static void main(string[] args) {         new testtabbedpane01();     }      private jtabbedpane tabbedpane;      public testtabbedpane01() {         eventqueue.invokelater(new runnable() {             @override             public void run() {                 try {                     uimanager.setlookandfeel(uimanager.getsystemlookandfeelclassname());                 } catch (classnotfoundexception ex) {                 } catch (instantiationexception ex) {                 } catch (illegalaccessexception ex) {                 } catch (unsupportedlookandfeelexception ex) {                 }                  tabbedpane = new jtabbedpane();                 jbutton btnadd = new jbutton("add");                 btnadd.addactionlistener(new actionlistener() {                     @override                     public void actionperformed(actionevent e) {                         final jpanel panel = new jpanel(new gridbaglayout());                         panel.add(new jlabel(string.valueof(tabbedpane.getcomponentcount())));                         tabbedpane.add(string.valueof(tabbedpane.getcomponentcount()), panel);                         system.out.println("new panel size = " + panel.getsize());                         swingutilities.invokelater(new runnable() {                             @override                             public void run() {                                 system.out.println("new panel size (later) = " + panel.getsize());                             }                         });                     }                 });                  jframe frame = new jframe("test");                 frame.setdefaultcloseoperation(jframe.exit_on_close);                 frame.setlayout(new borderlayout());                 frame.add(tabbedpane);                 frame.add(btnadd, borderlayout.south);                 frame.setsize(200, 200);                 frame.setlocationrelativeto(null);                 frame.setvisible(true);             }         });     }   } 

Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

javascript - jQuery .height() return 0 when visible but non-0 when hidden -