diff --git a/test/jdk/java/awt/Frame/DisabledParentOfToplevel.java b/test/jdk/java/awt/Frame/DisabledParentOfToplevel.java new file mode 100644 index 0000000000000..878809749d35a --- /dev/null +++ b/test/jdk/java/awt/Frame/DisabledParentOfToplevel.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2004, 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.BorderLayout; +import java.awt.Button; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Window; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/* + * @test + * @bug 5062118 + * @key headful + * @summary Disabling of a parent should not disable Window. + * @run main DisabledParentOfToplevel + */ + +public class DisabledParentOfToplevel { + private static Button okBtn; + private static Window ww; + private static Frame parentFrame; + private static volatile Point p; + private static volatile Dimension d; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + try { + EventQueue.invokeAndWait(() -> { + createAndShowUI(); + }); + robot.delay(1000); + EventQueue.invokeAndWait(() -> { + p = okBtn.getLocationOnScreen(); + d = okBtn.getSize(); + }); + robot.mouseMove(p.x + d.width / 2, p.x + d.height / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(500); + if (ww.isVisible()) { + throw new RuntimeException("Window is visible but should be hidden: failure."); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (parentFrame != null) { + parentFrame.dispose(); + } + }); + } + } + + private static void createAndShowUI() { + parentFrame = new Frame("parentFrame"); + parentFrame.setSize(100, 100); + parentFrame.setEnabled(false); + ww = new Window(parentFrame); + ww.setLayout(new BorderLayout()); + okBtn = new Button("Click to Close Me"); + ww.add(okBtn); + ww.setSize(250, 250); + ww.setLocation(110, 110); + okBtn.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + System.out.println("Pressed: close"); + ww.setVisible(false); + } + }); + parentFrame.setVisible(true); + ww.setVisible(true); + okBtn.requestFocus(); + } +} diff --git a/test/jdk/java/awt/Frame/FrameVisualTest.java b/test/jdk/java/awt/Frame/FrameVisualTest.java new file mode 100644 index 0000000000000..767eb0a18965c --- /dev/null +++ b/test/jdk/java/awt/Frame/FrameVisualTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2002, 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.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +/* + * @test + * @bug 4328588 + * @key headful + * @summary Non-default visual on top-level Frame should work + * @run main FrameVisualTest + */ + +public class FrameVisualTest { + private static GraphicsConfiguration[] gcs; + private static volatile Frame[] frames; + private static volatile int index; + + private static Frame f; + private static Robot robot; + private static volatile Point p; + private static volatile Dimension d; + private static final int TOLERANCE = 5; + + public static void main(String[] args) throws Exception { + gcs = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getConfigurations(); + robot = new Robot(); + robot.setAutoDelay(100); + try { + EventQueue.invokeAndWait(() -> { + createAndShowUI(); + }); + robot.delay(1000); + System.out.println("frames.length: "+frames.length); + for (index = 0; index < frames.length; index++) { + EventQueue.invokeAndWait(() -> { + p = frames[index].getLocation(); + d = frames[index].getSize(); + }); + Rectangle rect = new Rectangle(p, d); + BufferedImage img = robot.createScreenCapture(rect); + if (chkImgBackgroundColor(img)) { + try { + ImageIO.write(img, "png", new File("Frame_" + index + ".png")); + } catch (IOException ignored) {} + throw new RuntimeException("Frame visual test failed with non-white background color"); + } + } + } finally { + for (index = 0; index < frames.length; index++) { + EventQueue.invokeAndWait(() -> { + if (frames[index] != null) { + frames[index].dispose(); + } + }); + } + } + } + + private static void createAndShowUI() { + frames = new Frame[gcs.length]; + for (int i = 0; i < frames.length; i++) { + frames[i] = new Frame("Frame w/ gc " + i, gcs[i]); + frames[i].setSize(100, 100); + frames[i].setUndecorated(true); + frames[i].setBackground(Color.WHITE); + frames[i].setVisible(true); + } + } + + private static boolean chkImgBackgroundColor(BufferedImage img) { + + // scan for mid-line and if it is non-white color then return true. + for (int x = 1; x < img.getWidth() - 1; ++x) { + Color c = new Color(img.getRGB(x, img.getHeight() / 2)); + if ((c.getRed() - Color.WHITE.getRed()) > TOLERANCE && + (c.getGreen() - Color.WHITE.getGreen()) > TOLERANCE && + (c.getBlue() - Color.WHITE.getBlue()) > TOLERANCE) { + return true; + } + } + return false; + } +} + diff --git a/test/jdk/java/awt/Frame/IMStatusBar.java b/test/jdk/java/awt/Frame/IMStatusBar.java new file mode 100644 index 0000000000000..7e882d01c707c --- /dev/null +++ b/test/jdk/java/awt/Frame/IMStatusBar.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1998, 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.BorderLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; + +/* + * @test + * @bug 4113040 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Checks that IMStatusBar does not affect Frame layout + * @run main/manual/othervm -Duser.language=ja -Duser.country=JP IMStatusBar + */ + +public class IMStatusBar { + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + If the window appears the right size, but then resizes so that the + status field overlaps the bottom label, press Fail; otherwise press Pass. + """; + + PassFailJFrame.builder() + .title("IMStatusBar Instruction") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(IMStatusBar::createUI) + .build() + .awaitAndCheck(); + } + + private static Frame createUI() { + Frame f = new Frame(); + Panel centerPanel = new Panel(); + f.setSize(200, 200); + f.setLayout(new BorderLayout()); + f.add(new Label("Top"), BorderLayout.NORTH); + f.add(centerPanel, BorderLayout.CENTER); + f.add(new Label("Bottom"), BorderLayout.SOUTH); + centerPanel.setLayout(new BorderLayout()); + centerPanel.add(new TextField("Middle"), BorderLayout.CENTER); + centerPanel.validate(); + return f; + } +} diff --git a/test/jdk/java/awt/Frame/MultiScreenTest.java b/test/jdk/java/awt/Frame/MultiScreenTest.java new file mode 100644 index 0000000000000..845f601138b74 --- /dev/null +++ b/test/jdk/java/awt/Frame/MultiScreenTest.java @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2000, 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.BorderLayout; +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Label; +import java.awt.LayoutManager; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.TextField; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import java.awt.image.ColorModel; +import java.awt.image.MemoryImageSource; + +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JFrame; + +import jtreg.SkippedException; + +/* + * @test + * @bug 4312921 + * @key multimon + * @library /java/awt/regtesthelpers /test/lib + * @build PassFailJFrame + * @summary Tests that no garbage is painted on primary screen with DGA + * @run main/manual MultiScreenTest + */ + +public class MultiScreenTest { + static GraphicsEnvironment ge; + static GraphicsDevice[] gs; + + public static void main(String[] args) throws Exception { + ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + gs = ge.getScreenDevices(); + if (gs.length < 2) { + throw new SkippedException("You have only one monitor in your system - test passed"); + } + MultiScreenTest obj = new MultiScreenTest(); + String INSTRUCTIONS = + "This test is to be run only on multiscreen machine. " + + "You have " + gs.length + " monitors in your system.\n" + + "Actively drag the DitherTest frames on the secondary screen and " + + "if you see garbage appearing on your primary screen " + + "test failed otherwise it passed.";; + + PassFailJFrame.builder() + .title("MultiScreenTest Instruction") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(40) + .testUI(obj::init) + .build() + .awaitAndCheck(); + } + + public List init() { + List list = new ArrayList<>(); + for (int j = 0; j < gs.length; j++) { + GraphicsConfiguration[] gc = gs[j].getConfigurations(); + if (gc.length > 0) { + for (int i = 0; i < gc.length / 2; i++) { + JFrame f = new JFrame(gc[i]); //test JFrame( gc ) + GCCanvas c = new GCCanvas(gc[i]);//test canvas( gc ) + Rectangle gcBounds = gc[i].getBounds(); //test getBounds() + int xoffs = gcBounds.x; + int yoffs = gcBounds.y; + + f.getContentPane().add(c); + f.setTitle("Screen# " + Integer.toString(j) + ", GC#" + Integer.toString(i)); + f.setSize(300, 200); + f.setLocation(400 + xoffs, (i * 150) + yoffs);//test displaying in right location + list.add(f); + + Frame ditherfs = new Frame("DitherTest GC#" + Integer.toString(i), gc[i]); + ditherfs.setLayout(new BorderLayout()); //showDitherTest + DitherTest ditherTest = new DitherTest(gc[i]); + ditherfs.add("Center", ditherTest); + ditherfs.setBounds(300, 200, 300, 200); + ditherfs.setLocation(750 + xoffs, (i * 50) + yoffs); + ditherfs.pack(); + ditherfs.show(); + ditherTest.start(); + } + } + } + return list; + } +} + +class GCCanvas extends Canvas { + + GraphicsConfiguration gc; + Rectangle bounds; + Graphics g = this.getGraphics(); + Dimension size = getSize(); + + public GCCanvas(GraphicsConfiguration gc) { + super(gc); + this.gc = gc; + bounds = gc.getBounds(); + } + + public void paint( Graphics _g ) { + + Graphics2D g = (Graphics2D) _g; + + g.drawRect(0, 0, size.width-1, size.height-1); + g.setColor(Color.lightGray); + g.draw3DRect(1, 1, size.width-3, size.height-3, true); + + g.setColor(Color.red); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g.drawString("HELLO!", 110, 10); + + g.setColor(Color.blue); + g.drawString("ScreenSize="+Integer.toString(bounds.width)+"X"+ + Integer.toString(bounds.height), 10, 20); + g.setColor(Color.green); + g.drawString(gc.toString(), 10, 30); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + + g.setColor(Color.orange); + g.fillRect(40, 20, 50, 50); + + g.setColor(Color.red); + g.drawRect(100, 20, 30, 30); + + g.setColor(Color.gray); + g.drawLine(220, 20, 280, 40); + + g.setColor(Color.cyan); + g.fillArc(150, 30, 30, 30, 0, 200); + } + + public Dimension getPreferredSize(){ + return new Dimension(300, 200); + } +} + +class DitherCanvas extends Canvas { + Image img; + static String calcString = "Calculating..."; + + GraphicsConfiguration mGC; + + public DitherCanvas(GraphicsConfiguration gc) { + super(gc); + mGC = gc; + } + + public GraphicsConfiguration getGraphicsConfig() { + return mGC; + } + + public void paint(Graphics g) { + int w = getSize().width; + int h = getSize().height; + if (img == null) { + super.paint(g); + g.setColor(Color.black); + FontMetrics fm = g.getFontMetrics(); + int x = (w - fm.stringWidth(calcString)) / 2; + int y = h / 2; + g.drawString(calcString, x, y); + } else { + g.drawImage(img, 0, 0, w, h, this); + } + } + + public void update(Graphics g) { + paint(g); + } + + public Dimension getMinimumSize() { + return new Dimension(20, 20); + } + + public Dimension getPreferredSize() { + return new Dimension(200, 200); + } + + public Image getImage() { + return img; + } + + public void setImage(Image img) { + this.img = img; + paint(getGraphics()); + } +} + +class DitherTest extends Panel implements Runnable { + final static int NOOP = 0; + final static int RED = 1; + final static int GREEN = 2; + final static int BLUE = 3; + final static int ALPHA = 4; + final static int SATURATION = 5; + + Thread runner; + + DitherControls XControls; + DitherControls YControls; + DitherCanvas canvas; + + public DitherTest(GraphicsConfiguration gc) { + String xspec, yspec; + int xvals[] = new int[2]; + int yvals[] = new int[2]; + + xspec = "red"; + yspec = "blue"; + int xmethod = colormethod(xspec, xvals); + int ymethod = colormethod(yspec, yvals); + + setLayout(new BorderLayout()); + XControls = new DitherControls(this, xvals[0], xvals[1], + xmethod, false); + YControls = new DitherControls(this, yvals[0], yvals[1], + ymethod, true); + YControls.addRenderButton(); + add("North", XControls); + add("South", YControls); + add("Center", canvas = new DitherCanvas(gc)); + } + + public void start() { + runner = new Thread(this); + runner.start(); + } + + int colormethod(String s, int vals[]) { + int method = NOOP; + + if (s == null) { + s = ""; + } + + String lower = s.toLowerCase(); + int len = 0; + if (lower.startsWith("red")) { + method = RED; + lower = lower.substring(3); + } else if (lower.startsWith("green")) { + method = GREEN; + lower = lower.substring(5); + } else if (lower.startsWith("blue")) { + method = BLUE; + lower = lower.substring(4); + } else if (lower.startsWith("alpha")) { + method = ALPHA; + lower = lower.substring(4); + } else if (lower.startsWith("saturation")) { + method = SATURATION; + lower = lower.substring(10); + } + + if (method == NOOP) { + vals[0] = 0; + vals[1] = 0; + return method; + } + + int begval = 0; + int endval = 255; + + try { + int dash = lower.indexOf('-'); + if (dash < 0) { + begval = endval = Integer.parseInt(lower); + } else { + begval = Integer.parseInt(lower.substring(0, dash)); + endval = Integer.parseInt(lower.substring(dash + 1)); + } + } catch (Exception e) { + } + + if (begval < 0) { + begval = 0; + } + if (endval < 0) { + endval = 0; + } + if (begval > 255) { + begval = 255; + } + if (endval > 255) { + endval = 255; + } + + vals[0] = begval; + vals[1] = endval; + + return method; + } + + void applymethod(int c[], int method, int step, int total, int vals[]) { + if (method == NOOP) + return; + int val = ((total < 2) + ? vals[0] + : vals[0] + ((vals[1] - vals[0]) * step / (total - 1))); + switch (method) { + case RED: + c[0] = val; + break; + case GREEN: + c[1] = val; + break; + case BLUE: + c[2] = val; + break; + case ALPHA: + c[3] = val; + break; + case SATURATION: + int max = Math.max(Math.max(c[0], c[1]), c[2]); + int min = max * (255 - val) / 255; + if (c[0] == 0) { + c[0] = min; + } + if (c[1] == 0) { + c[1] = min; + } + if (c[2] == 0) { + c[2] = min; + } + break; + } + } + + public void run() { + canvas.setImage(null); // Wipe previous image + Image img = calculateImage(); + synchronized (this) { + if (img != null && runner == Thread.currentThread()) { + canvas.setImage(img); + } + } + } + + /** + * Calculates and returns the image. Halts the calculation and returns + * null if stopped during the calculation. + */ + Image calculateImage() { + Thread me = Thread.currentThread(); + + int width = canvas.getSize().width; + int height = canvas.getSize().height; + int xvals[] = new int[2]; + int yvals[] = new int[2]; + int xmethod = XControls.getParams(xvals); + int ymethod = YControls.getParams(yvals); + int pixels[] = new int[width * height]; + int c[] = new int[4]; + int index = 0; + + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + c[0] = c[1] = c[2] = 0; + c[3] = 255; + if (xmethod < ymethod) { + applymethod(c, xmethod, i, width, xvals); + applymethod(c, ymethod, j, height, yvals); + } else { + applymethod(c, ymethod, j, height, yvals); + applymethod(c, xmethod, i, width, xvals); + } + pixels[index++] = ((c[3] << 24) | + (c[0] << 16) | + (c[1] << 8) | + (c[2] << 0)); + + } + // Poll once per row to see if we've been told to stop. + if (runner != me) { + return null; + } + } + + return createImage(new MemoryImageSource(width, height, + ColorModel.getRGBdefault(), pixels, 0, width)); + } + + public String getInfo() { + return "An interactive demonstration of dithering."; + } + + public String[][] getParameterInfo() { + String[][] info = { + {"xaxis", "{RED, GREEN, BLUE, PINK, ORANGE, MAGENTA, CYAN, WHITE, YELLOW, GRAY, DARKGRAY}", + "The color of the Y axis. Default is RED."}, + {"yaxis", "{RED, GREEN, BLUE, PINK, ORANGE, MAGENTA, CYAN, WHITE, YELLOW, GRAY, DARKGRAY}", + "The color of the X axis. Default is BLUE."} + }; + return info; + } +} + +class DitherControls extends Panel implements ActionListener { + TextField start; + TextField end; + Button button; + Choice choice; + DitherTest dt; + + static LayoutManager dcLayout = new FlowLayout(FlowLayout.CENTER, 10, 5); + + public DitherControls(DitherTest app, int s, int e, int type, + boolean vertical) { + dt = app; + setLayout(dcLayout); + add(new Label(vertical ? "Vertical" : "Horizontal")); + add(choice = new Choice()); + choice.addItem("Noop"); + choice.addItem("Red"); + choice.addItem("Green"); + choice.addItem("Blue"); + choice.addItem("Alpha"); + choice.addItem("Saturation"); + choice.select(type); + add(start = new TextField(Integer.toString(s), 4)); + add(end = new TextField(Integer.toString(e), 4)); + } + + public void addRenderButton() { + add(button = new Button("New Image")); + button.addActionListener(this); + } + + public int getParams(int vals[]) { + vals[0] = Integer.parseInt(start.getText()); + vals[1] = Integer.parseInt(end.getText()); + return choice.getSelectedIndex(); + } + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == button) { + dt.start(); + } + } +}