1 /* 2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package mandel; 26 27 import hat.buffer.Buffer; 28 import hat.buffer.S32Array2D; 29 import hat.util.ui.SevenSegmentDisplay; 30 31 import javax.swing.Box; 32 import javax.swing.BoxLayout; 33 import javax.swing.JButton; 34 import javax.swing.JComponent; 35 import javax.swing.JFrame; 36 import javax.swing.JLabel; 37 import javax.swing.JMenuBar; 38 import javax.swing.JPanel; 39 import javax.swing.WindowConstants; 40 import java.awt.Dimension; 41 import java.awt.Graphics; 42 import java.awt.Graphics2D; 43 import java.awt.Point; 44 import java.awt.event.MouseAdapter; 45 import java.awt.event.MouseEvent; 46 import java.awt.image.BufferedImage; 47 import java.awt.image.DataBufferInt; 48 import java.lang.foreign.MemoryLayout; 49 import java.lang.foreign.MemorySegment; 50 51 import static java.lang.foreign.ValueLayout.JAVA_INT; 52 53 public class Viewer extends JFrame { 54 55 public final SevenSegmentDisplay framesSecondSevenSegment; 56 57 public static class PointF32 { 58 public final float x; 59 public final float y; 60 61 public PointF32(float x, float y) { 62 this.x = x; 63 this.y = y; 64 } 65 } 66 67 public final ImageViewer imageViewer; 68 69 70 public static class ImageViewer extends JComponent { 71 72 public PointF32 getZoomPoint(float scale) { 73 waitForDoorbell(); 74 return new PointF32( 75 ((float) (to.x - (image.getWidth() / 2)) / image.getWidth()) * scale, 76 ((float) (to.y - (image.getHeight() / 2)) / image.getHeight()) * scale); 77 } 78 79 final BufferedImage image; 80 private final Object doorBell = new Object(); 81 public Point to = null; 82 83 ImageViewer(BufferedImage image) { 84 super(); 85 this.image = image; 86 addMouseListener(new MouseAdapter() { 87 @Override 88 public void mouseClicked(MouseEvent e) { 89 to = e.getPoint(); 90 synchronized (doorBell) { 91 doorBell.notify(); 92 } 93 } 94 }); 95 to = new Point(image.getWidth() / 2, image.getHeight() / 2); 96 } 97 98 @Override 99 public Dimension getPreferredSize() { 100 return new Dimension(image.getWidth(), image.getHeight()); 101 } 102 103 @Override 104 public void paintComponent(Graphics g1d) { 105 super.paintComponent(g1d); 106 Graphics2D g = (Graphics2D) g1d; 107 g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), this); 108 } 109 110 public void waitForDoorbell() { 111 to = null; 112 while (to == null) { 113 synchronized (doorBell) { 114 try { 115 doorBell.wait(); 116 } catch (final InterruptedException ie) { 117 ie.getStackTrace(); 118 } 119 } 120 } 121 } 122 123 public void syncWithRGB(S32Array2D s32Array2D) { 124 long offset = Buffer.getLayout(s32Array2D).byteOffset(MemoryLayout.PathElement.groupElement("array")); 125 MemorySegment.copy(Buffer.getMemorySegment(s32Array2D), JAVA_INT, offset, ((DataBufferInt) image.getRaster().getDataBuffer()).getData(), 0, s32Array2D.width()*s32Array2D.height()); 126 this.repaint(); 127 } 128 129 130 } 131 132 public Viewer(String title, S32Array2D s32Array2D) { 133 super(title); 134 135 this.imageViewer = new ImageViewer(new BufferedImage(s32Array2D.width(), s32Array2D.height(), BufferedImage.TYPE_INT_RGB)); 136 var menuBar = new JMenuBar(); 137 JPanel panel = new JPanel(); 138 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); 139 ((JButton) panel.add(new JButton("Exit"))).addActionListener(_ -> System.exit(0)); 140 panel.add(new JLabel("FPS")); 141 this.framesSecondSevenSegment = (SevenSegmentDisplay) 142 panel.add(new SevenSegmentDisplay(4,30,panel.getForeground(),panel.getBackground())); 143 panel.add(Box.createHorizontalStrut(400)); 144 menuBar.add(panel); 145 this.setJMenuBar(menuBar); 146 this.getContentPane().add(this.imageViewer); 147 this.pack(); 148 this.setLocationRelativeTo(null); 149 this.setVisible(true); 150 this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 151 } 152 }