JDK-4673221 : printDialog freezes when handling large list of printers in java 1.4
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.0,1.4.0,1.4.1
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,solaris_7
  • CPU: generic,sparc
  • Submitted: 2002-04-23
  • Updated: 2004-09-20
  • Resolved: 2004-09-20
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
Duplicate :  
Relates :  
Relates :  
Description
printDialog freezes when handling large list of printers in java 1.4, solaris 7.
When I do an lpstat -a, it lists over 700 printers.  So the bug is that the print dialog box for JDK 1.4 can't handle large number of printers.  It should truncate the results or allow users to put a wildcard specification to narrow the search results.
If I create a .printers file in my home directory with say, 5 printers,
then it doesn't hang.  It just doesn't seem to like large printer
lists.  However, defining the .printers file is not something that most
users know how to do given its bizarre syntax.  The lpconfig command is
not much easier either and can only be run as root.

The following example code from the Java2D tutorial exhibits this problem

http://java.sun.com/docs/books/tutorial/2d/printing/example-1dot2/ShapesPrint.java
import java.awt.geom.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.print.PrinterJob;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.awt.print.*;

public class ShapesPrint extends JPanel implements Printable, ActionListener {

    
    final static Color bg = Color.white;
    final static Color fg = Color.black;
    final static Color red = Color.red; 
    final static Color white = Color.white;

    final static BasicStroke stroke = new BasicStroke(2.0f);
    final static BasicStroke wideStroke = new BasicStroke(8.0f);
    
    final static float dash1[] = {10.0f};
    final static BasicStroke dashed = new BasicStroke(1.0f,
                                                      BasicStroke.CAP_BUTT,
                                                      BasicStroke.JOIN_MITER,
                                                      10.0f, dash1, 0.0f);
    final static JButton button = new JButton("Print");

    public ShapesPrint() {
	setBackground(bg);
        button.addActionListener(this);
    }


