1

i am developing a java swing application that doesn't fit the normal application profile. It contains a tabbed pane (and some other panels) and each tab contains a Canvas with active rendering (only one thread paints at a time).

The problem is that when i resize the main application window the canvas content doesn't show (it shows up when i stop dragging the mouse) and i cant figure why. I've also noticed that some tutorials render the content to a buffered image:

http://jamesgames.org/resources/double_buffer/double_buffering_and_active_rendering.html

Could that be the reason the Canvas is flickering (the way i understand the tutorial buffered image was only use to remove the title bar offset)?

The GUI is structured like this:

JFrame 
  - TabbedPane
      - ScrollPane
          - Canvas 1
      - ScrollPane
          - Canvas 2
  - JPanel
    - labels,buttons,..

The code:

class Renderer extends Canvas implements Runnable
{
   Thread hThread = null;
   BufferStrategy strategy = null;  

   Renderer()
   {
       setIgnoreRepaint(true);
   }

   public void run()
   {
         while(active)
         {  
              g = strategy.getDrawGraphics();

              draw(g); // renderer elements

              strategy.show();
              g.dispose(); 
         }
   }

   // Called when switched to in Tabbed pane
   public void start()
   {
       createBufferStrategy(2); 
       strategy = getBufferStrategy();
       hThread = new Thread(this); 
       hThread.start();
   }

   // Called when switched off in Tabbed pane
   public void stop(){
       hThread.stop();
   }

} 
blejzz
  • 3,349
  • 4
  • 39
  • 60

2 Answers2

1

Double buffering techniques are for reducing or eliminating flickering in fast painting code, which is what you should be accomplishing via the BufferStrategy (internally using a BufferedImage).

Looks like this will get you headed in the right direction: AWT custom rendering - capture smooth resizes and eliminate resize flicker (EDIT: this link actually does not solve the Resize problem)

Community
  • 1
  • 1
Jim
  • 3,476
  • 4
  • 23
  • 33
  • so i should draw on a buffered image and also create a buffered strategy or does createBufferStrategy take care of that? Don't see how the link can help (since rendering is done in a thread)? – blejzz Apr 23 '12 at 21:04
  • buffered strategy takes care of the double buffering for you. You're telling it when to display the buffered image when you call strategy.show(). You should follow the example of how they did the threading in the question I linked to. I don't understand why you create a new Thread object in the start() method. Since Renderer implements Runnable, the Thread creation should be outside of Renderer. Reading that linked question more deeply reveals that they did not solve the resize problem. Sorry. more... – Jim Apr 23 '12 at 21:34
  • Maybe one of these or a combination will help: `Toolkit.getDefaultToolkit().setDynamicLayout(true); Toolkit.getDefaultToolkit().getDesktopProperty("awt.dynamicLayoutSupported"); System.setProperty("sun.awt.noerasebackground", "true");` – Jim Apr 23 '12 at 21:35
  • maybe listen for resize events and pause your render loop during resize? – Jim Apr 23 '12 at 21:54
  • i'll try it but dont know if it will help because the canvas is gray and when i resize the window and move the mouse around it turns white. When i stop moving the mouse it turns back to gray. So it looks like some other component is painting over it (maybe tabbed pane). or something like that – blejzz Apr 23 '12 at 22:01
1

fixed my problem. The solution was to remove the JScrollPane and replace it with a JPanel. I then add the canvas to the JPanel and handle scrolling on my own (with JScrollBar). The canvas isnt flickering anymore and also resizing performs better.

blejzz
  • 3,349
  • 4
  • 39
  • 60