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 10 of 10

Thread: How does repaint work in combination with paintComponent (Graphics class)?

  1. #1
    Junior Member
    Join Date
    Jun 2014
    Posts
    25
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Default How does repaint work in combination with paintComponent (Graphics class)?

    I’m teaching myself AWT/Swing using an Oracle tutorial. There’s a section a don’t fully understand.

    It concerns an application that creates dynamic graphics using the Graphics class. I understand that the code that creates graphics should be put in a “paintComponent” method of a (descendant of a) JPanel class. And that when you want to change something on this panel outside “paintComponent”, you have to call the “repaint” method, that somehow causes “paintComponent” to be invoked.

    However, I don’t fully understand the explanation of the example at Creating the Demo Application (Step 3) (The Java™ Tutorials > Creating a GUI With JFC/Swing > Performing Custom Painting) . It concerns an application that moves a red square when a mouse button is clicked. The code can be found at the link, but I also repeat it below.

    package painting;
     
    import javax.swing.SwingUtilities;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.BorderFactory;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseMotionListener;
    import java.awt.event.MouseMotionAdapter;
     
    public class SwingPaintDemo3 {
     
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI(); 
                }
            });
        }
     
        private static void createAndShowGUI() {
            System.out.println("Created GUI on EDT? "+
            SwingUtilities.isEventDispatchThread());
            JFrame f = new JFrame("Swing Paint Demo");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
            f.add(new MyPanel());
            f.pack();
            f.setVisible(true);
        } 
    }
     
    class MyPanel extends JPanel {
     
        private int squareX = 50;
        private int squareY = 50;
        private int squareW = 20;
        private int squareH = 20;
     
        public MyPanel() {
     
            setBorder(BorderFactory.createLineBorder(Color.black));
     
            addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent e) {
                    moveSquare(e.getX(),e.getY());
                }
            });
     
            addMouseMotionListener(new MouseAdapter() {
                public void mouseDragged(MouseEvent e) {
                    moveSquare(e.getX(),e.getY());
                }
            });
     
        }
     
        private void moveSquare(int x, int y) {
            int OFFSET = 1;
            if ((squareX!=x) || (squareY!=y)) {
                repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
                squareX=x;
                squareY=y;
                repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
            } 
        }
     
     
        public Dimension getPreferredSize() {
            return new Dimension(250,200);
        }
     
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);       
            g.drawString("This is my custom Panel!",10,20);
            g.setColor(Color.RED);
            g.fillRect(squareX,squareY,squareW,squareH);
            g.setColor(Color.BLACK);
            g.drawRect(squareX,squareY,squareW,squareH);
        }  
    }

    This code indeed works. However, I don’t understand why. The explanation at the Oracle site is the following. “Because we are manually setting the clip, our moveSquare method invokes the repaint method not once, but twice. The first invocation tells Swing to repaint the area of the component where the square previously was (the inherited behavior uses the UI Delegate to fill that area with the current background color.) The second invocation paints the area of the component where the square currently is.”

    However, what I don’t understand: when repaint is first invoked, squareX and squareY still have their old values. If the invocation of repaint simply causes an invocation of paintComponent, then paintComponent should draw a red square at (squareX, squareY). Just like the second invocation of repaint causes paintComponent to draw a red suare at the new values of (squareX, squareY). Instead, the first invocation results in the red square being wiped out by the background color.

    So apparently, the first invocation of repaint does not simply cause an invocation of paintComponent. What does it do?


  2. #2
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,517
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: How does repaint work in combination with paintComponent (Graphics class)?

    Also posted here.

  3. #3
    Junior Member
    Join Date
    Jun 2014
    Posts
    25
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Default Re: How does repaint work in combination with paintComponent (Graphics class)?

    Yup. Are these forums somehow connected and, if so, is there a preferred place?

  4. #4
    Senior Member
    Join Date
    Jul 2013
    Location
    Europe
    Posts
    666
    Thanks
    0
    Thanked 121 Times in 105 Posts

    Default Re: How does repaint work in combination with paintComponent (Graphics class)?

    repaint() does NOT paint the component. The only thing it does is mark your component to indicate that it needs to be repainted at some point in the future. When this will be is hard to say, its up to the Swing rendering scheduler, but it will happen soon enough. If you call repaint 10 times in your method your component will not be painted 10 times, it will probably only get painted once after all 10 repaint requests have been made.

  5. #5
    Junior Member
    Join Date
    Jun 2014
    Posts
    25
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Default Re: How does repaint work in combination with paintComponent (Graphics class)?

    Thanks, this clarifies it a bit. But what I still don't understand is how the first invocation of repaint causes the red box to be wiped out.

  6. #6
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,517
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: How does repaint work in combination with paintComponent (Graphics class)?

    Try messing with the code. Take out the if() statement, remove the first repaint(), change either or both of the calls to repaint( x, y, z, q ) to simply repaint(). I don't know why most of the Oracle and legacy Sun example code is largely uncommented, but that's the way it is.

  7. #7
    Junior Member
    Join Date
    Jun 2014
    Posts
    25
    Thanks
    0
    Thanked 2 Times in 2 Posts

    Default Re: How does repaint work in combination with paintComponent (Graphics class)?

    I already messed with the code. What I found out is that the code actually works as if the first repaint removes the red box: if you remove that line, the red box remains displayed also at its old location. However, I don't understand how this line can remove the red box.

  8. #8
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,139
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: How does repaint work in combination with paintComponent (Graphics class)?

    Add some println statements to show when the repaint methods are called and when the paintComponent() method is called. What are the values of x and y when each of those methods are called? What is the region referenced by the first repaint() method vs where the paintComponent() method draws the square?
    If paintComponent() clears the regions and then redraws, both regions referenced by the repaint() are cleared but only the second region is drawn in.
    If you don't understand my answer, don't ignore it, ask a question.

  9. #9
    Senior Member
    Join Date
    Jul 2013
    Location
    Europe
    Posts
    666
    Thanks
    0
    Thanked 121 Times in 105 Posts

    Default Re: How does repaint work in combination with paintComponent (Graphics class)?

    The call to "super.paintComponent(g);" within your JPanel will invoke the default painting of panels. The default is to clear everything with the background color.
    In this case your panel will remove any leftovers from the previous paintComponent.

  10. #10
    Member Darryl.Burke's Avatar
    Join Date
    Mar 2010
    Location
    Madgaon, Goa, India
    Posts
    494
    Thanks
    8
    Thanked 48 Times in 46 Posts

    Default Re: How does repaint work in combination with paintComponent (Graphics class)?

    This thread has been cross posted here:

    http://www.coderanch.com/t/640432/GUI/java/repaint-work-combination-paintComponent-Graphics

    Although cross posting is allowed, for everyone's benefit, please read:

    Java Programming Forums Cross Posting Rules

    The Problems With Cross Posting


Similar Threads

  1. Combination Lock Class help
    By dx8292 in forum What's Wrong With My Code?
    Replies: 2
    Last Post: October 4th, 2012, 10:25 AM
  2. Graphics repaint() NOT Firing
    By russdb in forum AWT / Java Swing
    Replies: 1
    Last Post: June 22nd, 2012, 11:20 AM
  3. repaint() event does not work.
    By SagiIs in forum What's Wrong With My Code?
    Replies: 33
    Last Post: December 25th, 2011, 05:12 PM
  4. Graphics class NullPointerException Initialize Graphics Class??
    By bglueck in forum What's Wrong With My Code?
    Replies: 7
    Last Post: May 13th, 2011, 11:13 PM
  5. paintComponent(Graphics g)
    By Kumarrrr in forum Java Theory & Questions
    Replies: 1
    Last Post: February 8th, 2011, 08:55 AM