diff --git a/test/jdk/java/awt/Canvas/MultiDitherTest.java b/test/jdk/java/awt/Canvas/MultiDitherTest.java new file mode 100644 index 00000000000..ab592280c80 --- /dev/null +++ b/test/jdk/java/awt/Canvas/MultiDitherTest.java @@ -0,0 +1,422 @@ +/* + * 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. + */ + +/* + * @test + * @bug 6616089 + * @summary Displays a dithered Canvas on all available GraphicsConfigurations + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MultiDitherTest + */ + +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.EventQueue; +import java.awt.FlowLayout; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +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.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.ColorModel; +import java.awt.image.MemoryImageSource; +import java.util.List; + +public class MultiDitherTest 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; + final static String calcString = "Calculating..."; + static LayoutManager dcLayout = new FlowLayout(FlowLayout.CENTER, 10, 5); + Thread runner; + DitherControls XControls; + DitherControls YControls; + DitherCanvas canvas; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + Depending on the GraphicsConfiguration, the dithering may be in + color or in grayscale and/or display at a lower bitdepth. + The number of GraphicsConfigurations will be printed in the + TextArea below as the test is starting up. + Ensure that there are as many Frames created as there are + available GraphicsConfigurations. + Examine each Frame to ensure it displays the dither pattern. + If all Canvases display correctly, the test PASSES. + Otherwise, the test FAILS. + The GC button runs the garbage collector. + This button can be ignored for now. + + """; + PassFailJFrame passFailJFrame = PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .build(); + + EventQueue.invokeAndWait(() -> { + for (Frame frame : MultiDitherTest.initialize()) { + PassFailJFrame.addTestWindow(frame); + frame.setVisible(true); + } + }); + passFailJFrame.awaitAndCheck(); + } + + public MultiDitherTest(GraphicsConfiguration gc) { + String xSpec, ySpec; + int[] xValues = new int[2]; + int[] yValues = new int[2]; + + xSpec = "red"; + ySpec = "blue"; + int xMethod = colorMethod(xSpec, xValues); + int yMethod = colorMethod(ySpec, yValues); + + setLayout(new BorderLayout()); + XControls = new DitherControls(this, xValues[0], xValues[1], + xMethod, false); + YControls = new DitherControls(this, yValues[0], yValues[1], + yMethod, true); + YControls.addRenderButton(); + YControls.addGCButton(); + add("North", XControls); + add("South", YControls); + add("Center", canvas = new DitherCanvas(gc)); + } + + private static List initialize() { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] gds = ge.getScreenDevices(); + Frame[] frames = new Frame[0]; + System.out.println(gds.length + " screens detected"); + + for (int j = 0; j < gds.length; j++) { + + GraphicsDevice gd = gds[j]; + GraphicsConfiguration[] gcs = gd.getConfigurations(); + frames = new Frame[gcs.length]; + System.out.println(gcs.length + " GraphicsConfigurations available on screen " + j); + for (int i = 0; i < gcs.length; i++) { + Frame f = new Frame("MultiDitherTest " + (i + 1), gcs[i]); + f.setLayout(new BorderLayout()); + f.setLocation(gcs[i].getBounds().x + 100 + (i * 10), + gcs[i].getBounds().y + 100 + (i * 10)); + MultiDitherTest ditherTest = new MultiDitherTest(gcs[i]); + f.add("Center", ditherTest); + f.pack(); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent ev) { + ev.getWindow().dispose(); + } + }); + f.setVisible(true); + ditherTest.start(); + frames[i] = f; + } + + } + return List.of(frames); + } + + int colorMethod(String s, int[] values) { + int method = NOOP; + + if (s == null) { + s = ""; + } + + String lower = s.toLowerCase(); + 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) { + values[0] = 0; + values[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; + } + + values[0] = begval; + values[1] = endval; + + return method; + } + + public void start() { + runner = new Thread(this); + runner.start(); + } + + public void stop() { + runner = null; + } + + public void destroy() { + remove(XControls); + remove(YControls); + remove(canvas); + } + + void applyMethod(int[] c, int method, int step, int total, int[] values) { + if (method == NOOP) { + return; + } + int val = ((total < 2) + ? values[0] + : values[0] + ((values[1] - values[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); + 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 the Application is stopped during the calculation. + */ + Image calculateImage() { + Thread me = Thread.currentThread(); + + int width = canvas.getSize().width; + int height = canvas.getSize().height; + int[] xValues = new int[2]; + int[] yValues = new int[2]; + int xMethod = XControls.getParams(xValues); + int yMethod = YControls.getParams(yValues); + 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, xValues); + applyMethod(c, yMethod, j, height, yValues); + } else { + applyMethod(c, yMethod, j, height, yValues); + applyMethod(c, xMethod, i, width, xValues); + } + 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)); + } + + static class DitherCanvas extends Canvas { + Image img; + 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()); + } + } + + static class DitherControls extends Panel implements ActionListener { + TextField start; + TextField end; + Button button; + Choice choice; + MultiDitherTest panel; + Button gc; + + public DitherControls(MultiDitherTest app, int s, int e, int type, + boolean vertical) { + panel = 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 void addGCButton() { + add(gc = new Button("GC")); + gc.addActionListener(this); + } + + public int getParams(int[] values) { + values[0] = Integer.parseInt(start.getText()); + values[1] = Integer.parseInt(end.getText()); + return choice.getSelectedIndex(); + } + + public void actionPerformed(ActionEvent e) { + if (e.getSource() == button) { + panel.start(); + } else if (e.getSource() == gc) { + System.gc(); + } + } + } +} \ No newline at end of file diff --git a/test/jdk/java/awt/Canvas/MultiGraphicsTest.java b/test/jdk/java/awt/Canvas/MultiGraphicsTest.java new file mode 100644 index 00000000000..c38d6041c2b --- /dev/null +++ b/test/jdk/java/awt/Canvas/MultiGraphicsTest.java @@ -0,0 +1,139 @@ +/* + * 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. + */ + +/* + * @test + * @bug 6616089 + * @summary Display an image in all available GraphicsConfigurations + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual MultiGraphicsTest + */ + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Toolkit; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.net.URL; +import java.util.List; + +public class MultiGraphicsTest extends Canvas { + final static String IMAGEFILE = "duke_404.gif"; + static Image jim; + MediaTracker tracker; + int w, h; + + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + This test displays several Windows containing an image, + one Window for each available GraphicsConfiguration. + Depending on the GraphicsConfiguration, images may be + displayed in color or in grayscale and/or displayed at a + lower bitdepth. + The number of GraphicsConfigurations will be printed below + as the test is starting up. + Ensure that there are as many Windows created as there are + available GraphicsConfigurations. + Examine each Window to ensure it displays Duke_404. + If all Canvases display correctly, the test PASSES. + Otherwise, the test FAILS." + """; + PassFailJFrame.builder() + .title("Test Instructions") + .instructions(INSTRUCTIONS) + .rows((int) INSTRUCTIONS.lines().count() + 2) + .columns(35) + .testUI(initialize()) + .build() + .awaitAndCheck(); + } + + public MultiGraphicsTest(GraphicsConfiguration gc) { + super(gc); + tracker = new MediaTracker(this); + tracker.addImage(jim, 0); + try { + tracker.waitForAll(); + } catch (java.lang.InterruptedException e) { + System.err.println(e); + } + w = jim.getWidth(this); + h = jim.getHeight(this); + } + + private static List initialize() { + URL imgURL; + imgURL = MultiGraphicsTest.class.getResource(IMAGEFILE); + if (imgURL == null) { + System.err.println("Unable to locate " + IMAGEFILE); + return null; + } + jim = Toolkit.getDefaultToolkit().getImage(imgURL); + + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + GraphicsConfiguration[] gc = gd.getConfigurations(); + Frame[] frames = new Frame[gc.length]; + System.out.println(gc.length + " available GraphicsConfigurations"); + for (int i = 0; i < gc.length; i++) { + Frame f = new Frame("GraphicsTest " + (i + 1)); + f.setLayout(new BorderLayout()); + f.setLocation(100 + (i * 10), 100 + (i * 10)); + MultiGraphicsTest gcTest = new MultiGraphicsTest(gc[i]); + f.add("Center", gcTest); + f.pack(); + f.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent ev) { + ev.getWindow().setVisible(false); + } + }); + frames[i] = f; + } + return List.of(frames); + } + + public void paint(Graphics g) { + g.drawImage(jim, 0, 0, w, h, this); + } + + public void update(Graphics g) { + paint(g); + } + + public Dimension getMinimumSize() { + return new Dimension(w, h); + } + + public Dimension getPreferredSize() { + return new Dimension(w, h); + } +} diff --git a/test/jdk/java/awt/Canvas/NoEventsLeakTest.java b/test/jdk/java/awt/Canvas/NoEventsLeakTest.java new file mode 100644 index 00000000000..4768775224a --- /dev/null +++ b/test/jdk/java/awt/Canvas/NoEventsLeakTest.java @@ -0,0 +1,96 @@ +/* + * 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. + */ + +/* + * @test + * @bug 4250354 + * @key headful + * @summary tests that JNI global refs are cleaned up correctly + * @run main/timeout=600 NoEventsLeakTest + */ + +import java.awt.Canvas; +import java.awt.EventQueue; +import java.awt.Frame; + +public class NoEventsLeakTest extends Frame { + static final int nLoopCount = 1000; + + private static void initialize() { + NoEventsLeakTest app = new NoEventsLeakTest(); + boolean result = app.run(); + if (result) { + throw new RuntimeException("Memory leak in Component"); + } + System.out.println("Test Passed"); + } + + public boolean run() { + setSize(10, 10); + addNotify(); + for (int i = 0; i < nLoopCount; i++) { + Canvas panel = new TestCanvas(); + add(panel, 0); + remove(0); + panel = null; + System.gc(); + } + try { + Thread.currentThread().sleep(1000); + } catch (InterruptedException e) { + } + System.gc(); + System.out.println("Checking"); + return ((TestCanvas.created - TestCanvas.finalized) > 800); + } + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(NoEventsLeakTest::initialize); + } +} + +class TestCanvas extends Canvas { + static int finalized = 0; + static int created = 0; + static final int nLoopPrint = 100; + + public TestCanvas() { + if (created % nLoopPrint == 0) { + System.out.println("Created " + getClass() + " " + created); + } + created++; + } + + @SuppressWarnings("removal") + protected void finalize() { + try { + super.finalize(); + if (finalized % nLoopPrint == 0) { + System.out.println("Finalized " + getClass() + " " + finalized); + } + finalized++; + } catch (Throwable t) { + System.out.println("Exception in " + getClass() + ": " + t); + } + } +} diff --git a/test/jdk/java/awt/Canvas/duke_404.gif b/test/jdk/java/awt/Canvas/duke_404.gif new file mode 100644 index 00000000000..4958e0d0dfa Binary files /dev/null and b/test/jdk/java/awt/Canvas/duke_404.gif differ diff --git a/test/jdk/java/awt/Rectangle/IntersectionTest.java b/test/jdk/java/awt/Rectangle/IntersectionTest.java new file mode 100644 index 00000000000..41680b2e7b6 --- /dev/null +++ b/test/jdk/java/awt/Rectangle/IntersectionTest.java @@ -0,0 +1,88 @@ +/* + * 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. + */ + +/* + * @test + * @bug 4147957 + * @key headful + * @summary Test to verify setClip with invalid rect changes rect to valid + * @run main IntersectionTest + */ + +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Rectangle; +import java.awt.Robot; + +public class IntersectionTest { + public static Frame frame; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + try { + robot.setAutoDelay(100); + EventQueue.invokeAndWait(() -> { + TestFrame panel = new TestFrame(); + frame = new Frame("Rectangle Intersection Test"); + frame.add(panel); + + frame.pack(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(200); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} + +class TestFrame extends Panel { + @Override + public void paint(Graphics g) { + Rectangle r1 = new Rectangle(0, 0, 100, 100); + Rectangle r2 = new Rectangle(200, 200, 20, 20); + Rectangle r3 = r1.intersection(r2); + System.out.println("intersect:(" + (int) r3.getX() + "," + + (int) r3.getY() + "," + (int) r3.getWidth() + "," + + (int) r3.getHeight() + ")"); + g.setClip(r3); + Rectangle r4 = g.getClipBounds(); + System.out.println("getClipBounds:(" + (int) r4.getX() + "," + + (int) r4.getY() + "," + (int) r4.getWidth() + "," + + (int) r4.getHeight() + ")"); + + if ((r4.getWidth() <= 0) || (r4.getHeight() <= 0)) { + System.out.println("Test Passed"); + } else { + throw new RuntimeException("IntersectionTest failed. " + + "Non-empty clip bounds."); + } + } +}