JDK-4135445 : printAll() doesn't work on inner Swing containers
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.1.5,1.2.0
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic,windows_95,windows_nt
  • CPU: generic,x86
  • Submitted: 1998-05-05
  • Updated: 1999-03-15
  • Resolved: 1999-03-15
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description

Name: rk38400			Date: 05/05/98


I can use printAll() to print the text of a Label
object or the contents of a Panel object 
contained in an AWT Frame object.

I cannot use printAll() to print the text of a
JLabel object or the contents of a JPanel 
object contained in a Swing JFrame object.

I can use printAll() to print the contents of a 
JFrame object but the print quality is much poorer
than when printing the contents of a similar
Frame object using similar code.

When printAll() is used to print the contents of
a Frame object, only the contents of the Frame are
printed.  

When printAll() is used to print the
contents of a JFrame object, an attempt is made
to print the JFrame object in addition to its 
contents.  The border and the banner show up (with
no buttons or text in the banner) I'm not certain
which is correct, but I believe that the JFrame
container is not supposed to be rendered to the
printer, only its contents.

It appears that printAll() cannot be used to 
print the contents of a Swing container that is
placed inside of another container.

When the contents of a JLabel or a JPanel refuse
to print, there are no error messages.  The image
simply isn't rendered onto the printer, and 
doesn't appear to flow through the Win95 print 
queue unless it happens so fast that it cannot be
seen.

I am including three simple programs that can be
used to illustrate the difference in behavior
between the AWT and Swing in this regard.

The AWT version works as expected.  Neither of the
Swing versions work the way I expect them to work.

Each program has two modes, selected by using
comment indicators to enable and disable one of
two printAll() statements in the program and then
recompiling.

Instructions for using the three programs to
illustrate the problem are provided in the 
comments at the beginning of the first program.

##################################################
/**********************************************************
File TestAwtPrint.java
The purpose of this program is to provide a test vehicle
that can be used to compare AWT and Swing 1.0.1 insofar
as the printAll() method is concerned.

This is the AWT version and is the first of three
programs designed to illustrate the nature of the problem.

The programs named TestSwingPrint and TestSwingPanelPrint
are comparable Swing 1.0.1 versions of this program.

By using comment indicators, two different printAll()
statements can each be enabled or disabled.  When one of
the statement is enabled, the entire contents of the Frame
or JFrame object are printed.  When the other statement is
enabled, only the Label or JLabel object (or in one case a
JPanel object) is printed.

For the AWT version, both printAll methods work as 
expected with a reasonable rendering on a Cannon BJC 4000
printer operating in black and white mode.

For both Swing programs, only the printAll() method that
prints the entire JFrame renders anything on the paper.
Furthermore, for the Swing program that contains a JLabel
and a JButton, the rendering on the same Cannon printer is
poor that the word Hello in the JLabel isn't even
readable.  

For the Swing programs that attempt to print only the 
JLabel in one case and the JPanel in the other case,
nothing is rendered onto the paper. There is no error, and
no visible indication that anything is actually entered
into the Win95 print queue.  In other words, the attempt
to print the Swing JLabel in one program and the JPane
in the other program appears to be completely ignored.

Another interesting difference is that in the case of
Swing where the JFrame is specified as the container to
print, an attempt is made to render the entire container
on the paper, including the border and the banner at the
top (without buttons or title).  In the AWT case, only
the contents of the client area of the Frame are rendered
onto the paper.

These programs were tested using JDK 1.1.6 and Swing 1.0.1
under Win95
**********************************************************/
import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 
import com.sun.java.swing.*;

public class TestAwtPrint extends Frame implements ActionListener{
  Label theLabel;

  public static void main(String[] argc){
    TestAwtPrint T=new TestAwtPrint();
    T.setSize(new Dimension(200,200));
    T.setVisible(true);
  }//end main()
  //-----------------------------------------------------//

  public TestAwtPrint(){//constructor
    this.setTitle("Printer Test");
    this.setLayout( new FlowLayout());
    theLabel = new Label("Hello!");
    this.add(theLabel);
    Button b=new Button("Print");
    b.addActionListener(this);
    this.add(b);
  }//end constructor
  //-----------------------------------------------------//

  public void actionPerformed(ActionEvent e){
    String com=e.getActionCommand();
      if (com.equals("Print")){
      PrintJob pj= getToolkit().getPrintJob(this,"Test!",
                                         new Properties());
      Graphics g=pj.getGraphics(); 

      //By moving the comment indicator, one or the other of
      // the two following statements can be enabled as 
      // described in the comments at the beginning of the
      // program.
//      theLabel.printAll(g);
      printAll(g);

      g.dispose();
      pj.end();
    }//end if
  }//end actionPerformed()
}//end class TestAwtPrint
################################################

/**********************************************************
File TestSwingPrint.java
This is one of three programs designed to provide a test 
vehicle that can be used to compare AWT and Swing 1.0.1 
insofar as the printAll() method is concerned.

The other two programs are named TestAwtPrint and 
TestSwingPanelPrint.

See the comments in the program named TestAwtPrint for an
overall description of the manner in which these three
programs can be used to illustrate a printing problem
in Swing 1.0.1.

These programs were tested using JDK 1.1.6 and Swing 1.0.1
under Win95
**********************************************************/
import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 
import com.sun.java.swing.*;

