bustany
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=17 0]}
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.setDebugGraphicsOptio ns(DebugGr aphics.LOG _OPTION);
// Add the main panel to the scroll pane.
this.getViewport().add(mai nPanel);
}
/*
// 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,20 0);
f.setTitle("Capacity");
f.setVisible(true);
f.setDefaultCloseOperation (WindowCon stants.DIS POSE_ON_CL OSE);
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.ColorUIRe source[r=2 04,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.ColorUIRe source[r=0 ,g=0,b=0]
Graphics(7-1) Setting font: javax.swing.plaf.FontUIRes ource[fami ly=dialog, name=Dialo g,style=pl ain,size=1 2]
Graphics(10-1) Setting color: javax.swing.plaf.ColorUIRe source[r=0 ,g=0,b=0]
Graphics(10-1) Setting font: javax.swing.plaf.FontUIRes ource[fami ly=dialog, name=Dialo g,style=pl ain,size=1 2]
Graphics(12-1) Setting color: javax.swing.plaf.ColorUIRe source[r=2 04,g=204,b =204]
Graphics(12-1) Filling rect: java.awt.Rectangle[x=0,y=0 ,width=189 ,height=17 0]
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
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.setDebugGraphicsOptio
// Add the main panel to the scroll pane.
this.getViewport().add(mai
}
/*
// Only applicable for JPanel.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.magenta);
g.fillArc(100,100,150,140,
} // 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
j.setColor(Color.black);
j.drawArc(100,100,50,50,30
j.dispose();
} // public void paintComponent
public static void main(String args[])
{
final JFrame f = new JFrame();
f.getContentPane().add(new
f.setBounds(400,400,200,20
f.setTitle("Capacity");
f.setVisible(true);
f.setDefaultCloseOperation
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.ColorUIRe
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.ColorUIRe
Graphics(7-1) Setting font: javax.swing.plaf.FontUIRes
Graphics(10-1) Setting color: javax.swing.plaf.ColorUIRe
Graphics(10-1) Setting font: javax.swing.plaf.FontUIRes
Graphics(12-1) Setting color: javax.swing.plaf.ColorUIRe
Graphics(12-1) Filling rect: java.awt.Rectangle[x=0,y=0
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I increased the points by 30 since he answered part two
of the question
of the question
The reason that the drawing is painted over is that order of drawing components in your program is:
JScrollPane.paintComponent
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,
} // public void paintComponent
};
public CapacityScrollPane()
{
this.setDebugGraphicsOptio
// Add the main panel to the scroll pane.
this.getViewport().add(mai
}
public static void main(String args[])
{
final JFrame f = new JFrame();
f.getContentPane().add(new
f.setBounds(400,400,200,20
f.setTitle("Capacity");
f.setVisible(true);
f.setDefaultCloseOperation
f.addWindowListener(new WindowAdapter()
{
public void windowClosed(WindowEvent e)
{
System.exit(0);
}});
}
}