JDK-4708924 : REGRESSION:IllegalStateException:constrain(xywh) not supp. for complex transform
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.0,1.4.1,1.4.2
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris_8,windows_2000,windows_xp
  • CPU: x86,sparc
  • Submitted: 2002-06-27
  • Updated: 2003-07-29
  • Resolved: 2003-07-29
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.
Other
1.4.2_02 02Fixed
Description

Name: rmT116609			Date: 06/27/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

and

java version "1.4.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-beta-b14)
Java HotSpot(TM) Client VM (build 1.4.1-beta-b14, mixed mode)

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]

EXTRA RELEVANT SYSTEM CONFIGURATION :
nVidia GeForce2 Integerated GPU Bios version 3.1A.01.01.06

DESCRIPTION OF THE PROBLEM :
I cannot successfully call paintComponent(g) on a object extended from JPanel with some imbeded components to a graphics context obtained from a BufferedImage. This used to work on JDK 1.3.1

REGRESSION.  Last worked in version 1.3.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.javac ShowBug.java
2.java ShowBug


ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalStateException: constrain(xywh) is not supported for complex
transform.

	at sun.java2d.SunGraphics2D.constrain(SunGraphics2D.java:287)

	at sun.awt.SunGraphicsCallback.constrainGraphics
(SunGraphicsCallback.java:25)

	at sun.awt.SunGraphicsCallback.runOneComponent
(SunGraphicsCallback.java:51)

	at sun.awt.SunGraphicsCallback.runComponents
(SunGraphicsCallback.java:90)

	at java.awt.Container.printComponents(Container.java:1227)

	at ShowBug.generateImage(ShowBug.java:67)

	at ShowBug.generateImage(ShowBug.java:85)

	at ShowBug.main(ShowBug.java:47)



REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import java.awt.image.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;
import java.beans.*;

public class ShowBug {
  Frame frame = new Frame();
  Window window = new Window(frame);

  public ShowBug() {
    window.setBounds(0,0,0,0);
  }
  public static void main(String[] args) {
    class SomeClass extends JPanel{
      JButton jButton = new JButton();

      public SomeClass() {
        try {
          jbInit();
        }
        catch(Exception e) {
          e.printStackTrace();
        }
      }
      private void jbInit() throws Exception {
        this.setLayout(null);
        jButton.setText("Some button");
        jButton.setBounds(new Rectangle(10, 10, 111, 27));
        this.add(jButton, null);
      }
    }
    JPanel print = new SomeClass();
    new ShowBug().generateImage(print);
    System.exit(0);
  }

  public void generateImage(JPanel report, OutputStream outStream){
    float aspectRatio = 4f / 3f;
    double detailFactor = 3d;
    int width = (int)(600 * detailFactor);
    int height = (int)(width * aspectRatio);

    report.setBounds(0,0,width,height);
    try {
      BufferedImage image = new BufferedImage
(width,height,BufferedImage.TYPE_BYTE_BINARY);
      Graphics2D g = (Graphics2D)image.getGraphics();

      g.fillRect(0,0,width,height);
      g.scale(detailFactor,detailFactor);
      synchronized(window){
        window.add(report);
        window.show();
        report.printComponents(g);
        window.hide();
        window.remove(report);
      }

      //Add JAI and uncomment the following line to view image
      //javax.media.jai.TiledImage tiledImage = new javax.media.jai.TiledImage
(image,false);
      //javax.media.jai.JAI.create("encode",tiledImage,outStream,"PNG",null);
    }catch (Exception ex){
      ex.printStackTrace();
    }
  }

  public void generateImage(JPanel report){
    FileOutputStream outStream = null;
    String fileName = null;
    try {
      fileName = "Test.png";
      outStream = new FileOutputStream(fileName);
      generateImage(report,outStream);
    }catch (Exception ex){
      ex.printStackTrace();
    }finally{
      try {if (outStream != null)outStream.close();}catch (Exception ex) {}
    }
  }
}
---------- END SOURCE ----------

Release Regression From : 1.3.1_04
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

(Review ID: 158556) 
======================================================================

Name: jk109818			Date: 07/15/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

also tested under

java version "1.4.1-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-beta-b14)
Java HotSpot(TM) Client VM (build 1.4.1-beta-b14, mixed mode)


FULL OPERATING SYSTEM VERSION :
Microsoft Windows XP [Version 5.1.2600]


A DESCRIPTION OF THE PROBLEM :
When trying to paint a Compount Component (i.e. a Component
derived from Container that holds another component) in a
scaled graphics2D context, the following error occurs:

java.lang.IllegalStateException: constrain(xywh) is not
supported for complex tr
ansform.
        at sun.java2d.SunGraphics2D.constrain
(SunGraphics2D.java:295)
        
And painting is stopped.

REGRESSION.  Last worked in version 1.3.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a class derived from Frame.
2. Override its paint method to scale the graphics context:
3. Create a simple compound component
4. add the compound component to the Frame
5. compile and run.

