From c989e69f9fa12582f8f198feb786d2083bddf465 Mon Sep 17 00:00:00 2001 From: "J. Neugebauer" Date: Thu, 30 Jun 2022 21:29:01 +0200 Subject: [PATCH] Behandlung von inputs nun in eigener EventQueue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tastatur- und Mauseingaben werden nun nicht mehr direkt verarbeitet, sondern in eine interne EventQueue geschoben, die nach dem Aufruf von `draw()` abgearbeitet wird. Die `InputEvent`s werden momentan direkt an die üblichen Listener Methoden weitergegeben. Ggf. ist in Zukunft hier auch ein vereinfachtes Eventsystem (siehe Processing) sinnvoll. Ist die ZM pausiert, werden Events ohne verzögerung direkt ausgelöst. --- src/schule/ngb/zm/Zeichenmaschine.java | 269 +++++++++++++++++++------ 1 file changed, 209 insertions(+), 60 deletions(-) diff --git a/src/schule/ngb/zm/Zeichenmaschine.java b/src/schule/ngb/zm/Zeichenmaschine.java index 6501d2e..4d4a9e3 100644 --- a/src/schule/ngb/zm/Zeichenmaschine.java +++ b/src/schule/ngb/zm/Zeichenmaschine.java @@ -12,6 +12,8 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.LinkedList; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; /** * Hauptklasse der Zeichenmaschine. @@ -20,17 +22,45 @@ import java.util.LinkedList; * Die Klasse übernimmt die Initialisierung eines Programmfensters und der * nötigen Komponenten. */ -public class Zeichenmaschine extends Constants implements MouseInputListener, KeyListener { +public class Zeichenmaschine extends Constants { /** * Gibt an, ob die Zeichenmaschine aus BlueJ heraus gestartet wurde. */ - public static boolean IN_BLUEJ; + public static final boolean IN_BLUEJ; static { IN_BLUEJ = System.getProperty("java.class.path").contains("bluej"); } + public static final boolean MACOS; + + public static final boolean WINDOWS; + + public static final boolean LINUX; + + static { + final String name = System.getProperty("os.name"); + + if( name.contains("Mac") ) { + MACOS = true; + WINDOWS = false; + LINUX = false; + } else if( name.contains("Windows") ) { + MACOS = false; + WINDOWS = true; + LINUX = false; + } else if( name.equals("Linux") ) { // true for the ibm vm + MACOS = false; + WINDOWS = false; + LINUX = true; + } else { + MACOS = false; + WINDOWS = false; + LINUX = false; + } + } + /* * Objektvariablen, die von Unterklassen benutzt werden können. */ @@ -112,6 +142,9 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke // Hauptthread der Zeichenmaschine. private Thread mainThread; + // Queue für abgefangene InputEvents + private BlockingQueue eventQueue = new LinkedBlockingQueue<>(); + // Gibt an, ob nach Ende des Hauptthreads das Programm beendet werden soll, // oder das Zeichenfenster weiter geöffnet bleibt. private boolean quitAfterTeardown = false; @@ -250,16 +283,22 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); // Das Icon des Fensters ändern + try { ImageIcon icon = new ImageIcon(ImageIO.read(new File("res/icon_64.png"))); - frame.setIconImage(icon.getImage()); - // Dock Icon in macOS setzen - Taskbar taskbar = Taskbar.getTaskbar(); - taskbar.setIconImage(icon.getImage()); + if( MACOS ) { + // Dock Icon in macOS setzen + Taskbar taskbar = Taskbar.getTaskbar(); + taskbar.setIconImage(icon.getImage()); + } else { + // Kleines Icon des Frames setzen + frame.setIconImage(icon.getImage()); + } } catch( IOException e ) { } + // Erstellen der Leinwand canvas = new Zeichenleinwand(width, height); frame.add(canvas); @@ -279,9 +318,67 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke settings(); // Listener hinzufügen, um auf Maus- und Tastatureingaben zu hören. - canvas.addMouseListener(this); - canvas.addMouseMotionListener(this); - canvas.addKeyListener(this); + //canvas.addMouseListener(this); + //canvas.addMouseMotionListener(this); + //canvas.addKeyListener(this); + canvas.addMouseListener(new MouseInputListener() { + @Override + public void mouseClicked( MouseEvent e ) { + enqueueEvent(e); + } + + @Override + public void mousePressed( MouseEvent e ) { + enqueueEvent(e); + } + + @Override + public void mouseReleased( MouseEvent e ) { + enqueueEvent(e); + } + + @Override + public void mouseEntered( MouseEvent e ) { + } + + @Override + public void mouseExited( MouseEvent e ) { + } + + @Override + public void mouseDragged( MouseEvent e ) { + enqueueEvent(e); + } + + @Override + public void mouseMoved( MouseEvent e ) { + enqueueEvent(e); + } + }); + /* + canvas.addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseWheelMoved( MouseWheelEvent e ) { + enqueueEvent(e); + } + }); + */ + canvas.addKeyListener(new KeyListener() { + @Override + public void keyTyped( KeyEvent e ) { + enqueueEvent(e); + } + + @Override + public void keyPressed( KeyEvent e ) { + enqueueEvent(e); + } + + @Override + public void keyReleased( KeyEvent e ) { + enqueueEvent(e); + } + }); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing( WindowEvent e ) { @@ -527,12 +624,13 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke * @see #setSize(int, int) * @see #setFullscreen(boolean) */ - private void changeSize( int width, int height ) { + private void changeSize( int newWidth, int newHeight ) { + width = Math.min(Math.max(newWidth, 100), screenWidth); + height = Math.min(Math.max(newHeight, 100), screenHeight); + if( canvas != null ) { canvas.setSize(width, height); } - this.width = Math.min(Math.max(width, 100), screenWidth); - this.height = Math.min(Math.max(height, 100), screenHeight); } /** @@ -995,9 +1093,95 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke /* * Mouse handling */ - @Override - public final void mouseClicked( MouseEvent e ) { - mouseEvent = e; + private void enqueueEvent( InputEvent evt ) { + eventQueue.add(evt); + + if (isPaused()) { + dispatchEvents(); + } + } + + private void dispatchEvents() { + synchronized( eventQueue ) { + while( !eventQueue.isEmpty() ) { + InputEvent evt = eventQueue.poll(); + + // ??? + switch( evt.getID() ) { + case KeyEvent.KEY_TYPED: + case KeyEvent.KEY_PRESSED: + case KeyEvent.KEY_RELEASED: + handleKeyEvent((KeyEvent) evt); + break; + + case MouseEvent.MOUSE_CLICKED: + case MouseEvent.MOUSE_PRESSED: + case MouseEvent.MOUSE_RELEASED: + case MouseEvent.MOUSE_MOVED: + case MouseEvent.MOUSE_DRAGGED: + case MouseEvent.MOUSE_WHEEL: + handleMouseEvent((MouseEvent) evt); + break; + } + } + } + } + + private void handleKeyEvent( KeyEvent evt ) { + keyEvent = evt; + key = evt.getKeyChar(); + keyCode = evt.getKeyCode(); + + switch( evt.getID() ) { + case KeyEvent.KEY_TYPED: + keyTyped(evt); + break; + case KeyEvent.KEY_PRESSED: + keyPressed = true; + keyPressed(evt); + break; + case KeyEvent.KEY_RELEASED: + keyPressed = false; + keyReleased(evt); + break; + } + } + + private void handleMouseEvent( MouseEvent evt ) { + if( mouseEvent != null && evt.getComponent() == canvas ) { + pmouseX = mouseX; + pmouseY = mouseY; + + mouseX = evt.getX(); + mouseY = evt.getY(); + } + + mouseEvent = evt; + + switch( evt.getID() ){ + case MouseEvent.MOUSE_CLICKED: + mouseClicked(evt); + break; + case MouseEvent.MOUSE_PRESSED: + mousePressed = true; + mouseButton = evt.getButton(); + mousePressed(evt); + break; + case MouseEvent.MOUSE_RELEASED: + mousePressed = false; + mouseButton = NOBUTTON; + mousePressed(evt); + break; + case MouseEvent.MOUSE_DRAGGED: + mouseDragged(evt); + break; + case MouseEvent.MOUSE_MOVED: + mouseMoved(evt); + break; + } + } + + public void mouseClicked( MouseEvent e ) { mouseClicked(); } @@ -1005,11 +1189,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke // Intentionally left blank } - @Override - public final void mousePressed( MouseEvent e ) { - mouseEvent = e; - mousePressed = true; - mouseButton = e.getButton(); + public void mousePressed( MouseEvent e ) { mousePressed(); } @@ -1017,11 +1197,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke // Intentionally left blank } - @Override - public final void mouseReleased( MouseEvent e ) { - mouseEvent = e; - mousePressed = false; - mouseButton = NOBUTTON; + public void mouseReleased( MouseEvent e ) { mouseReleased(); } @@ -1029,19 +1205,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke // Intentionally left blank } - @Override - public final void mouseEntered( MouseEvent e ) { - // Intentionally left blank - } - - @Override - public final void mouseExited( MouseEvent e ) { - // Intentionally left blank - } - - @Override - public final void mouseDragged( MouseEvent e ) { - mouseEvent = e; + public void mouseDragged( MouseEvent e ) { mouseDragged(); } @@ -1049,9 +1213,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke // Intentionally left blank } - @Override - public final void mouseMoved( MouseEvent e ) { - mouseEvent = e; + public void mouseMoved( MouseEvent e ) { mouseMoved(); } @@ -1083,9 +1245,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke /* * Keyboard handling */ - @Override - public final void keyTyped( KeyEvent e ) { - saveKeys(e); + public void keyTyped( KeyEvent e ) { keyTyped(); } @@ -1093,10 +1253,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke // Intentionally left blank } - @Override - public final void keyPressed( KeyEvent e ) { - saveKeys(e); - keyPressed = true; + public void keyPressed( KeyEvent e ) { keyPressed(); } @@ -1104,10 +1261,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke // Intentionally left blank } - @Override - public final void keyReleased( KeyEvent e ) { - saveKeys(e); - keyPressed = false; + public void keyReleased( KeyEvent e ) { keyReleased(); } @@ -1115,12 +1269,6 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke // Intentionally left blank } - private final void saveKeys( KeyEvent event ) { - keyEvent = event; - key = event.getKeyChar(); - keyCode = event.getKeyCode(); - } - // Window changes public void fullscreenChanged() { // Intentionally left blank @@ -1161,7 +1309,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke delta = (System.nanoTime() - beforeTime) / 1000000000.0; beforeTime = System.nanoTime(); - saveMousePosition(mouseEvent); + //saveMousePosition(mouseEvent); if( state != Options.AppState.PAUSED ) { handleUpdate(delta); @@ -1172,6 +1320,8 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke // canvas.invalidate(); // frame.repaint(); } + + dispatchEvents(); } // delta time in ns @@ -1190,7 +1340,6 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke overslept = (System.nanoTime() - afterTime) - sleep; } else { overslept = 0L; - } _tick += 1;