Skip to main content

Gradient JPanel drawing issues when obscuring window moves.

1 reply [Last post]
d_bleyl
Offline
Joined: 2003-07-15
Points: 0

Hello,

I subclassed JPanel to create a GradientJPanel. All is fine, but when a covering window is moved, a ghost rectangle remains for a split second, and it's the JFrame's background color.

<br />
public class GradientJPanel extends JPanel {<br />
    private Color colorTwo = Color.WHITE;<br />
    private Color colorOne = new Color(20, 19, 153, 20);<br />
    private TexturePaint tp;<br />
    private BufferedImage bufferedImage;<br />
    private Rectangle2D anchor;<br />
    private Rectangle clipBounds = new Rectangle();<br />
    private GradientPaint gp;<br />
    private int cachedHeight = 0;<br />
    /**<br />
     * Construct a JPanel which draws tiles, and a translucent shade on top.<br />
     * The tiled image is<br />
     **/<br />
    public GradientJPanel() {<br />
        bufferedImage = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB);<br />
        Graphics2D g2 = bufferedImage.createGraphics();<br />
        g2.setColor(Color.DARK_GRAY);<br />
        g2.fillRect(0, 0, 50, 50);<br />
        g2.setColor(Color.GRAY);<br />
        g2.fillOval(5, 5, 45, 45);<br />
        g2.drawRect(0, 0, 50, 50);<br />
        anchor = new Rectangle(0, 0, 50, 50);<br />
        tp = new TexturePaint(bufferedImage, anchor);<br />
        GradientPaint gp = new GradientPaint(0, 0, colorOne, 0, getHeight(), colorTwo);<br />
        setDoubleBuffered(false);<br />
    }<br />
    /*<br />
     * (non-Javadoc)<br />
     *<br />
     * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)<br />
     */<br />
    protected void paintComponent(Graphics g) {<br />
        if (cachedHeight != getHeight()) {<br />
            cachedHeight = getHeight();<br />
            gp = new GradientPaint(0, 0, colorOne, 0, getHeight(), colorTwo);<br />
        }<br />
        if (isOpaque()) {<br />
            Graphics2D g2 = (Graphics2D) g.create();<br />
            g2.setPaint(tp);<br />
            g2.fillRect(0, 0, getWidth(), cachedHeight);<br />
            g2.setPaint(gp);<br />
            g2.fillRect(0, 0, getWidth(), cachedHeight);<br />
            g2.dispose();<br />
        }<br />
    }<br />
}</p>
<p>

Here's a test client:
<br />
 public class Main {<br />
    /**<br />
     * Creates four JFrames, with various numbers of custom JPanels.<br />
     *<br />
     * @param args No cmd-line args.<br />
     */<br />
    public static void main(String[] args) {<br />
        panels(1);<br />
        panels(10);<br />
        panels(20);<br />
        panels(50);<br />
    }<br />
    /**<br />
     * Create a JFrame, and create and add the number of panels specified.<br />
     *<br />
     * @param numberOfPanels Number of panels created and added to the JFrame.<br />
     */<br />
    private static void panels(int numberOfPanels) {<br />
        JFrame parentFrame = new JFrame();<br />
        //Set the background color of the JFrame - this is the color that<br />
        //bleeds thru when windows move over the JFrame.<br />
        parentFrame.setBackground(Color.LIGHT_GRAY);<br />
        //Apply double buffering to the content pane.<br />
        JPanel contentPane = new GradientJPanel();<br />
        contentPane.setDoubleBuffered(true);<br />
        parentFrame.setContentPane(contentPane);<br />
        parentFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);<br />
        parentFrame.addWindowStateListener(new WindowStateListener() {<br />
            public void windowStateChanged(WindowEvent e) {<br />
                if (e.getNewState() == WindowEvent.WINDOW_CLOSING) {<br />
                    System.exit(0);<br />
                }<br />
            }<br />
        });<br />
        parentFrame.getContentPane().setLayout(new GridLayout(numberOfPanels, 1));<br />
        for (int i = 0; i < numberOfPanels; i++) {<br />
            JPanel p = new GradientJPanel();<br />
            //Every even component is Opaque.<br />
            if (i % 2 == 0) {<br />
                p.setOpaque(false);<br />
            }<br />
            parentFrame.getContentPane().add(p);<br />
        }<br />
        parentFrame.pack();<br />
        parentFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);<br />
        parentFrame.setVisible(true);<br />
    }<br />
}<br />

Any suggestions for making the code more efficient, or
prevent the JFrame's background from being repainted?
Thanks.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
d_bleyl
Offline
Joined: 2003-07-15
Points: 0

This is an AWT issue, and the fix is as simple as setting
a System property:
System.setProperty("sun.awt.noerasebackground", "true");
Credit where credit is due:
http://www.javalobby.com/forums/thread.jspa?threadID=15846&tstart=0