EXPECTED VERSUS ACTUAL BEHAVIOR :
The compound component is painted correctly (scaled) under
1.3 & 1.3.1 but causes an exception under 1.4 & 1.4.1



ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalStateException: constrain(xywh) is not supported for complex tr
ansform.
        at sun.java2d.SunGraphics2D.constrain(SunGraphics2D.java:295)
        at sun.awt.SunGraphicsCallback.constrainGraphics(SunGraphicsCallback.jav
a:25)
        at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:
51)
        at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97
)
        at java.awt.Container.paint(Container.java:1309)
        at Scale.paint(JFrame1.java:61)
        at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)

        at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:
60)
        at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97
)
        at java.awt.Container.paint(Container.java:1309)
        at sun.awt.RepaintArea.paint(RepaintArea.java:177)
        at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:260)
        at java.awt.Component.dispatchEventImpl(Component.java:3658)
        at java.awt.Container.dispatchEventImpl(Container.java:1623)
        at java.awt.Window.dispatchEventImpl(Window.java:1585)
        at java.awt.Component.dispatchEvent(Component.java:3439)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:450)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchTh
read.java:197)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:150)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144)

        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136)

        at java.awt.EventDispatchThread.run(EventDispatchThread.java:99)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;


public class JFrame1 extends Frame
{
	public JFrame1()
	{
		setLayout(null);
		setSize(640,480);
		setVisible(false);

        Component c = new TestContainer();
        c.setSize(c.getPreferredSize());
        c.setLocation(100,100);

        add(c);
		this.addWindowListener( new java.awt.event.WindowAdapter() {
		    public void windowClosing(java.awt.event.WindowEvent event)
{
		        System.exit(0);            // close the application
		    }
	    });
    }

	static public void main(String args[])
	{
		try {
			(new JFrame1()).setVisible(true);
		}
		catch (Throwable t) {
			t.printStackTrace();
			System.exit(1);
		}
	}

    public void paint(Graphics g) {
        ((Graphics2D)g).setRenderingHint
(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        ((Graphics2D)g).scale(0.8,0.8);
        super.paint(g);
    }
}


class TestContainer extends Container
{
    public TestContainer()
    {
        setLayout(new BorderLayout());
        setBackground(Color.lightGray);
        add(new SimpleComponent(), "Center");
    }

    public Dimension getPreferredSize()
    {
        return new Dimension(404, 210);
    }

} 

class SimpleComponent extends Component
{
    public void paint(Graphics g) {
        Dimension sz = getSize();
        g.setColor(new Color(34,234,179));
        g.fill3DRect(0, 0, sz.width-1,sz.height-1, true);
    }
}



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

CUSTOMER WORKAROUND :
Continue using version 1.3.1 as this defect renders or
product un-usable.
(Review ID: 159089)
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.4.2_02 tiger FIXED IN: 1.4.2_02 tiger INTEGRATED IN: 1.4.2_02 tiger tiger-b13
14-06-2004

EVALUATION Based on the synopsis, I'm going to let 2D take the first cut at this. ###@###.### 2002-06-27 Fix for tiger. ###@###.### 2002-06-27 Fujitsu ran into this issue today while porting their app to JDk 1.4.2 from 1.3.1. Can someone please evaluate it and see if there are any workarounds? I will also file an escalation ###@###.### 2003-07-07 The problem here is that we used to have an implementation which basically assumed that the coordinate system was unscaled. This was discovered when we were fixing a bug in the handling of the constrained coordinate system and so code was added to specifically check the transform and reject those cases. Such a transform would not normally occur during the internal processing of trees of lightweight components in the system, unless the developer did something explicit, such as installing a complex transform as in the test case. The handling of complex transforms was discovered to be so broken that only the most minimal and basic operation would do anything resembling what the caller might expect. In particular, I think that the usage provided in the test case was one of the rare circumstances where the method managed to work accidentally by just ignoring the transform, but even slight modifications to the component layout would cause the case to break seriously. Furthermore, we never documented that trees of lightweight components should be able to render under a complex transform that was not mapped 1:1 coordinates to pixels. When we discovered how broken the handling of the constrain method was in the face of a complex transform we decided to block such operations since they were never explicitly supported. We would like to eventually be able to render all components under all varieties of transforms, but such support would require some major changes to the handling of the interactions between the device, constraint, and user clips in the rendering pipelines and such an operation was never feasible given the available engineering resources. We do hope to get to this in the Tiger time frame as more and more of the implementation is generalized to the point where it can handle such complicated clip combinations. ###@###.### 2003-07-09 A quick fix would be to implement the workaround code that the callers use when a Graphics does not implement the Constrainable extensions instead of throwing an exception when there is a transform. The workaround code does not attempt to enforce the resulting constraint clip, and it does not adjust the coordinate system based on the constrained location on the window or drawable, but at least it lets well-behaved components continue with roughly the same output that would be normally expected under 1.3.1. A later fix could reestablish the enforeability of the constraint clip by doing a better job of factoring the new bounds into the existing clip and coordinate origin constraint variables. ###@###.### 2003-07-18
18-07-2003