public class TestSwingPrint extends JFrame 
                                 implements ActionListener{
  JLabel theLabel;

  public static void main(String[] argc){
    TestSwingPrint T=new TestSwingPrint();
    T.setSize(new Dimension(200,200));
    T.setVisible(true);
  }//end main()
  //-----------------------------------------------------//

  public TestSwingPrint(){//constructor
    this.setTitle("Printer Test");
    this.getContentPane().setLayout( new FlowLayout());
    theLabel = new JLabel("Hello!");
    this.getContentPane().add(theLabel);
    JButton b=new JButton("Print");
    b.addActionListener(this);
    this.getContentPane().add(b);
  }//end constructor
  //-----------------------------------------------------//

  public void actionPerformed(ActionEvent e){
    String com=e.getActionCommand();
      if (com.equals("Print")){
      PrintJob pj= getToolkit().getPrintJob(this,"Test!",
                                         new Properties());
      Graphics g=pj.getGraphics(); 

      //By moving the comment indicator, one or the other of
      // the two following statements can be enabled as 
      // described in the comments at the beginning of the
      // program.
//      theLabel.printAll(g);
      printAll(g);

      g.dispose();
      pj.end();
    }//end if
  }//end actionPerformed()
}//end class TestSwingPrint
#################################################

/**********************************************************
File TestSwingPanelPrint.java
This is one of three programs designed to provide a test 
vehicle that can be used to compare AWT and Swing 1.0.1 
insofar as the printAll() method is concerned.

The other two programs are named TestAwtPrint and 
TestSwingPrint.

See the comments in the program named TestAwtPrint for an
overall description of the manner in which these three
programs can be used to illustrate a printing problem
in Swing 1.0.1.

These programs were tested using JDK 1.1.6 and Swing 1.0.1
under Win95
**********************************************************/
import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 
import com.sun.java.swing.*;

public class TestSwingPanelPrint extends JFrame 
                                 implements ActionListener{
  JPanel thePanel;

  public static void main(String[] argc){
    TestSwingPanelPrint T=new TestSwingPanelPrint();
    T.setSize(new Dimension(200,200));
    T.setVisible(true);
  }//end main()
  //-----------------------------------------------------//

  public TestSwingPanelPrint(){//constructor
    this.setTitle("Printer Test");
    this.getContentPane().setLayout( new FlowLayout());
    thePanel = new JPanel();
    thePanel.add(new JButton("One"));
    thePanel.add(new JButton("Two"));
    thePanel.add(new JButton("Three"));
    thePanel.setBackground(Color.yellow);
    this.getContentPane().add(thePanel);
    JButton b=new JButton("Print");
    b.addActionListener(this);
    this.getContentPane().add(b);
  }//end constructor
  //-----------------------------------------------------//

  public void actionPerformed(ActionEvent e){
    String com=e.getActionCommand();
      if (com.equals("Print")){
      PrintJob pj= getToolkit().getPrintJob(this,"Test!",
                                         new Properties());
      Graphics g=pj.getGraphics(); 

      //By moving the comment indicator, one or the other of
      // the two following statements can be enabled as 
      // described in the comments at the beginning of the
      // program.
      thePanel.printAll(g);
//      printAll(g);

      g.dispose();
      pj.end();
    }//end if
  }//end actionPerformed()
}//end class TestSwingPanelPrint
#################################################

-the end-
(Review ID: 29746)
======================================================================

Comments
WORK AROUND Name: rk38400 Date: 05/05/98 I'm not aware of a workaround. ======================================================================
11-06-2004

EVALUATION Most of the problems documented in this bug report have been fixed in 1.1.7 and 1.2fcs. See BugId 4155884. The third test case still throws a NullPointerException during printing: Exception occurred during event dispatching: java.lang.NullPointerException at javax.swing.JComponent.paint(JComponent.java:472) at java.awt.Component.print(Component.java:1941) at java.awt.Container.print(Container.java:810) at java.awt.Component.lightweightPrint(Component.java:1981) at java.awt.Container.lightweightPrint(Container.java:928) at java.awt.Component.printAll(Component.java:1963) at TestSwingPanelPrint.actionPerformed(TestSwingPanelPrint.java:43) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1066) at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(AbstractButton.java:1101) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:378) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:250) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:217) at java.awt.Component.processMouseEvent(Component.java:3126) at java.awt.Component.processEvent(Component.java:2965) at java.awt.Container.processEvent(Container.java:987) at java.awt.Component.dispatchEventImpl(Component.java:2376) at java.awt.Container.dispatchEventImpl(Container.java:1032) at java.awt.Component.dispatchEvent(Component.java:2289) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:1942) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:1732) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:1645) at java.awt.Container.dispatchEventImpl(Container.java:1019) at java.awt.Window.dispatchEventImpl(Window.java:678) at java.awt.Component.dispatchEvent(Component.java:2289) at java.awt.EventQueue.dispatchEvent(EventQueue.java:258) at java.awt.EventDispatchThread.run(EventDispatchThread.java:68) This exception is thrown because JComponent.paint(Graphics) does not gracefully handle a null clipping rectangle. david.mendenhall@eng 1998-09-16 We have tracked down the remaining problem to a minor issue in Component.java. Closing as duplicate of 4212564, which is fixed in 1.2.1. david.mendenhall@eng 1999-03-15
16-09-1998