| /* | |
| * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| import java.awt.Button; | |
| import java.awt.Canvas; | |
| import java.awt.Checkbox; | |
| import java.awt.Choice; | |
| import java.awt.Color; | |
| import java.awt.Component; | |
| import java.awt.Container; | |
| import java.awt.Dimension; | |
| import java.awt.FlowLayout; | |
| import java.awt.Font; | |
| import java.awt.Frame; | |
| import java.awt.Graphics; | |
| import java.awt.Insets; | |
| import java.awt.JobAttributes; | |
| import java.awt.Label; | |
| import java.awt.List; | |
| import java.awt.Menu; | |
| import java.awt.MenuBar; | |
| import java.awt.MenuItem; | |
| import java.awt.PageAttributes; | |
| import java.awt.Panel; | |
| import java.awt.PrintJob; | |
| import java.awt.Scrollbar; | |
| import java.awt.ScrollPane; | |
| import java.awt.TextArea; | |
| import java.awt.TextField; | |
| import java.awt.event.ActionEvent; | |
| import java.awt.event.ActionListener; | |
| import java.awt.event.WindowAdapter; | |
| import java.awt.event.WindowEvent; | |
| import java.awt.JobAttributes.DialogType; | |
| import java.awt.PageAttributes.OriginType; | |
| /* | |
| * @test | |
| * @bug 4111262 4035285 4038900 4046147 4049680 4084038 4100004 4105875 | |
| * @bug 4117502 4037486 4068433 4128031 4151161 4151707 4155884 4212564 | |
| * @bug 4025626 4029565 4034365 4036068 4040622 4061890 4067405 4086256 | |
| * @bug 4113827 4116722 4121984 4145350 4146510 4172659 4179886 4218471 | |
| * @bug 4219657 4227128 4242308 4245917 4265746 | |
| * @key printer | |
| * @library /java/awt/regtesthelpers | |
| * @build PassFailJFrame | |
| * @summary Test printing of lightweight (and heavyweight) components | |
| * @run main/manual PrintComponentTest | |
| */ | |
| public class PrintComponentTest { | |
| public static void main(String[] args) throws Exception { | |
| String INSTRUCTIONS = """ | |
| A frame window will appear. | |
| Choose 'Print to Printer...' from the 'Print' menu. Examine the output | |
| and verify that the frame and all the components in it get printed properly. | |
| Print using both 'Portrait' and 'Landscape' orientation. | |
| Verify that the paper dimensions printed to standard error | |
| are exactly inverted. | |
| (That is, if the output for 'Portrait' is | |
| "Dimensions: java.awt.Dimension[width=612,height=792]" then the output | |
| for 'Landscape' should be "Dimensions: java.awt.Dimension[width=792, height=612].) | |
| Now, attempt to print a second time. When the print dialog box appears, | |
| however, cancel the print request. | |
| Verify that _no_ output is sent to standard error. | |
| You should attempt to print with both the native and common print dialogs, | |
| as well as with no dialog. | |
| Note that on Linux the native and common print dialogs are identical. | |
| On Windows, the common print dialog communicates with the printer to | |
| determine supported paper sizes and duplex capability. | |
| Verify that these constraints are properly enforced in the common dialog | |
| for the target printer. | |
| Known problems: | |
| * The text in the second row of the menubar is not indented | |
| correctly. | |
| You can also use the 'Print to Screen...' command for a quick manual | |
| check that printing works, but this is only for debugging purposes."""; | |
| PassFailJFrame.builder() | |
| .title("PrintComponentTest Test Instructions") | |
| .instructions(INSTRUCTIONS) | |
| .rows((int) INSTRUCTIONS.lines().count() + 2) | |
| .columns(60) | |
| .testTimeOut(10) | |
| .testUI(new MainFrame()) | |
| .logArea(8) | |
| .build() | |
| .awaitAndCheck(); | |
| } | |
| } | |
| class MainFrame extends Frame { | |
| private LWContainer lwc; | |
| public MainFrame() { | |
| super("PrintComponentTest"); | |
| setSize(800, 400); | |
| setLayout(new FlowLayout()); | |
| // peered components | |
| Button button = new Button("Button"); | |
| button.setFont(new Font("Dialog", Font.PLAIN, 12)); | |
| add(button); | |
| add(new TestCanvas()); | |
| Checkbox cbox = new Checkbox("Checkbox", true); | |
| cbox.setFont(new Font("DialogInput", Font.PLAIN, 12)); | |
| add(cbox); | |
| Choice choice = new Choice(); | |
| choice.add("Choice 1"); | |
| choice.add("Choice Two"); | |
| choice.setFont(new Font("Monospaced", Font.PLAIN, 12)); | |
| add(choice); | |
| Label label = new Label("Label"); | |
| label.setFont(new Font("Serif", Font.PLAIN, 12)); | |
| add(label); | |
| List list = new List(); | |
| list.add("List 1"); | |
| list.add("List Two"); | |
| list.setFont(new Font("SansSerif", Font.PLAIN, 12)); | |
| add(list); | |
| add(new Scrollbar(Scrollbar.VERTICAL) ); | |
| add(new Scrollbar(Scrollbar.HORIZONTAL) ); | |
| ScrollPane scrollpane = new ScrollPane(); | |
| Button spButton = new Button("Button in a scrollpane"); | |
| spButton.setFont(new Font("Monospaced", Font.PLAIN, 12)); | |
| scrollpane.add(spButton); | |
| add(scrollpane); | |
| TextArea textarea = new TextArea("TextArea", 3, 30); | |
| textarea.setFont(new Font("Dialog", Font.ITALIC, 10)); | |
| add(textarea); | |
| TextField textfield = new TextField("TextField"); | |
| textfield.setFont(new Font("DialogInput", Font.ITALIC, 10)); | |
| add(textfield); | |
| // nested components | |
| Panel panel1 = new Panel(); | |
| panel1.setLayout(new FlowLayout()); | |
| panel1.setBackground(Color.red); | |
| this.add(panel1); | |
| Button p1Button = new Button("level 2"); | |
| p1Button.setFont(new Font("Monospaced", Font.ITALIC, 10)); | |
| panel1.add(p1Button); | |
| Panel panel2 = new Panel(); | |
| panel2.setLayout(new FlowLayout()); | |
| panel2.setBackground(Color.green); | |
| panel1.add(panel2); | |
| Button p2Button = new Button("level 3"); | |
| p2Button.setFont(new Font("Serif", Font.ITALIC, 10)); | |
| panel2.add(p2Button); | |
| // lightweight components | |
| LWButton lwbutton = new LWButton("LWbutton"); | |
| lwbutton.setFont(new Font("SansSerif", Font.ITALIC, 10)); | |
| add(lwbutton); | |
| lwc = new LWContainer("LWContainerLWContainerLWContainerLWContainerLWContainerLWContainerLWContainerLWContainerLWContainerLWContainerLWContainerLWContainerLWContainer"); | |
| lwc.setFont(new Font("Monospaced", Font.ITALIC, 10)); | |
| add(lwc); | |
| Button lwcButton1 = new Button("HW Button 1"); | |
| Button lwcButton2 = new Button("HW Button 2"); | |
| LWButton lwcButton3 = new LWButton("LW Button"); | |
| lwcButton1.setFont(new Font("Dialog", Font.BOLD, 14)); | |
| lwcButton2.setFont(new Font("DialogInput", Font.BOLD, 14)); | |
| lwcButton3.setFont(new Font("Monospaced", Font.BOLD, 14)); | |
| lwc.add(lwcButton1); | |
| lwc.add(lwcButton2); | |
| lwc.add(lwcButton3); | |
| // overlapping components | |
| add(new ZOrderPanel()); | |
| /////////////////////// | |
| Menu menu = new Menu("Print"); | |
| Menu menu2 = new Menu("File"); | |
| Menu menu3 = new Menu("Edit"); | |
| Menu menu4 = new Menu("ReallyReallyReallyReallyReallyReallyReallyReally" + | |
| "ReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReally" + | |
| "ReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyLong"); | |
| menu2.setFont(new Font("SansSerif", Font.BOLD, 20)); | |
| menu2.setEnabled(false); | |
| menu3.setFont(new Font("Monospaced", Font.ITALIC, 18)); | |
| menu3.setEnabled(false); | |
| menu4.setEnabled(false); | |
| MenuItem itemJFC = | |
| new MenuItem("Print to Printer with Cross-Platform Dialog..."); | |
| itemJFC.setActionCommand("common"); | |
| MenuItem itemNative = | |
| new MenuItem("Print to Printer with Native Dialog..."); | |
| itemNative.setActionCommand("native"); | |
| MenuItem itemBackground = | |
| new MenuItem("Print to Printer in Background"); | |
| itemBackground.setActionCommand("none"); | |
| MenuItem itemScreen = new MenuItem("Print to Screen..."); | |
| menu.add(itemJFC); | |
| menu.add(itemNative); | |
| menu.add(itemBackground); | |
| menu.add(itemScreen); | |
| MenuBar menuBar = new MenuBar(); | |
| menuBar.add( menu ); | |
| menuBar.add( menu2 ); | |
| menuBar.add( menu3 ); | |
| menuBar.add( menu4 ); | |
| setMenuBar(menuBar); | |
| ActionPrint actionPrint = new ActionPrint(); | |
| itemJFC.addActionListener( actionPrint ); | |
| itemNative.addActionListener( actionPrint ); | |
| itemBackground.addActionListener( actionPrint ); | |
| itemScreen.addActionListener( new ActionPrintToScreen() ); | |
| } | |
| class ActionPrint implements ActionListener { | |
| private final int ITERATIONS = 1; | |
| private PageAttributes pageAttributes = new PageAttributes(); | |
| private JobAttributes jobAttributes = new JobAttributes(); | |
| public void actionPerformed(ActionEvent ev) { | |
| DialogType dialog; | |
| if (ev.getActionCommand().equals("common")) { | |
| dialog = DialogType.COMMON; | |
| } else if (ev.getActionCommand().equals("native")) { | |
| dialog = DialogType.NATIVE; | |
| } else { | |
| dialog = DialogType.NONE; | |
| } | |
| jobAttributes.setDialog(dialog); | |
| pageAttributes.setOrigin(OriginType.PRINTABLE); | |
| System.err.println(jobAttributes); | |
| System.err.println(pageAttributes); | |
| PassFailJFrame.log("About to show print dialog..."); | |
| PrintJob pj = getToolkit().getPrintJob( | |
| MainFrame.this, "Print test!", jobAttributes, pageAttributes); | |
| if (pj == null) { | |
| return; | |
| } | |
| Dimension d = pj.getPageDimension(); | |
| PassFailJFrame.log("About to print..."); | |
| PassFailJFrame.log("Dimensions: " + d); | |
| System.err.println(jobAttributes); | |
| System.err.println(pageAttributes); | |
| // For xor mode set, there is a printing issue with number of copies to be print. | |
| // So, ITERATIONS are changed to 1 from 3. | |
| // So, for now the XOR related code is commented out. | |
| //boolean xor = false; | |
| for (int i = 0; i < ITERATIONS; i++) { | |
| Graphics g = pj.getGraphics(); | |
| g.setColor(Color.red); | |
| //if (xor) { | |
| // g.setXORMode(Color.blue); | |
| //} | |
| printAll(g); | |
| g.dispose(); | |
| //xor = (xor) ? false : true; | |
| } | |
| // For xor mode set, LWC components don't get printed. | |
| // So, for now the code is commented out and separate bug | |
| // (JDK-8340495) is filed to handle it. | |
| // one more page so that we can test printing a lightweight | |
| // at the top of the hierarchy (BugId 4212564) | |
| //Graphics g = pj.getGraphics(); | |
| //g.setColor(Color.red); | |
| //lwc.printAll(g); | |
| //g.dispose(); | |
| // end 4212564 | |
| pj.end(); | |
| } | |
| } | |
| class ActionPrintToScreen implements ActionListener { | |
| public void actionPerformed(ActionEvent ev) { | |
| PrintFrame printFrame = new PrintFrame(MainFrame.this); | |
| printFrame.show(); | |
| Graphics g = printFrame.getGraphics(); | |
| g.setColor(Color.red); | |
| printAll(g); | |
| g.dispose(); | |
| } | |
| } | |
| // Frame window that displays results of printing | |
| // main window to a screen Graphics-- useful for | |
| // quick testing of printing | |
| class PrintFrame extends Frame | |
| { | |
| private Component printComponent; | |
| public PrintFrame( Component c ) | |
| { | |
| super("Print to Screen"); | |
| printComponent = c ; | |
| addWindowListener( new WindowAdapter() { | |
| public void windowClosing(WindowEvent ev) { | |
| setVisible(false); | |
| dispose(); | |
| } | |
| } | |
| ); | |
| setSize(printComponent.getSize()); | |
| setResizable(false); | |
| } | |
| public void paint( Graphics g ) { | |
| printComponent.printAll(g); | |
| } | |
| } | |
| class LWButton extends Component { | |
| String label; | |
| int width = 100; | |
| int height = 30; | |
| public LWButton(String label) { | |
| super(); | |
| this.label = label; | |
| } | |
| public void paint(Graphics g) { | |
| Dimension d = getSize(); | |
| g.setColor(Color.orange); | |
| g.setFont(getFont()); | |
| g.fillRect(0, 0, d.width, d.height); | |
| g.setColor(Color.black); | |
| int x = 5; | |
| int y = (d.height - 5); | |
| g.drawString(label, x, y); | |
| } | |
| public Dimension getPreferredSize() | |
| { | |
| return new Dimension(width, height); | |
| } | |
| } | |
| class LWContainer extends Container { | |
| String label; | |
| int width = 300; | |
| int height = 100; | |
| public LWContainer(String label) { | |
| super(); | |
| this.label = label; | |
| setLayout(new FlowLayout()); | |
| } | |
| public void paint(Graphics g) { | |
| super.paint(g); | |
| Dimension d = getSize(); | |
| g.setColor(Color.green); | |
| g.setFont(getFont()); | |
| g.drawLine(0, 0, d.width - 1, 0); | |
| g.drawLine(d.width - 1, 0, d.width - 1, d.height - 1); | |
| g.drawLine(d.width - 1, d.height - 1, 0, d.height - 1); | |
| g.drawLine(0, d.height - 1, 0, 0); | |
| g.setColor(Color.black); | |
| int x = 5; | |
| int y = (d.height - 5); | |
| g.drawString(label, x, y); | |
| } | |
| public Dimension getPreferredSize() | |
| { | |
| return new Dimension(width, height); | |
| } | |
| } | |
| class TestCanvas extends Canvas { | |
| int width = 100; | |
| int height = 100; | |
| public void paint(Graphics g) { | |
| g.setColor(Color.blue); | |
| g.fillRoundRect(10, 10, 50, 50, 15, 30); | |
| g.setColor(Color.red); | |
| g.fillOval(70, 70, 25, 25); | |
| } | |
| public Dimension getPreferredSize() { | |
| return new Dimension(width, height); | |
| } | |
| } | |
| class ZOrderPanel extends Panel | |
| { | |
| ZOrderPanel() | |
| { | |
| setLayout(null); | |
| Component first, second, third, fourth; | |
| setVisible(true); | |
| // add first component | |
| first = makeBox("Second", Color.blue, | |
| new Font("Serif", Font.BOLD, 14), | |
| -1); | |
| // insert on top | |
| second = makeBox("First", Color.yellow, | |
| new Font("SansSerif", Font.BOLD, 14), | |
| 0); | |
| // put at the back | |
| fourth = makeBox("Fourth", Color.red, | |
| new Font("Monospaced", Font.BOLD, 14), | |
| 2); | |
| // insert in last position | |
| third = makeBox("Third", Color.green, | |
| new Font("Dialog", Font.PLAIN, 12), | |
| 3); | |
| // swap third and fourth to correct positions | |
| remove(third); | |
| add(third, 2); | |
| // re-validate so third and fourth peers change position | |
| validate(); | |
| // now make things really interesting with a lightweight | |
| // component at the top of the z-order, that should print | |
| // _below_ the native guys to match the screen... | |
| add(new LWButton("LWButton"), 0); | |
| } | |
| public Dimension preferredSize() | |
| { | |
| return new Dimension(260, 80); | |
| } | |
| public void layout() | |
| { | |
| int i, n; | |
| Insets ins = getInsets(); | |
| n = getComponentCount(); | |
| for (i = n-1; i >= 0; i--) { | |
| Component p = getComponent(i); | |
| p.setBounds(ins.left + 40 * i, ins.top + 5 * i, 60, 60); | |
| } | |
| } | |
| public Component makeBox(String s, Color c, Font f, int index) | |
| { | |
| Label l = new Label(s); | |
| l.setBackground(c); | |
| l.setAlignment(Label.RIGHT); | |
| l.setFont(f); | |
| add(l, index); | |
| validate(); | |
| return l; | |
| } | |
| } | |
| } |