JDK-4678208 : single pixel polygons are not drawn
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2002-05-01
  • Updated: 2008-11-05
  • Resolved: 2002-10-16
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 mantisFixed
Related Reports
Relates :  
Relates :  
Description

Name: gm110360			Date: 05/01/2002


FULL PRODUCT VERSION :
FAILS:
 Java Plug-in (under IE 5.50 )
 > 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)

WORKS:
 Java Plug-in (under IE 5.50 )
 > java version "1.3.1"
 > Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
 > Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)



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


ADDITIONAL OPERATING SYSTEMS :
Windows NT 4.0



EXTRA RELEVANT SYSTEM CONFIGURATION :
Appears on varying combinations of video hardware, across
Windows 2000/NT4 (others untested).  Fails consistantly on
these video cards: Matrox Millenium 200, ATI Rage Pro.
Fails intermittently on: ATI Radeon DDR 32 M.

A DESCRIPTION OF THE PROBLEM :
A class extending JButton overrides the paint( Graphics g )
method.  It properly calls the superconstructor, then makes
graphics calls to draw additional features to the button.

Under the latest 1.4 release, the button always takes on a
default appearance, despite the added calls in paint().

REGRESSION.  Last worked in version 1.3.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Override JButton (see source example)
2. Add to a JPanel with null layout manager, position
manually.
3. Display JPanel as part of a JApplet, view in the Plug-
in, inside MSIE.

EXPECTED VERSUS ACTUAL BEHAVIOR :
The expected result is that graphics calls made on the
Graphics object passed into the paint method would be drawn
to screen, as in previous versions of java.  Though the
calls are clearly made (because debug that is in-line with
the draw() calls is always printed), there is no on-screen
representation that they ever occurred.

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
<---- START SOURCE FOR OVERRIDDEN JButton WIDGET ---->
import java.awt.*;
import javax.swing.*;

public class JButtonWithArrow extends JButton {

    public JButtonWithArrow() {
        super();
    } // of constructor

    public JButtonWithArrow( String s ) {
        super( s );
    } // of constructor

    public JButtonWithArrow( String s, Icon i ) {
        super( s, i );
    } // of constructor

    public void paint( Graphics g ) {

        super.paint(g);

        int width = this.getBounds().width;
        int height = this.getBounds().height;
        int verticalCenter = height/2;

        Graphics2D g2d = (Graphics2D)(g);

        g2d.setPaint( Color.black );

        int[] arrowPointsX = new int[25];
        int[] arrowPointsY = new int[25];

        int i=0;

        for( i=0; i<=8; i++ ) {
            arrowPointsX[i] = width-(14-i);
            arrowPointsY[i] = verticalCenter-2;
        } // of for

        for( i=9; i<=15; i++ ) {
            arrowPointsX[i] = width-((14+8)-i);
            arrowPointsY[i] = verticalCenter-1;
        } // of for

        for( i=16; i<=20; i++ ) {
            arrowPointsX[i] = width-((21+7)-i);
            arrowPointsY[i] = verticalCenter;
        } // of for

        for( i=21; i<=23; i++ ) {
            arrowPointsX[i] = width-((26+6)-i);
            arrowPointsY[i] = verticalCenter+1;
        } // of for

        for( i=24; i<=24; i++ ) {
            arrowPointsX[i] = width-((29+5)-i);
            arrowPointsY[i] = verticalCenter+2;
        } // of for

        for( i=0; i<arrowPointsX.length; i++ ) {
            g2d.draw( new Rectangle( arrowPointsX[i], arrowPointsY[i], 0, 0 ) );
            System.out.println( "drawing at [" +
                                arrowPointsX[i] +
                                "," +
                                arrowPointsY[i] +
                                 "]" );
        } // of for

    } // of paint()

} // of class JButtonWithArrow
<---- END ---->

<---- START SOURCE FOR SIMPLE JApplet TO DEMONSTRATE ---->
import javax.swing.*;

import java.awt.*;

public class TestApplet extends JApplet {

    private int appletW;
    private int appletH;

    private JPanel blackPanel;

    protected JButtonWithArrow b1,
                               b2,
                               b3,
                               b4;

    public void init() {

        appletW = this.getBounds().width;
        appletH = this.getBounds().height;

        blackPanel = new JPanel();
        blackPanel.setLayout( null );
        blackPanel.setBounds( 5, 5, appletW-10, appletH-10 );
        blackPanel.setBackground( Color.black );

        this.getContentPane().setLayout( null );
        this.getContentPane().add( blackPanel );

        b1 = new JButtonWithArrow();
        b1.setBounds( 5, 5, 50, 25 );

        b2 = new JButtonWithArrow();
        b2.setBounds( 5, 35, 100, 25 );

        b3 = new JButtonWithArrow();
        b3.setBounds( 5, 65, 50, 40 );

        b4 = new JButtonWithArrow();
        b4.setBounds( 5, 110, 100, 40 );

        blackPanel.add( b1 );
        blackPanel.add( b2 );
        blackPanel.add( b3 );
        blackPanel.add( b4 );

    } // of init()

} // of class TestApplet
<---- END ---->
---------- END SOURCE ----------

CUSTOMER WORKAROUND :
Use JRE/JSDK 1.3.1 Plug-In

Release Regression From : 1.3.1_03
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: 143158) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis FIXED IN: mantis INTEGRATED IN: mantis mantis-b04
14-06-2004

EVALUATION First off, the developer should be overriding paintComponent rather than paint. However, I have determined that this is unrelated as the problem occurs regardless of which method is overridden. I have narrowed it down to an issue with Graphics2D.draw(Shape) when given a rectangle such as Rectangle(x, y, 0, 0). It seems that in 1.3.1 this actually put a pixel on the screen. When I tested on my machine with 1.4.0 it did not. According to the bug report, it sounds like it depends on the graphics card. I have not confirmed this. Note that if the call to draw in this test case is instead passed a Rectangle such as Rectangle(x, y, 1, 1) everything works fine. Lastly, to save some trouble, please note that this does not require the plugin to reproduce. The problem exists when run under appletviewer or even if the example is turned into a stand-alone app. Re-assigning to Java2D. ###@###.### 2002-05-02 This happens on any Windows framebuffer which uses GDI to render polygons and any framebuffer which uses local memory images for the Swing back buffer allocations (including many X11 framebuffers on Solaris). The problem lies in trying to draw a Shape that consists of multiple segments that all have the same vertices. Our software renderer tries to eliminate the duplicate stores at the shared vertex coordinates (this is mainly a bug fix to prevent the vertices from "dropping out" in XOR mode, but it can help boost non-XOR performance by avoiding the extra memory accesses). Unfortunately, when all the vertices are the same, it never decides to actually draw anything. This will have to be looked into for some better logic as to when to avoid the extra store. The GDI renderer suffers from GDI's rule that it doesn't draw the last pixel in a path when you call ::StrokePath(). We have some logic in there to make sure an extra segment is appended to the path to ensure that this last pixel is drawn, but that logic also seems to fail when all the vertices are the same (mainly because it decides that the figure is already closed so the last pixel was drawn by the first edge - this fails when the first edge didn't draw anything either). ###@###.### 2002-08-28 A regression in draw/fillPolygon on Windows was caused by the fix for this bug. See 4770290 for more information and the associated fix. ###@###.### 2002-10-29
28-08-2002