JDK-6689025 : Graphics2D.setPaint() doesn't work if transform has changed but paint hasn't
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6u10
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-04-15
  • Updated: 2010-04-02
  • Resolved: 2008-04-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u10 b23Fixed 7Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_10-beta"
Java(TM) SE Runtime Environment (build 1.6.0_10-beta-b21)
Java HotSpot(TM) Client VM (build 11.0-b11, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
When painting with a gradient paint, which of course is sensitive to the painting coordinates, resetting the paint to the same LinearGradientPaint object after changes to the transform does not properly update the painting coordinates of the gradient.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run the test case provided on 6u4 vs 6u10

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Teh red edges in the test case should always paint
ACTUAL -
The gradient location is not updated with the new transform coordinates so the painted area is not properly filled.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/*
 * Demonstrates bug in setPaint with transform changes
 */
package painttransformtest;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.Paint;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.UIManager;

/**
 *
 * @author scott.palmer
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                JFrame f = new JFrame("Paint Transform Test");
                f.getContentPane().add(new Widget());
                f.setSize(200, 200);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setVisible(true);
            }
        });

    }

    static class Widget extends JComponent {
        private int cellHeight = 10;
        private int cellWidth = 22;

        Paint gradient;
        
        public Widget() {
        gradient = new LinearGradientPaint(0, 0, 0, 9,
                new float[]{0.3f, 0.7692f},
                new Color[]{Color.RED, UIManager.getColor("Panel.background")});
        }

        
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(cellWidth, 100);
        }

        @Override
        protected void paintComponent(Graphics g1) {
            Graphics2D g = (Graphics2D) g1;
                    int cellSpacing = cellHeight + 1;
        int h = getHeight();
        int cw = cellWidth - 2;
        int ch = cellHeight - 1;
        int cells = (h + 1) / cellSpacing;

            for (int i = 0; i < cells; i++) {
                // paint edge - first time will paint, the rest will look blank
                // I assuem because the gradient doesn't get translated
                g.translate(0, i * cellSpacing);
                g.setPaint(gradient);
                g.drawRoundRect(1, 0, cw, ch, 3, 5);
                g.translate(0, -i * cellSpacing);
                // could put More painting here
                // if we change the paint the above gradients will paint for the next
                // interation of the loop - presumably because the paint changes
                // the gradient will be properly translated
                if (i > cells/2) {
                    g.setPaint(Color.GREEN);
                    g.fillRoundRect(1, 1+i * cellSpacing, cw, ch, 3, 5);
                }
            }
        }
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
change the paint to something different after the transform has changed, then back again.

Release Regression From : 6u4
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Release Regression From : 6u4
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Comments
SUGGESTED FIX http://sa.sfbay.sun.com/projects/java2d_data/6u10/6689025.0
18-04-2008

EVALUATION We have an optimization where we don't update the paint unless it's changed. But in the case when the tx is changed we do need to update it.
15-04-2008