Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 11 of 11

Thread: Flicker with JPanel in JApplet

  1. #1
    Junior Member
    Join Date
    Jun 2012
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Flicker with JPanel in JApplet

    I have an applet which I wanted to convert from AWT to Swing,
    which went pretty well except for one thing.

    The applet window is divided into two parts:
    1) Top part is a Panel/JPanel with some labels, buttons, etc.
    2) Bottom part is just drawing area (drawRect, fillRect, that sort of thing).

    Part of the applet is 'drag and drop' whereby shapes are moved around
    by dragging them with the mouse.

    In order to eliminate flicker while doing that, I use an image buffer for the painting.

    It all works fine with AWT.

    With Swing, it seems I have two choices:
    a) No panel appears
    b) Panel appears, but flickers every time mouse is moved.

    The difference is a call to repaint() for the Panel itself,
    which wasn't necessary with AWT.

    I tried making the JPanel a (regular) Panel,
    which stopped the flicker problem, but caused some others -
    like the controls added to it were painted incorrectly,
    and some of them ceased functioning.

    Any ideas?

    Here is a simplified version of the applet.

    See the line marked with ***** for the focus of my question.
    It doesn't seem to matter where I try to put it, the results are the same.

    The panel just has one button, and you can drag the blue rectangle around with the mouse.

    /*
    <applet code="sw1.class" codebase="./"
    align="baseline" width="600" height="600">
    alt=&quot;Applet not running&quot;
    Applet tag ignored
    </applet>
    */
     
    import java.applet.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
     
    public class sw1 extends JApplet
      implements MouseMotionListener
    {
     JPanel p;
     JButton b;
     private Image im;
     private Dimension imsize;
     private Graphics g2;
     
     public void init()
     {
      setLayout(null);
      p = new JPanel();
      b = new JButton("Yo! A button");
      p.setBounds(50,50,160,40);
      p.add(b);
      setBackground(Color.gray);
      add(p);
      addMouseMotionListener(this);
     }
     
     int x = 50, y = 100;
     public void paint(Graphics g)
     {
     Dimension d = getSize(); 
     if ( (im == null) ||
          (d.width != imsize.width)|| (d.height !=imsize.height) ) 
      {
       im = createImage(d.width,d.height);    
       imsize = d; 
       g2 = im.getGraphics();
      } 
     
      g2.setColor(Color.gray);
      g2.fillRect(0,0,d.width, d.height); // Need this or dragged image gets left behind and replicated.
     
      // *****
      p.repaint(); // ***** This is the line in question: without it, no panel, with it, flickering panel.
      // *****
     
      paint2(g2);
      g.drawImage(im,0,0,null); 
     }
     
     public void paint2(Graphics g)
     {
      g.setColor(Color.blue);
      g.drawRect(x, y, 100, 60);
     }
     
     public void mouseMoved(MouseEvent e) { }
     public void mouseDragged(MouseEvent e) 
       {
        x = e.getX();
        y = e.getY();
        repaint();
       }
     
    }


  2. #2
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,372
    Thanks
    183
    Thanked 836 Times in 779 Posts
    Blog Entries
    5

    Default Re: Flicker with JPanel in JApplet

    Some recommendations a) I wouldn't recommend using a null layout. b) Override paintComponent, not paint (there is a big difference when trying to add components to the component being painted, because you end up painting over those components) c) Calling repaint from within paint is a bad idea - it cues your painting into an infinite loop (repaint tells Swing to repaint the component - hence calling paint). The latter 2 of these points require special attention, as they are causing the problems you see.

  3. #3
    Junior Member
    Join Date
    Jun 2012
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Flicker with JPanel in JApplet

    Thank you for your speedy reply.
    Perhaps you could elaborate a little?

    > Some recommendations
    > a) I wouldn't recommend using a null layout.


    That may be good advice in general,
    but I don't see the relevance to this particular question.

    Without the setBounds call, which I believe conflicts with Layout Managers,
    the Panel seems to take over the whole window, and obscures anything else.

    > b) Override paintComponent, not paint (there is a big difference when trying to add components to the component being painted)


    How should I do that?

    I changed paint to paintComponent, and it is never called,
    and then only the panel shows up - nothing else.

    I tried p.paintComponent(g) and it said I couldn't do that because it is protected.

    > c) Calling repaint from within paint is a bad idea - it cues your painting into an infinite loop (repaint tells Swing to repaint the component - hence calling paint)

    The repaint which is called within paint is for the Panel -
    not the applet, and there is no recursion.
    At various times in doing this, I did cause that, and of course
    it dies with stack overflow, but not in version I presented.

    Thank you for your patience and your help.

  4. #4
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,372
    Thanks
    183
    Thanked 836 Times in 779 Posts
    Blog Entries
    5

    Default Re: Flicker with JPanel in JApplet

    Actually, I stand corrected. I misread your code in a few places - I apologize.

    For point a, this wasn't directly related to your problem. Just general advice - I speak from experience when I say using a layout manager helps incredible when it comes to code reuse and maintainability.

    For the flickering, you shouldn't need to worry about it (eg manually double buffering - Swing is already double buffered). Either way, you should make a call to the super method when painting...here's an abbreviated version you can try
    @Override
    public void paint(Graphics g){
    	 super.paint(g); 
    	 g.setColor(Color.blue);
    	 g.drawRect(x, y, 100, 60);
     }

    I would recommend drawing to a JPanel added to the applet rather than drawing directly to the JApplet (using the paintComponent method)

  5. #5
    Junior Member
    Join Date
    Jun 2012
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Flicker with JPanel in JApplet

    Sorry to have to keep going, but the variations on your last suggestion didn't improve anything.

    If I remove the manual double buffering I get horrible flicker over the whole applet,
    not just the controls JPanel.

    I have not tried making the lower area of the window into another JPanel because
    in the full applet it would be very complicated to do so.

    The basic problem, it seems to me, stems from one thing:
    having to repaint the background all the time, which is for two reasons.
    1) I want a color other than the default.
    2) I need to in any case to erase the previous incarnation of the dragged shape.
    Even when I call repaint on a limited area far from the flickering panel,
    it still flickers.

    This example is similar to my test case, but everything is within the same JPanel and there are no subcomponents which appear/disappear. And there is no background fill, either.

  6. #6
    Junior Member
    Join Date
    Jun 2012
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Flicker with JPanel in JApplet

    > I have not tried making the lower area of the window into another JPanel because
    in the full applet it would be very complicated to do so.

    It looks like that will be the solution: it works quite well in the small test case,
    but will be a lot of work in the full applet.

    I'll let you know how it goes.

  7. #7
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,372
    Thanks
    183
    Thanked 836 Times in 779 Posts
    Blog Entries
    5

    Default Re: Flicker with JPanel in JApplet

    Sorry to have to keep going, but the variations on your last suggestion didn't improve anything.
    Really? You replaced all the code in your paint method with the one posted above? That works on my end.

    The basic problem, it seems to me, stems from one thing:
    having to repaint the background all the time, which is for two reasons.
    1) I want a color other than the default.
    2) I need to in any case to erase the previous incarnation of the dragged shape.
    Even when I call repaint on a limited area far from the flickering panel,
    it still flickers.
    1) A JPanel honors the color in the setBackground method
    2) Calling the super.paint or super.paintComponent in your code erases all previous drawing

    As I mentioned above, draw to a JPanel. Remove the paint method, override the paintComponent method of said JPanel (for instance, your p object), and remove the null layout. At the risk of ruining the fun parts of trial and error, here is some code - try running the following:
    public class sw1 extends JApplet implements MouseMotionListener
    {
    	JPanel p;
    	JButton b;
     
    	public void init()
    	{
    		p = new JPanel(){
    			@Override
    			public void paintComponent(Graphics g){
    				super.paintComponent(g);
    				g.setColor(Color.blue);
    				g.drawRect(x, y, 100, 60);
    			}
    		};
    		p.setBackground(Color.gray);
    		b = new JButton("Yo! A button");
    		p.add(b);
    		setBackground(Color.gray);
    		add(p);
    		addMouseMotionListener(this);
    	}
     
    	int x = 50, y = 100;
    	public void mouseMoved(MouseEvent e){}
    		public void mouseDragged(MouseEvent e) 
    	{
    		x = e.getX();
    		y = e.getY();
    		repaint();
    	}
     
    }

  8. #8
    Junior Member
    Join Date
    Jun 2012
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Flicker with JPanel in JApplet

    Thanks for sticking with this.

    For the version of the program below, the behavior is as follows:
    -the moving rectangle flickers as it moves
    -the background remains the default
    - the panel / button does not flicker.

    (I changed the background to red to make it more obvious that it is not showing up.)

    To avoid any ambiguity, here's the full program for this test.

     /*
     <applet code="sw1.class" codebase="./"
     align="baseline" width="600" height="600">
     alt=&quot;Applet not running&quot;
     Applet tag ignored
     </applet>
     */
     
    import java.applet.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
     
        public class sw1 extends JApplet
          implements MouseMotionListener
        {
         JPanel p;
         JButton b;
         private Image im;
         private Dimension imsize;
         private Graphics g2;
     
         public void init()
         {
          setLayout(null);
          p = new JPanel();
          b = new JButton("Yo! A button");
          p.setBounds(50,50,160,40);
          p.add(b);
          setBackground(Color.red);
          add(p);
          addMouseMotionListener(this);
         }
     
         @Override
         public void paint(Graphics g){
    	    super.paint(g); 
    	    g.setColor(Color.blue);
    	    g.drawRect(x, y, 100, 60);
         }
     
         int x = 50, y = 100;
     
         public void mouseMoved(MouseEvent e) { }
         public void mouseDragged(MouseEvent e)
           {
            x = e.getX();
            y = e.getY();
            repaint();
           }
        }

  9. #9
    Junior Member
    Join Date
    Jun 2012
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Flicker with JPanel in JApplet

    > As I mentioned above, draw to a JPanel. Remove the paint method, override the paintComponent method of said JPanel (for instance, your p object), and remove the null layout. At the risk of ruining the fun parts of trial and error, here is some code - try running the following:

    That does work perfectly - but - I'll have to see if it scales up so to speak,
    since it is not a perfect model of the full applet.

    It will take some work to make the full applet fit this model.

    Thanks for you help so far.

  10. #10
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,372
    Thanks
    183
    Thanked 836 Times in 779 Posts
    Blog Entries
    5

    Default Re: Flicker with JPanel in JApplet

    Good luck, and post again if you have troubles. For what its worth, I've written some pretty comprehensive painting implementations, and the times I witnessed flickering it was a simple implementation problem or issue with having computationally intensive tasks in my painting method

  11. #11
    Junior Member
    Join Date
    Jun 2012
    Posts
    7
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Flicker with JPanel in JApplet

    > As I mentioned above, draw to a JPanel. Remove the paint method, override the paintComponent method of said JPanel

    THANKS again - that was the ticket - it's all working perfectly now!

    Here's what I did (kinda kludgy, but I'll clean it up "later"):

    I added a second JPanel the entire size of the applet, and put it underneath the other one.
    In effect, the new JPanel is the applet for drawing purposes.

    Then paintComponent() for that panel just calls the applets (former) paint(), now called paint2(),
    passing the JPanel's graphics as the parameter.

    And presto! no flicker, faster than it was before, and I'm happy as a clam!

Similar Threads

  1. Components I add to JApplet won't appear!
    By austin.rose94 in forum What's Wrong With My Code?
    Replies: 3
    Last Post: January 6th, 2012, 11:47 AM
  2. [SOLVED] Pesky <JPanel>.getWidth() and <JPanel>.getHeight() Methods...
    By snowguy13 in forum AWT / Java Swing
    Replies: 1
    Last Post: December 31st, 2011, 03:35 PM
  3. BufferedImage create flicker in simple code
    By arnbook in forum What's Wrong With My Code?
    Replies: 0
    Last Post: March 12th, 2011, 12:22 AM
  4. How to copy image from one jpanel to another jpanel
    By ramanavarayuri1986 in forum AWT / Java Swing
    Replies: 0
    Last Post: February 15th, 2010, 02:36 AM
  5. Creating and displaying a JPanel inside another JPanel
    By JayDuck in forum AWT / Java Swing
    Replies: 1
    Last Post: April 7th, 2009, 09:02 AM

Tags for this Thread