java - How can a Swing JWindow be resized without flickering? -


i trying make custom ui based on jwindow purpose of selecting area of screen shared. have extended jwindow , added code make resizable , 'cut out' centre of window using awtutilities.setwindowshape().

when running code experiencing flicker window resized in negative x , y directions, i.e. , left. appears happening window resized , drawn before components updated. below simplified version of code. when run top panel can used resize window , left. background of window set green make clear pixels not want showing are.

edit: improved code shape window correctly using componentlistener , added dummy component @ bottom further illustrate flicker (also updated screenshots).

import java.awt.borderlayout; import java.awt.color; import java.awt.graphics; import java.awt.rectangle; import java.awt.event.componentadapter; import java.awt.event.componentevent; import java.awt.event.mouseevent; import java.awt.event.mouselistener; import java.awt.event.mousemotionlistener; import java.awt.geom.area;  import javax.swing.jpanel; import javax.swing.jwindow; import javax.swing.border.compoundborder; import javax.swing.border.emptyborder; import javax.swing.border.etchedborder; import javax.swing.border.lineborder;  import com.sun.awt.awtutilities;  public class flickerwindow extends jwindow implements mouselistener, mousemotionlistener{      jpanel controlpanel;     jpanel outlinepanel;     int mousex, mousey;     rectangle windowrect;     rectangle cutoutrect;     area windowarea;      public static void main(string[] args) {         flickerwindow fw = new flickerwindow();     }      public flickerwindow() {         super();         setlayout(new borderlayout());         setbounds(500, 500, 200, 200);         setbackground(color.green);          controlpanel = new jpanel();         controlpanel.setbackground(color.gray);         controlpanel.setborder(new etchedborder(etchedborder.lowered));         controlpanel.addmouselistener(this);         controlpanel.addmousemotionlistener(this);          outlinepanel = new jpanel();         outlinepanel.setbackground(color.blue);         outlinepanel.setborder(new compoundborder(new emptyborder(2,2,2,2), new lineborder(color.red, 1)));          add(outlinepanel, borderlayout.center);         add(controlpanel, borderlayout.north);         add(new jbutton("dummy button"), borderlayout.south);         setvisible(true);         setshape();          addcomponentlistener(new componentadapter() {                        @override             public void componentresized(componentevent e) {                 setshape();             }});     }       public void paint(graphics g) {         // un-comment or breakpoint here see window updates more         //try {thread.sleep(10);} catch (exception e) {}         super.paint(g);     }      public void setshape() {         rectangle bounds = getbounds();         rectangle outlinebounds = outlinepanel.getbounds();         area newshape = new area (new rectangle(0, 0, bounds.width, bounds.height));         newshape.subtract(new area(new rectangle(3, outlinebounds.y + 3, outlinebounds.width - 6, outlinebounds.height - 6)));         setsize(bounds.width, bounds.height);         awtutilities.setwindowshape(this, newshape);     }      public void mousedragged(mouseevent e) {         int dx = e.getxonscreen() - mousex;         int dy = e.getyonscreen() - mousey;          rectangle newbounds = getbounds();         newbounds.translate(dx, dy);         newbounds.width -= dx;         newbounds.height -= dy;          mousex = e.getxonscreen();         mousey = e.getyonscreen();          setbounds(newbounds);     }      public void mousepressed(mouseevent e) {         mousex = e.getxonscreen();         mousey = e.getyonscreen();     }      public void mousemoved(mouseevent e) {}     public void mouseclicked(mouseevent e) {}     public void mousereleased(mouseevent e) {}     public void mouseentered(mouseevent e) {}     public void mouseexited(mouseevent e) {} } 

the overridden paint() method can used breakpoint or thread.sleep() can uncommented there provide clearer view of update happens.

my problem seems stem setbounds() method causing window painted screen before being laid out.


window before resizing, should look:

alt text


window during resizing larger (up , left) seen @ breakpoint @ overridden paint() method):

alt text


window during resizing smaller (down , right) seen @ breakpoint @ overridden paint() method):

alt text


granted these screenshots taken during aggressive mouse drag movements flicker becomes quite annoying more moderate mouse drags.

the green area on resize larger screenshot shows new background gets drawn before painting/layout done, seems happen in underlying componentpeer or native window manager. blue area on 'resize smaller' screenshot shows jpanel's background being pushed view out of date. happens under linux(ubuntu) , windows xp.

has found way cause window or jwindow resize buffer before changes made screen , avoid flickering effect? maybe there java.awt.... system property can set avoid this, not find 1 though.


edit #2: comment out call awtutilities.setwindowshape() (and optionally uncomment thread.sleep(10) line in paint()) drag top panel around aggressively in order see nature of flicker.

edit #3: able test behaviour under sun java on windows 7 or mac osx ?

i admit not particularly helpful answer, understanding swing may help.

see, swing own work, short of getting bit of space draw on os. drawing, widgets, etc java code. it's not running slowly, it's running without benefit of 2d graphics card acceleration , os rendering tricks.

remember directdraw? has nowadays, , window ops butter-smooth. if ever grab computer doesn't have reason (say, xp install no drivers) notice exactly type of slowdown.

with swing, because manages own space, os can't of these rendering tricks out.

somebody may come along optimization fixes problem on computer, i'm concerned it's not going fix base issue - swing slow , can't faster.

you should native toolkits. awt ok, missing lot of widgets/etc. it's native, , built-in, should plenty fast if that's need. i'm partial swt, eclipse, vuze (among others) use. combines native-ness of awt ease , features of swing, , of course runs everywhere.

edit: it's pretty clear after reading more of comments absolutely understand how windowing happens - don't want come off condescending. not that, you're more interested in resizing, comment doesn't have with. i'd still recommend swt because it's native code , faster, that's different answer 1 above.


Comments

Popular posts from this blog

asp.net - repeatedly call AddImageUrl(url) to assemble pdf document -

java - Android recognize cell phone with keyboard or not? -

iphone - How would you achieve a LED Scrolling effect? -