   public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof JButton) {   
        PrinterJob printJob = PrinterJob.getPrinterJob();
        printJob.setPrintable(this);
        if (printJob.printDialog()) {
            try {
                printJob.print();  
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
	}
}
    public void paintComponent(Graphics g) {
	super.paintComponent(g);
	Graphics2D g2 = (Graphics2D) g;
	drawShapes(g2);
}
public void drawShapes(Graphics2D g2){
        Dimension d = getSize();
        int gridWidth = 400 / 6;
        int gridHeight = 300 / 2;
         
        int rowspacing = 5;
        int columnspacing = 7;
        int rectWidth = gridWidth - columnspacing;
        int rectHeight = gridHeight - rowspacing;

        Color fg3D = Color.lightGray;
    
        g2.setPaint(fg3D);
        g2.drawRect(80, 80, 400 - 1, 310);
        g2.setPaint(fg);
         
        int x = 85;
        int y = 87;

        
        // draw Line2D.Double
        g2.draw(new Line2D.Double(x, y+rectHeight-1, x + rectWidth, y));
        x += gridWidth;
        
        // draw Rectangle2D.Double
        g2.setStroke(stroke);
        g2.draw(new Rectangle2D.Double(x, y, rectWidth, rectHeight));
        x += gridWidth;
        
        // draw  RoundRectangle2D.Double
        g2.setStroke(dashed);
        g2.draw(new RoundRectangle2D.Double(x, y, rectWidth,
                                            rectHeight, 10, 10));
        x += gridWidth;
       
        // draw Arc2D.Double
        g2.setStroke(wideStroke);
        g2.draw(new Arc2D.Double(x, y, rectWidth, rectHeight, 90,
                                 135, Arc2D.OPEN));
        x += gridWidth;
                                            
        // draw Ellipse2D.Double
        g2.setStroke(stroke);

        g2.draw(new Ellipse2D.Double(x, y, rectWidth, rectHeight));
        x += gridWidth;
        
        // draw GeneralPath (polygon)
        int x1Points[] = {x, x+rectWidth, x, x+rectWidth};
        int y1Points[] = {y, y+rectHeight, y+rectHeight, y};
        GeneralPath polygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD,
                                              x1Points.length);
        polygon.moveTo(x1Points[0], y1Points[0]);
        for ( int index = 1; index <x1Points.length; index++ ) {  
            polygon.lineTo(x1Points[index], y1Points[index]);
        };
        polygon.closePath();
        
        g2.draw(polygon);
        
        // NEW ROW
        x = 85;
       y += gridHeight;
          
        // draw GeneralPath (polyline)
        
        int x2Points[] = {x, x+rectWidth, x, x+rectWidth};
        int y2Points[] = {y, y+rectHeight, y+rectHeight, y};
        GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD,
                                               x2Points.length);
        polyline.moveTo (x2Points[0], y2Points[0]);
       for ( int index = 1; index < x2Points.length; index++ ) {
            polyline.lineTo(x2Points[index], y2Points[index]);
        };
        
        g2.draw(polyline);
        x += gridWidth;
        
        // fill Rectangle2D.Double (red)
        g2.setPaint(red);
        g2.fill(new Rectangle2D.Double(x, y, rectWidth, rectHeight));
        g2.setPaint(fg);
        x += gridWidth;
        
        // fill RoundRectangle2D.Double
        GradientPaint redtowhite = new GradientPaint(x,y,red,x+rectWidth, y,white);
        g2.setPaint(redtowhite);
        g2.fill(new RoundRectangle2D.Double(x, y, rectWidth,
                                            rectHeight, 10, 10));
        g2.setPaint(fg);
        x += gridWidth;
        
        // fill Arc2D
        g2.setPaint(red);
        g2.fill(new Arc2D.Double(x, y, rectWidth, rectHeight, 90,
                                 135, Arc2D.OPEN));
        g2.setPaint(fg);
        x += gridWidth; 
        
        // fill Ellipse2D.Double
        redtowhite = new GradientPaint(x,y,red,x+rectWidth, y,white);
        g2.setPaint(redtowhite);
        g2.fill (new Ellipse2D.Double(x, y, rectWidth, rectHeight));
        g2.setPaint(fg);
        x += gridWidth; 
        // fill and stroke GeneralPath
        int x3Points[] = {x, x+rectWidth, x, x+rectWidth};
        int y3Points[] = {y, y+rectHeight, y+rectHeight, y};
        GeneralPath filledPolygon = new GeneralPath(GeneralPath.WIND_EVEN_ODD,
                                                    x3Points.length);
        filledPolygon.moveTo(x3Points[0], y3Points[0]);
        for ( int index = 1; index < x3Points.length; index++ ) {
            filledPolygon.lineTo(x3Points[index], y3Points[index]);
        };
        filledPolygon.closePath();
        g2.setPaint(red);
        g2.fill(filledPolygon);
        g2.setPaint(fg);
        g2.draw(filledPolygon);
    }


    public int print(Graphics g, PageFormat pf, int pi) throws PrinterException {
        if (pi>= 1) {
            return Printable.NO_SUCH_PAGE;
	}
	drawShapes((Graphics2D) g);
        return Printable.PAGE_EXISTS;
    }
  
   public static void main(String s[]){
	WindowListener l = new WindowAdapter() {
		public void windowClosing(WindowEvent e) {System.exit(0);}
		public void windowClosed(WindowEvent e) {System.exit(0);}
	};
	JFrame f = new JFrame();
	f.addWindowListener(l);
	JPanel panel = new JPanel();
	panel.add(button);
	f.getContentPane().add(BorderLayout.SOUTH, panel);
	f.getContentPane().add(BorderLayout.CENTER, new ShapesPrint());
	f.setSize(580, 500);
	f.show();
    }

}


Name: vtR10009			Date: 06/11/2002


This bug causes failure of JCK tests:
api/javax_print/CancelablePrintJob/index.html#Cancel
api/javax_print/DocPrintJob/index.html#AttributeListener 
api/javax_print/DocPrintJob/index.html#Get
api/javax_print/DocPrintJob/index.html#JobListener
api/javax_print/PrintService/index.html#hashCode

======================================================================
###@###.### 2004-09-20

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis mantis-b02 FIXED IN: mantis mantis-b02 INTEGRATED IN: mantis mantis-b02 VERIFIED IN: 1.5.0_01
22-09-2004

WORK AROUND create a .printers file in the home directory with few printers, then it doesn't hang.
22-09-2004

EVALUATION Marking as incomplete - please attach stack dump. ###@###.### 2002-05-14 =================================== This is reproducible in the campus here in SCA if you remove your .printers file. lpstat will then list 1324 printers(!). The problem isn't exactly the number of printers however, its that the exec'd command to return the list of printers isn't exiting because it generates over 10Kbytes of output and waits for some of this to be read from the buffer before returning. Unfortunately the code in JDK that execs the command does a Process.waitFor and won't start reading the results until the command has exited. Experimentation showed 10240 bytes is the threshhold. The waitFor is reasonable in that JDK wants to make sure no printers are missed due to prematurely terminating reading from the stream, but its not working well in this case. Some experimentation is probably necessary to get the right behaviour. ###@###.### 2002-05-30 ============================ Fix is to redirect output to a file which is does not wait for some bytes to be read before exiting. ###@###.### 2002-07-10 ===================================
10-07-2002