Link to home
Start Free TrialLog in
Avatar of bustany
bustanyFlag for United States of America

asked on

JScrollPane is erasing the Graphics Image but JPanel doesn't

When I draw a line inside a JPanel (which is
itself is contained within a JScrollPane), the
line is drawn then quickly painted over!!

However, when I eliminate the use of JScrollPane
and simply use JPanel, the problem doesn't happen.
Based on the DebugGraphics class output (included
at the bottom), someone is repainting the background
over the entire JFrame.  Very odd!!!!!!
{Graphics(12-1) Filling rect: java.awt.Rectangle[x=0,y=0,width=189,height=170]}


Another very related question worth 10 points:
If I move the window (i.e., JFrame) to the edge
of my display screen the image appears. Then, when
I drag or move another unrelated window over a portion
of the Graphics Image, the repainting of the image
is considerably flickering  even though I didn't
turn off double buffering.
This flickering does not happen when I only use
JPanel.


-------- CapacityScrollPane.java ------------
import javax.swing.*;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.*;

public class CapacityScrollPane extends JScrollPane
{
    private JPanel mainPanel = new JPanel();

    public CapacityScrollPane()
    {
        this.setDebugGraphicsOptions(DebugGraphics.LOG_OPTION);

        // Add the main panel to the scroll pane.
        this.getViewport().add(mainPanel);
    }

/*
    // Only applicable for JPanel.
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        g.setColor(Color.magenta);
        g.fillArc(100,100,150,140,30,300);

    } // public void paintComponent
*/

    // Only applicable for JScrollPane.
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Graphics j = mainPanel.getGraphics();

        j.setColor(Color.magenta);
        j.fillArc(100,100,50,50,30,180);
        j.setColor(Color.black);
        j.drawArc(100,100,50,50,30,90);

        j.dispose();

    } // public void paintComponent


    public static void main(String args[])
    {
        final JFrame f = new JFrame();
        f.getContentPane().add(new CapacityScrollPane());

        f.setBounds(400,400,200,200);
        f.setTitle("Capacity");
        f.setVisible(true);

        f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        f.addWindowListener(new WindowAdapter()
                            {
                                public void windowClosed(WindowEvent e)
                                {
                                    System.exit(0);
                                }});
    }
}
---------------------------------------------


............................
... many lines deleted .....
............................
Graphics(1-1) Drawing line: from (191, 1) to (191, 172)
Graphics(1-1) Drawing line: from (1, 172) to (191, 172)
Graphics(1-1) Setting color: javax.swing.plaf.ColorUIResource[r=204,g=204,b=204]
Graphics(1-1) Drawing line: from (190, 2) to (190, 2)
Graphics(1-1) Drawing line: from (1, 171) to (1, 171)
Graphics(1-1) Translating by: java.awt.Point[x=0,y=0]
Graphics(7-1) Setting color: javax.swing.plaf.ColorUIResource[r=0,g=0,b=0]
Graphics(7-1) Setting font: javax.swing.plaf.FontUIResource[family=dialog,name=Dialog,style=plain,size=12]
Graphics(10-1) Setting color: javax.swing.plaf.ColorUIResource[r=0,g=0,b=0]
Graphics(10-1) Setting font: javax.swing.plaf.FontUIResource[family=dialog,name=Dialog,style=plain,size=12]
Graphics(12-1) Setting color: javax.swing.plaf.ColorUIResource[r=204,g=204,b=204]
Graphics(12-1) Filling rect: java.awt.Rectangle[x=0,y=0,width=189,height=170]

Avatar of mwibbels
mwibbels

The problem with your code is that you try to draw on the JPanel from the JScrollPanes's paintComponent. Instead you should redefine the paintComponent of the JPanel.
The reason that the drawing is painted over is that order of drawing components in your program is:

JScrollPane.paintComponent()   <- here you draw in the JPanel
JScrollPane.paintChildren()
  calls JPanel.paintComponent() <- here the default behaviour of the JPanel is to fill its space with the background color, thus erasing your drawing

Redefine your code as:



import javax.swing.*;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.*;

public class CapacityScrollPane extends JScrollPane
{
      private JPanel mainPanel = new JPanel() {

                           // ovverride paintComponent of the JPanel
            public void paintComponent(Graphics g)
            {
                  super.paintComponent(g);

                  g.setColor(Color.magenta);
                  g.fillArc(100,100,150,140,30,300);

            } // public void paintComponent

      };

      public CapacityScrollPane()
      {
            this.setDebugGraphicsOptions(DebugGraphics.LOG_OPTION);

            // Add the main panel to the scroll pane.
            this.getViewport().add(mainPanel);
      }

      public static void main(String args[])
      {
            final JFrame f = new JFrame();
            f.getContentPane().add(new CapacityScrollPane());

            f.setBounds(400,400,200,200);
            f.setTitle("Capacity");
            f.setVisible(true);

            f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

            f.addWindowListener(new WindowAdapter()
                                          {
                                                public void windowClosed(WindowEvent e)
                                                {
                                                      System.exit(0);
                                                }});
      }
}

Avatar of bustany

ASKER

Thank you, mwibbels.  Your answer did fix
the problem and made it clearer.

However, I'm still very confused how the
image did get painted and remained on the screen
when the JFrame is moved to the edge of the
screen (i.e., beyond the edge) or when another
window overlapped on top of a portion of the
image.  In both of these cases, shouldn't the
image never have remained since it should have
been painted over the the JPanel's paintComponent?

Again, thank you.

Mohammed
ASKER CERTIFIED SOLUTION
Avatar of mwibbels
mwibbels

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of bustany

ASKER

I increased the points by 30 since he answered part two
of the question