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 }