mirror of
https://github.com/jneug/zeichenmaschine.git
synced 2026-04-14 14:43:33 +02:00
Refactorings und Dokumentation
This commit is contained in:
@@ -2,6 +2,7 @@ package schule.ngb.zm;
|
|||||||
|
|
||||||
import schule.ngb.zm.util.ImageLoader;
|
import schule.ngb.zm.util.ImageLoader;
|
||||||
|
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@@ -71,6 +72,11 @@ public class Constants {
|
|||||||
public static final Color BROWN = Color.BROWN;
|
public static final Color BROWN = Color.BROWN;
|
||||||
|
|
||||||
public static final Color STD_BACKGROUND = new Color(200, 200, 200);
|
public static final Color STD_BACKGROUND = new Color(200, 200, 200);
|
||||||
|
|
||||||
|
public static final int NOBUTTON = MouseEvent.NOBUTTON;
|
||||||
|
public static final int BUTTON1 = MouseEvent.BUTTON1;
|
||||||
|
public static final int BUTTON2 = MouseEvent.BUTTON2;
|
||||||
|
public static final int BUTTON3 = MouseEvent.BUTTON3;
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ public final class Options {
|
|||||||
INITIALIZING,
|
INITIALIZING,
|
||||||
INITIALIZED,
|
INITIALIZED,
|
||||||
RUNNING,
|
RUNNING,
|
||||||
AUSED,
|
UPDATING,
|
||||||
|
DRAWING,
|
||||||
|
PAUSED,
|
||||||
STOPPED,
|
STOPPED,
|
||||||
TERMINATED
|
TERMINATED
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ package schule.ngb.zm;
|
|||||||
|
|
||||||
import schule.ngb.zm.shapes.ShapesLayer;
|
import schule.ngb.zm.shapes.ShapesLayer;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.Canvas;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Toolkit;
|
||||||
import java.awt.image.BufferStrategy;
|
import java.awt.image.BufferStrategy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -12,7 +15,7 @@ import java.util.LinkedList;
|
|||||||
* mehreren Ebenen, auf denen auf verschiedene Arten gezeichnet werden kann. Die
|
* mehreren Ebenen, auf denen auf verschiedene Arten gezeichnet werden kann. Die
|
||||||
* Ebenen lassen sich beliebig übereinander aNORTHen, ausblenden oder wieder
|
* Ebenen lassen sich beliebig übereinander aNORTHen, ausblenden oder wieder
|
||||||
* löschen.
|
* löschen.
|
||||||
*
|
* <p>
|
||||||
* Jede Ebene besitzt eine Zeichenfläche, auf der ihre Zeichnung liegt. Diese
|
* Jede Ebene besitzt eine Zeichenfläche, auf der ihre Zeichnung liegt. Diese
|
||||||
* zeichenflächen werden pro Frame einmal von "DOWN" nach "UP" auf diese
|
* zeichenflächen werden pro Frame einmal von "DOWN" nach "UP" auf diese
|
||||||
* Leinwand gezeichnet.
|
* Leinwand gezeichnet.
|
||||||
@@ -40,7 +43,7 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
* Ändert die Größe der Zeichenleinwand auf die angegebene Größe in Pixeln.
|
* Ändert die Größe der Zeichenleinwand auf die angegebene Größe in Pixeln.
|
||||||
* Eine Größenänderung hat auch eine Größenänderung aller Ebenen zur Folge.
|
* Eine Größenänderung hat auch eine Größenänderung aller Ebenen zur Folge.
|
||||||
*
|
*
|
||||||
* @param width Neue Width der Leinwand in Pixeln.
|
* @param width Neue Width der Leinwand in Pixeln.
|
||||||
* @param height Neue Höhe der Leinwand in Pixeln.
|
* @param height Neue Höhe der Leinwand in Pixeln.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -59,6 +62,7 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
/**
|
/**
|
||||||
* Fügt der Zeichenleinwand eine Ebene hinzu, die oberhalb aller bisherigen
|
* Fügt der Zeichenleinwand eine Ebene hinzu, die oberhalb aller bisherigen
|
||||||
* Ebenen eingefügt wird.
|
* Ebenen eingefügt wird.
|
||||||
|
*
|
||||||
* @param layer Die neue Ebene.
|
* @param layer Die neue Ebene.
|
||||||
*/
|
*/
|
||||||
public void addLayer( Layer layer ) {
|
public void addLayer( Layer layer ) {
|
||||||
@@ -72,7 +76,8 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fügt der Zeichenleinwand eine Ebene an einer bestimmten Stelle hinzu.
|
* Fügt der Zeichenleinwand eine Ebene an einer bestimmten Stelle hinzu.
|
||||||
* @param i Index der Ebene, beginnend mit <code>0</code>.
|
*
|
||||||
|
* @param i Index der Ebene, beginnend mit <code>0</code>.
|
||||||
* @param layer Die neue Ebene.
|
* @param layer Die neue Ebene.
|
||||||
*/
|
*/
|
||||||
public void addLayer( int i, Layer layer ) {
|
public void addLayer( int i, Layer layer ) {
|
||||||
@@ -84,8 +89,18 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Anzahl der {@link Layer Ebenen} in dieser Leinwand zurück.
|
||||||
|
*
|
||||||
|
* @return Die Anzahl der Ebenen.
|
||||||
|
*/
|
||||||
|
public int getLayerCount() {
|
||||||
|
return layers.size();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt die Liste der bisher hinzugefügten Ebenen zurück.
|
* Gibt die Liste der bisher hinzugefügten Ebenen zurück.
|
||||||
|
*
|
||||||
* @return Liste der Ebenen.
|
* @return Liste der Ebenen.
|
||||||
*/
|
*/
|
||||||
public java.util.List<Layer> getLayers() {
|
public java.util.List<Layer> getLayers() {
|
||||||
@@ -193,7 +208,7 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
} while( strategy.contentsRestored() );
|
} while( strategy.contentsRestored() );
|
||||||
|
|
||||||
// Display the buffer
|
// Display the buffer
|
||||||
if (!strategy.contentsLost()) {
|
if( !strategy.contentsLost() ) {
|
||||||
strategy.show();
|
strategy.show();
|
||||||
|
|
||||||
Toolkit.getDefaultToolkit().sync();
|
Toolkit.getDefaultToolkit().sync();
|
||||||
@@ -204,4 +219,5 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ import java.io.IOException;
|
|||||||
*/
|
*/
|
||||||
public class Zeichenmaschine extends Constants implements MouseInputListener, KeyListener {
|
public class Zeichenmaschine extends Constants implements MouseInputListener, KeyListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt an, ob die Zeichenmaschine aus BlueJ heraus gestartet wurde.
|
||||||
|
*/
|
||||||
public static boolean IN_BLUEJ;
|
public static boolean IN_BLUEJ;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@@ -30,114 +33,240 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Attributes to be accessed by subclasses.
|
* Objektvariablen, die von Unterklassen benutzt werden können.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Leinwand, auf die alles gezeichnet wird. Die Leinwand enthält
|
||||||
|
* {@link Layer Ebenen}, die einzelne Zeichnungen enthalten. Die Inhalte
|
||||||
|
* aller Ebenen werden einmal pro Frame auf die Hauptleinwand übertragen.
|
||||||
|
*/
|
||||||
protected Zeichenleinwand canvas;
|
protected Zeichenleinwand canvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ebene mit der Hintergrundfarbe.
|
||||||
|
*/
|
||||||
protected ColorLayer background;
|
protected ColorLayer background;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zeichenebene
|
||||||
|
*/
|
||||||
protected DrawingLayer drawing;
|
protected DrawingLayer drawing;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formenebene
|
||||||
|
*/
|
||||||
protected ShapesLayer shapes;
|
protected ShapesLayer shapes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Anzahl der Ticks (Frames), die das Programm bisher läuft.
|
||||||
|
*/
|
||||||
protected int tick = 0;
|
protected int tick = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Zeit in Millisekunden, die das Programm seit seinem Start läuft.
|
||||||
|
*/
|
||||||
protected long runtime = 0L;
|
protected long runtime = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Zeitunterschied zum letzten Frame in Sekunden.
|
||||||
|
*/
|
||||||
protected double delta = 0.0;
|
protected double delta = 0.0;
|
||||||
|
|
||||||
protected double mouseX = 0.0, mouseY = 0.0, pmouseX = 0.0, pmouseY = 0.0;
|
/**
|
||||||
|
* Die aktuelle {@code x}-Koordinate der Maus.
|
||||||
|
*/
|
||||||
|
protected double mouseX = 0.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die aktuelle {@code y}-Koordinate der Maus.
|
||||||
|
*/
|
||||||
|
protected double mouseY = 0.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die letzte {@code x}-Koordinate der Maus (wird einmal pro Frame
|
||||||
|
* aktualisiert).
|
||||||
|
*/
|
||||||
|
protected double pmouseX = 0.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die letzte {@code y}-Koordinate der Maus (wird einmal pro Frame
|
||||||
|
* aktualisiert).
|
||||||
|
*/
|
||||||
|
protected double pmouseY = 0.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt an, ob ein Mausknopf derzeit gedrückt ist.
|
||||||
|
*/
|
||||||
protected boolean mousePressed = false;
|
protected boolean mousePressed = false;
|
||||||
|
|
||||||
protected int mouseButton = 0;
|
/**
|
||||||
|
* Der aktuell gedrückte Mausknopf. Die Mausknöpfe werden durch die Konstanten
|
||||||
|
* {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2} und {@link #BUTTON3}
|
||||||
|
* angegeben. (Sie stimmen mit den Konstanten in {@link MouseEvent} überein.
|
||||||
|
*
|
||||||
|
* @see MouseEvent
|
||||||
|
*/
|
||||||
|
protected int mouseButton = NOBUTTON;
|
||||||
|
|
||||||
protected char key = ' ';
|
/**
|
||||||
|
* Das zuletzt ausgelöste {@code MouseEvent}.
|
||||||
protected int keyCode = 0;
|
*/
|
||||||
|
protected MouseEvent mouseEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt an, ob derzeit eine Taste gedrückt ist.
|
||||||
|
*/
|
||||||
protected boolean keyPressed = false;
|
protected boolean keyPressed = false;
|
||||||
|
|
||||||
protected int width, height;
|
/**
|
||||||
|
* Das Zeichen der zuletzt gedrückten Taste.
|
||||||
|
*/
|
||||||
|
protected char key = ' ';
|
||||||
|
|
||||||
protected int screenWidth, screenHeight;
|
/**
|
||||||
|
* Der Tastencode der zuletzt gedrückten Taste. Die Keycodes können in der
|
||||||
|
* Klasse {@link KeyEvent} nachgesehen werden. (Zum Beispiel
|
||||||
|
* {@link KeyEvent#VK_ENTER}.)
|
||||||
|
*/
|
||||||
|
protected int keyCode = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Das zuletzt ausgelöste {@link KeyEvent}.
|
||||||
|
*/
|
||||||
|
protected KeyEvent keyEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Höhe der Zeichenleinwand.
|
||||||
|
*/
|
||||||
|
protected int width;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Breite der Zeichenleinwand.
|
||||||
|
*/
|
||||||
|
protected int height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Breite des Bildschirms, auf dem das Zeichenfenster geöffnet wurde.
|
||||||
|
* <p>
|
||||||
|
* Beachte, dass sich die Breite nicht anpasst, wenn das Zeichenfenster auf
|
||||||
|
* einen anderen Bildschirm verschoben wird.
|
||||||
|
*/
|
||||||
|
protected int screenWidth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Höhe des Bildschirms, auf dem das Zeichenfenster geöffnet wurde.
|
||||||
|
* <p>
|
||||||
|
* Beachte, dass sich die Höhe nicht anpasst, wenn das Zeichenfenster auf
|
||||||
|
* einen anderen Bildschirm verschoben wird.
|
||||||
|
*/
|
||||||
|
protected int screenHeight;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interne Attribute zur Steuerung der Zeichenmaschine.
|
* Interne Attribute zur Steuerung der Zeichenmaschine.
|
||||||
*/
|
*/
|
||||||
|
//@formatter:off
|
||||||
|
// Das Zeichenfenster der Zeichenmaschine
|
||||||
private JFrame frame;
|
private JFrame frame;
|
||||||
|
// Die Graphics-Objekte für das aktuelle Fenster.
|
||||||
private GraphicsEnvironment environment;
|
private GraphicsEnvironment environment;
|
||||||
|
|
||||||
private GraphicsDevice displayDevice;
|
private GraphicsDevice displayDevice;
|
||||||
|
|
||||||
private boolean running = false, isDrawing = false, isUpdating = false;
|
// Aktueller Zustand der Zeichenmaschine.
|
||||||
|
private Options.AppState state = Options.AppState.INITIALIZING;
|
||||||
|
private boolean running = false;
|
||||||
|
|
||||||
|
// Aktuelle Frames pro Sekunde der Zeichenmaschine.
|
||||||
private int framesPerSecond;
|
private int framesPerSecond;
|
||||||
|
|
||||||
|
// Hauptthread der Zeichenmaschine.
|
||||||
private Thread mainThread;
|
private Thread mainThread;
|
||||||
|
|
||||||
private boolean quitAfterTeardown = false, initialized = false;
|
// Gibt an, ob nach Ende des Hauptthreads das Programm beendet werden soll,
|
||||||
|
// oder das Zeichenfenster weiter geöffnet bleibt.
|
||||||
|
private boolean quitAfterTeardown = false;
|
||||||
|
//@formatter:on
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstellt eine neue Zeichenmaschine.
|
||||||
|
*/
|
||||||
public Zeichenmaschine() {
|
public Zeichenmaschine() {
|
||||||
this(APP_NAME + " " + APP_VERSION);
|
this(APP_NAME + " " + APP_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstellt eine neue Zeichenmaschine mit dem angegebene Titel.
|
||||||
|
*
|
||||||
|
* @param title Der Titel, der oben im Fenster steht.
|
||||||
|
*/
|
||||||
public Zeichenmaschine( String title ) {
|
public Zeichenmaschine( String title ) {
|
||||||
this(STD_WIDTH, STD_HEIGHT, title);
|
this(STD_WIDTH, STD_HEIGHT, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstellt eine neue zeichenmaschine mit einer Leinwand der angebenen
|
||||||
|
* Größe und dem angegebenen Titel.
|
||||||
|
*
|
||||||
|
* @param width Breite der {@link Zeichenleinwand Zeichenleinwand}.
|
||||||
|
* @param height Höhe der {@link Zeichenleinwand Zeichenleinwand}.
|
||||||
|
* @param title Der Titel, der oben im Fenster steht.
|
||||||
|
*/
|
||||||
public Zeichenmaschine( int width, int height, String title ) {
|
public Zeichenmaschine( int width, int height, String title ) {
|
||||||
|
// Setzen des "Look&Feel"
|
||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
} catch( Exception e ) {
|
} catch( Exception e ) {
|
||||||
System.err.println("Error setting the look and feel: " + e.getMessage());
|
System.err.println("Error setting the look and feel: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wir suchen den Bildschirm, der derzeit den Mauszeiger enthält, um
|
||||||
// Looking for the screen currently holding the mouse pointer
|
// das Zeichenfenster dort zu zentrieren.
|
||||||
// that will be used as the screen device for this Zeichenmaschine
|
|
||||||
java.awt.Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
|
java.awt.Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
|
||||||
environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||||
GraphicsDevice[] devices = environment.getScreenDevices();
|
GraphicsDevice[] devices = environment.getScreenDevices();
|
||||||
for( GraphicsDevice gd: devices ) {
|
for( GraphicsDevice gd : devices ) {
|
||||||
if( gd.getDefaultConfiguration().getBounds().contains(mouseLoc) ) {
|
if( gd.getDefaultConfiguration().getBounds().contains(mouseLoc) ) {
|
||||||
displayDevice = gd;
|
displayDevice = gd;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Keinen passenden Bildschirm gefunden. Wir nutzen den Standard.
|
||||||
if( displayDevice == null ) {
|
if( displayDevice == null ) {
|
||||||
displayDevice = environment.getDefaultScreenDevice();
|
displayDevice = environment.getDefaultScreenDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wir kennen nun den Bildschirm und können die Breite / Höhe abrufen.
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
java.awt.Rectangle displayBounds = displayDevice.getDefaultConfiguration().getBounds();
|
java.awt.Rectangle displayBounds = displayDevice.getDefaultConfiguration().getBounds();
|
||||||
this.screenWidth = (int)displayBounds.getWidth();
|
this.screenWidth = (int) displayBounds.getWidth();
|
||||||
this.screenHeight = (int)displayBounds.getHeight();
|
this.screenHeight = (int) displayBounds.getHeight();
|
||||||
|
|
||||||
|
|
||||||
|
// Erstellen des Zeichenfensters
|
||||||
frame = new JFrame(displayDevice.getDefaultConfiguration());
|
frame = new JFrame(displayDevice.getDefaultConfiguration());
|
||||||
frame.setTitle(title);
|
frame.setTitle(title);
|
||||||
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||||
|
|
||||||
|
// Erstellen der Leinwand
|
||||||
canvas = new Zeichenleinwand(width, height);
|
canvas = new Zeichenleinwand(width, height);
|
||||||
frame.add(canvas);
|
frame.add(canvas);
|
||||||
|
|
||||||
framesPerSecond = STD_FPS;
|
// Die drei Standardebenen merken, für den einfachen Zugriff aus unterklassen.
|
||||||
|
|
||||||
background = getBackgroundLayer();
|
background = getBackgroundLayer();
|
||||||
drawing = getDrawingLayer();
|
drawing = getDrawingLayer();
|
||||||
shapes = getShapesLayer();
|
shapes = getShapesLayer();
|
||||||
|
|
||||||
|
// FPS setzen
|
||||||
|
framesPerSecond = STD_FPS;
|
||||||
|
|
||||||
|
// Settings der Unterklasse aufrufen, falls das Fenster vor dem Öffnen
|
||||||
|
// verändert werden soll.
|
||||||
// TODO: When to call settings?
|
// TODO: When to call settings?
|
||||||
settings();
|
settings();
|
||||||
|
|
||||||
|
// Listener hinzufügen, um auf Maus- und Tastatureingaben zu hören.
|
||||||
canvas.addMouseListener(this);
|
canvas.addMouseListener(this);
|
||||||
canvas.addMouseMotionListener(this);
|
canvas.addMouseMotionListener(this);
|
||||||
canvas.addKeyListener(this);
|
canvas.addKeyListener(this);
|
||||||
@@ -153,40 +282,42 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fenster zusammenbauen, auf dem Bildschirm zentrieren ...
|
||||||
frame.pack();
|
frame.pack();
|
||||||
frame.setResizable(false);
|
frame.setResizable(false);
|
||||||
centerFrame();
|
centerFrame();
|
||||||
|
// ... und anzeigen!
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
// Nach dem Anzeigen kann die Pufferstrategie erstellt werden.
|
||||||
canvas.allocateBuffer();
|
canvas.allocateBuffer();
|
||||||
|
|
||||||
|
// Erstellen des Haupt-Zeichenthreads.
|
||||||
running = true;
|
running = true;
|
||||||
mainThread = new Zeichenthread();
|
mainThread = new Zeichenthread();
|
||||||
mainThread.start();
|
|
||||||
|
|
||||||
//frame.requestFocusInWindow();
|
//frame.requestFocusInWindow();
|
||||||
canvas.requestFocus();
|
canvas.requestFocus();
|
||||||
|
|
||||||
initialized = true;
|
// Fertig mit der Initialisierung!
|
||||||
|
state = Options.AppState.INITIALIZED;
|
||||||
|
// Los geht's ...
|
||||||
|
mainThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstellt ein neues Zeichenfesnter mit der aktuellen Konfiguration.
|
||||||
|
*
|
||||||
|
* @param title
|
||||||
|
*/
|
||||||
// TODO: Implement in conjunction with Zeichenfenster
|
// TODO: Implement in conjunction with Zeichenfenster
|
||||||
public final void createFrame( String title ) {
|
private final Zeichenfenster createFrame( String title ) {
|
||||||
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
public void show() {
|
|
||||||
if( !frame.isVisible() ) {
|
|
||||||
frame.setVisible(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void hide() {
|
|
||||||
if( frame.isVisible() ) {
|
|
||||||
frame.setVisible(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zentriert das Zeichenfenster auf dem aktuellen Bildschirm.
|
||||||
|
*/
|
||||||
public final void centerFrame() {
|
public final void centerFrame() {
|
||||||
// TODO: Center on current display (not main display by default)
|
// TODO: Center on current display (not main display by default)
|
||||||
// TODO: Position at current BlueJ windows if IN_BLUEJ
|
// TODO: Position at current BlueJ windows if IN_BLUEJ
|
||||||
@@ -195,11 +326,37 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
|
|
||||||
java.awt.Rectangle bounds = displayDevice.getDefaultConfiguration().getBounds();
|
java.awt.Rectangle bounds = displayDevice.getDefaultConfiguration().getBounds();
|
||||||
frame.setLocation(
|
frame.setLocation(
|
||||||
(int)(bounds.x + (screenWidth-frame.getWidth())/2.0),
|
(int) (bounds.x + (screenWidth - frame.getWidth()) / 2.0),
|
||||||
(int)(bounds.y + (screenHeight-frame.getHeight())/2.0)
|
(int) (bounds.y + (screenHeight - frame.getHeight()) / 2.0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zeigt das Zeichenfenster an.
|
||||||
|
*
|
||||||
|
* @see JFrame#setVisible(boolean)
|
||||||
|
*/
|
||||||
|
public void show() {
|
||||||
|
if( !frame.isVisible() ) {
|
||||||
|
frame.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Versteckt das Zeichenfenster.
|
||||||
|
*
|
||||||
|
* @see JFrame#setVisible(boolean)
|
||||||
|
*/
|
||||||
|
public void hide() {
|
||||||
|
if( frame.isVisible() ) {
|
||||||
|
frame.setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zeichnet die {@link Zeichenleinwand} neu und zeigt den aktuellen Inhalt
|
||||||
|
* im Zeichenfenster an.
|
||||||
|
*/
|
||||||
public final void redraw() {
|
public final void redraw() {
|
||||||
canvas.render();
|
canvas.render();
|
||||||
//canvas.invalidate();
|
//canvas.invalidate();
|
||||||
@@ -208,15 +365,30 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
//show();
|
//show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stoppt den Zeichenthread. Nachdem der aktuelle Frame gezeichnet wurde
|
||||||
|
* wird {@link #teardown()} aufgerufen. Das Programm wird nicht beendet und
|
||||||
|
* das Zeichenfenster bleibt weiter angezeigt.
|
||||||
|
*/
|
||||||
public final void stop() {
|
public final void stop() {
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Beendet das Programm.
|
||||||
|
*/
|
||||||
public void quit() {
|
public void quit() {
|
||||||
//quit(!IN_BLUEJ);
|
//quit(!IN_BLUEJ);
|
||||||
quit(true);
|
quit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Beendet das Programm. Falls <var>exit</var> gleich {@code true} ist,
|
||||||
|
* wird die komplette Virtuelle Maschine beendet.
|
||||||
|
*
|
||||||
|
* @param exit Ob die VM beendet werden soll.
|
||||||
|
* @see System#exit(int)
|
||||||
|
*/
|
||||||
public void quit( boolean exit ) {
|
public void quit( boolean exit ) {
|
||||||
frame.setVisible(false);
|
frame.setVisible(false);
|
||||||
canvas.dispose();
|
canvas.dispose();
|
||||||
@@ -227,6 +399,12 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setzte die Größe der {@link Zeichenleinwand}.
|
||||||
|
*
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
*/
|
||||||
public final void setSize( int width, int height ) {
|
public final void setSize( int width, int height ) {
|
||||||
//frame.setSize(width, height);
|
//frame.setSize(width, height);
|
||||||
|
|
||||||
@@ -235,30 +413,103 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
}
|
}
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
|
||||||
frame.pack();
|
frame.pack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Breite der {@link Zeichenleinwand}.
|
||||||
|
*
|
||||||
|
* @return Die Breite der {@link Zeichenleinwand}.
|
||||||
|
*/
|
||||||
public final int getWidth() {
|
public final int getWidth() {
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Höhe der {@link Zeichenleinwand}.
|
||||||
|
*
|
||||||
|
* @return Die Höhe der {@link Zeichenleinwand}.
|
||||||
|
*/
|
||||||
public final int getHeight() {
|
public final int getHeight() {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setTitle( String pTitel ) {
|
/**
|
||||||
frame.setTitle(pTitel);
|
* Setzt den Titel des Zeichenfensters.
|
||||||
|
*
|
||||||
|
* @param title Der Titel, der oben im Zeichenfenster angezeigt wird.
|
||||||
|
*/
|
||||||
|
public final void setTitle( String title ) {
|
||||||
|
frame.setTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Zeichenleinwand zurück.
|
||||||
|
*
|
||||||
|
* @return Die Zeichenleinwand.
|
||||||
|
*/
|
||||||
public final Zeichenleinwand getCanvas() {
|
public final Zeichenleinwand getCanvas() {
|
||||||
return canvas;
|
return canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fügt der {@link Zeichenleinwand} eine weitere {@link Layer Ebene}
|
||||||
|
* hinzu.
|
||||||
|
*
|
||||||
|
* @param layer Die neue Ebene.
|
||||||
|
*/
|
||||||
public final void addLayer( Layer layer ) {
|
public final void addLayer( Layer layer ) {
|
||||||
canvas.addLayer(layer);
|
canvas.addLayer(layer);
|
||||||
layer.setSize(getWidth(), getHeight());
|
layer.setSize(getWidth(), getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Anzahl der {@link Layer Ebenen} in der {@link Zeichenleinwand}
|
||||||
|
* zurück.
|
||||||
|
*
|
||||||
|
* @return Die Anzahl der Ebenen.
|
||||||
|
*/
|
||||||
|
public int getLayerCount() {
|
||||||
|
return canvas.getLayerCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die {@link Layer Ebene} am angegebenen Index zurück. Gibt es keine
|
||||||
|
* Ebene mit diesem Index.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public final Layer getLayer( int index ) {
|
||||||
|
return canvas.getLayer(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die erste (unterste) {@link Layer Ebene} der angegebenen Klasse
|
||||||
|
* zurück.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* DrawingLayer draw = getLayer(DrawingLayer.class);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param layerClass
|
||||||
|
* @param <LT>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public final <LT extends Layer> LT getLayer( Class<LT> layerClass ) {
|
||||||
|
return canvas.getLayer(layerClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die {@link ColorLayer Ebene} mit der Hintergrundfarbe zurück. Gibt es
|
||||||
|
* keine solche Ebene, so wird eine erstellt und der {@link Zeichenleinwand}
|
||||||
|
* hinzugefügt.
|
||||||
|
* <p>
|
||||||
|
* In der Regel sollte dies dieselbe Ebene sein wie {@link #background}.
|
||||||
|
*
|
||||||
|
* @return Die Hintergrundebene.
|
||||||
|
*/
|
||||||
public final ColorLayer getBackgroundLayer() {
|
public final ColorLayer getBackgroundLayer() {
|
||||||
ColorLayer layer = canvas.getLayer(ColorLayer.class);
|
ColorLayer layer = canvas.getLayer(ColorLayer.class);
|
||||||
if( layer == null ) {
|
if( layer == null ) {
|
||||||
@@ -268,6 +519,15 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Standard-{@link DrawingLayer Zeichenebene} zurück. Gibt es
|
||||||
|
* keine solche Ebene, so wird eine erstellt und der {@link Zeichenleinwand}
|
||||||
|
* hinzugefügt.
|
||||||
|
* <p>
|
||||||
|
* In der Regel sollte dies dieselbe Ebene sein wie {@link #drawing}.
|
||||||
|
*
|
||||||
|
* @return Die Zeichenebene.
|
||||||
|
*/
|
||||||
public final DrawingLayer getDrawingLayer() {
|
public final DrawingLayer getDrawingLayer() {
|
||||||
DrawingLayer layer = canvas.getLayer(DrawingLayer.class);
|
DrawingLayer layer = canvas.getLayer(DrawingLayer.class);
|
||||||
if( layer == null ) {
|
if( layer == null ) {
|
||||||
@@ -277,6 +537,15 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Standard-{@link ShapesLayer Formenebene} zurück. Gibt es
|
||||||
|
* keine solche Ebene, so wird eine erstellt und der {@link Zeichenleinwand}
|
||||||
|
* hinzugefügt.
|
||||||
|
* <p>
|
||||||
|
* In der Regel sollte dies dieselbe Ebene sein wie {@link #shapes}.
|
||||||
|
*
|
||||||
|
* @return Die Formenebene.
|
||||||
|
*/
|
||||||
public final ShapesLayer getShapesLayer() {
|
public final ShapesLayer getShapesLayer() {
|
||||||
ShapesLayer layer = canvas.getLayer(ShapesLayer.class);
|
ShapesLayer layer = canvas.getLayer(ShapesLayer.class);
|
||||||
if( layer == null ) {
|
if( layer == null ) {
|
||||||
@@ -286,14 +555,29 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die aktuellen Frames pro Sekunde zurück.
|
||||||
|
*
|
||||||
|
* @return Angepeilte Frames pro Sekunde
|
||||||
|
*/
|
||||||
public final int getFramesPerSecond() {
|
public final int getFramesPerSecond() {
|
||||||
return framesPerSecond;
|
return framesPerSecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setzt die Anzahl an Frames pro Sekunde auf einen neuen Wert.
|
||||||
|
*
|
||||||
|
* @param pFramesPerSecond Neue FPS.
|
||||||
|
*/
|
||||||
public final void setFramesPerSecond( int pFramesPerSecond ) {
|
public final void setFramesPerSecond( int pFramesPerSecond ) {
|
||||||
framesPerSecond = pFramesPerSecond;
|
framesPerSecond = pFramesPerSecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Speichert den aktuellen Inhalt der {@link Zeichenleinwand} in einer
|
||||||
|
* Bilddatei auf der Festplatte. Zur Auswahl der Zieldatei wird dem Nutzer
|
||||||
|
* ein {@link JFileChooser} angezeigt.
|
||||||
|
*/
|
||||||
public void saveImage() {
|
public void saveImage() {
|
||||||
JFileChooser jfc = new JFileChooser();
|
JFileChooser jfc = new JFileChooser();
|
||||||
jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
|
jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
|
||||||
@@ -309,8 +593,12 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Speichert den aktuellen Inhalt der {@link Zeichenleinwand} in einer
|
||||||
|
* Bilddatei im angegebenen Dateipfad auf der Festplatte.
|
||||||
|
*/
|
||||||
public void saveImage( String filepath ) {
|
public void saveImage( String filepath ) {
|
||||||
BufferedImage img = new BufferedImage(canvas.getWidth(),canvas.getHeight(), BufferedImage.TYPE_INT_RGB);
|
BufferedImage img = new BufferedImage(canvas.getWidth(), canvas.getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||||
|
|
||||||
Graphics2D g = img.createGraphics();
|
Graphics2D g = img.createGraphics();
|
||||||
g.setColor(STD_BACKGROUND.getColor());
|
g.setColor(STD_BACKGROUND.getColor());
|
||||||
@@ -320,13 +608,21 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
ImageLoader.saveImage(img, new File(filepath), true);
|
ImageLoader.saveImage(img, new File(filepath), true);
|
||||||
} catch ( IOException ex ) {
|
} catch( IOException ex ) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstellt eine Momentanaufnahme des aktuellen Inhalts der
|
||||||
|
* {@link Zeichenleinwand} und erstellt daraus eine {@link ImageLayer Bildebene}.
|
||||||
|
* Die Ebene wird automatisch der {@link Zeichenleinwand} vor dem
|
||||||
|
* {@link #background} hinzugefügt.
|
||||||
|
*
|
||||||
|
* @return Die neue Bildebene.
|
||||||
|
*/
|
||||||
public ImageLayer snapshot() {
|
public ImageLayer snapshot() {
|
||||||
BufferedImage img = new BufferedImage(canvas.getWidth(),canvas.getHeight(), BufferedImage.TYPE_INT_RGB);
|
BufferedImage img = new BufferedImage(canvas.getWidth(), canvas.getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||||
|
|
||||||
Graphics2D g = img.createGraphics();
|
Graphics2D g = img.createGraphics();
|
||||||
g.setColor(STD_BACKGROUND.getColor());
|
g.setColor(STD_BACKGROUND.getColor());
|
||||||
@@ -352,38 +648,22 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
return imgLayer;
|
return imgLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Methoden, die von Unterklassen überschrieben werden können / sollen.
|
* Pausiert die Schleife der Zeichenmaschine für die angegebene Anzahl an
|
||||||
|
* Millisekunden.
|
||||||
|
*
|
||||||
|
* @param ms Schlafenszeit in Millisekunden.
|
||||||
*/
|
*/
|
||||||
public void settings() {
|
public final void delay( int ms ) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setup() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void teardown() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update( double delta ) {
|
|
||||||
running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delay( int ms ) {
|
|
||||||
if( ms <= 0 ) {
|
if( ms <= 0 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long timer = 0L;
|
long timer = 0L;
|
||||||
if( isDrawing ) {
|
if( state == Options.AppState.DRAWING ) {
|
||||||
// Immediately show the current drawing before waiting
|
// Falls gerade draw() ausgeführt wird, zeigen wir den aktuellen
|
||||||
// Measure the render time and subtract from the waiting ms
|
// Stand der Zeichnung auf der Leinwand an. Die Zeit für das
|
||||||
|
// Rendern wird gemessen und von der Wartezeit abgezogen.
|
||||||
timer = System.nanoTime();
|
timer = System.nanoTime();
|
||||||
canvas.render();
|
canvas.render();
|
||||||
timer = System.nanoTime() - timer;
|
timer = System.nanoTime() - timer;
|
||||||
@@ -402,36 +682,112 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Methoden, die von Unterklassen überschrieben werden können / sollen.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Settings werden einmal beim Erstellten der Zeichenmaschine aufgerufen.
|
||||||
|
* <p>
|
||||||
|
* {@code settings()} wird nur selten benötigt, wenn das Zeichenfenster
|
||||||
|
*/
|
||||||
|
public void settings() {
|
||||||
|
// Intentionally left blank
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methode, die von Unterklassen überschrieben werden sollte, um die
|
||||||
|
* Zeichenmaschine vor dem Start zu konfigurieren. Hier können vorbereitende
|
||||||
|
* Befehle ausgeführt werden, die die {@link Zeichenleinwand} zu
|
||||||
|
* initialisieren, neue Objekte instanziieren und Variablen initialisieren.
|
||||||
|
*/
|
||||||
|
public void setup() {
|
||||||
|
// Intentionally left blank
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code update()} wird einmal pro Frame vor {@link #draw()} aufgerufen, um
|
||||||
|
* notwendige Aktualisierungen vorzunehmen. Im Gegensatz zu {@link #draw()}
|
||||||
|
* bekommt {@code update()} zusätzlich {@link #delta} übergeben, um die
|
||||||
|
* Aktualisierungen abhängig von der echten Verzögerung zwischen zwei Frames
|
||||||
|
* zu berechnen.
|
||||||
|
* <p>
|
||||||
|
* {@code delta} wird in Sekunden angegeben. Um eine Form zum Beispiel
|
||||||
|
* um {@code 50} Pixel pro Sekunde in {@code x}-Richtung zu bewegen,
|
||||||
|
* kann so vorgegangen werden:
|
||||||
|
* <pre>
|
||||||
|
* shape.move(50*delta, 0.0);
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param delta
|
||||||
|
*/
|
||||||
|
public void update( double delta ) {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code draw()} wird einmal pro Frame aufgerufen. Bei einer
|
||||||
|
* {@link #getFramesPerSecond() Framerate} von {@code 60} also in etwa 60-Mal
|
||||||
|
* pro Sekunde. In der {@code draw}-Methode wird der Inhalt der Ebenen
|
||||||
|
* manipuliert und deren Inhalte gezeichnet. Am Ende des Frames werden alle
|
||||||
|
* Ebenen auf die {@link Zeichenleinwand} übertragen.
|
||||||
|
* <p>
|
||||||
|
* {@code draw()} stellt die wichtigste Methode für eine Zeichenmaschine dar,
|
||||||
|
* da hier die Zeichnung des Programms erstellt wird.
|
||||||
|
*/
|
||||||
|
public void draw() {
|
||||||
|
// Intentionally left blank
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code teardown()} wird aufgerufen, sobald die Schleife des Hauptprogramms
|
||||||
|
* beendet wurde. Dies passiert entweder nach dem ersten Durchlauf (wenn keine
|
||||||
|
* eigene {@link #update(double)} erstellt wurde), nach dem Aufruf von
|
||||||
|
* {@link #stop()} oder nachdem das {@link Zeichenfenster} geschlossen wurde.
|
||||||
|
* <p>
|
||||||
|
* In {@code teardown()} kann zum Beispiel der Abschlussbildschirm eines
|
||||||
|
* Spiels oder der Abspann einer Animation angezeigt werden, oder mit
|
||||||
|
* {@link #saveImage()} die erstellte Zeichnung abgespeichert werden.
|
||||||
|
*/
|
||||||
|
public void teardown() {
|
||||||
|
// Intentionally left blank
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mouse handling
|
* Mouse handling
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void mouseClicked( MouseEvent e ) {
|
public final void mouseClicked( MouseEvent e ) {
|
||||||
saveMousePosition(e);
|
mouseEvent = e;
|
||||||
mouseClicked();
|
mouseClicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mouseClicked() {
|
public void mouseClicked() {
|
||||||
|
// Intentionally left blank
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void mousePressed( MouseEvent e ) {
|
public final void mousePressed( MouseEvent e ) {
|
||||||
saveMousePosition(e);
|
mouseEvent = e;
|
||||||
mousePressed = true;
|
mousePressed = true;
|
||||||
|
mouseButton = e.getButton();
|
||||||
mousePressed();
|
mousePressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mousePressed() {
|
public void mousePressed() {
|
||||||
|
// Intentionally left blank
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void mouseReleased( MouseEvent e ) {
|
public final void mouseReleased( MouseEvent e ) {
|
||||||
saveMousePosition(e);
|
mouseEvent = e;
|
||||||
mousePressed = false;
|
mousePressed = false;
|
||||||
|
mouseButton = NOBUTTON;
|
||||||
mouseReleased();
|
mouseReleased();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mouseReleased() {
|
public void mouseReleased() {
|
||||||
|
// Intentionally left blank
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -446,30 +802,32 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void mouseDragged( MouseEvent e ) {
|
public final void mouseDragged( MouseEvent e ) {
|
||||||
saveMousePosition(e);
|
mouseEvent = e;
|
||||||
mouseDragged();
|
mouseDragged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mouseDragged() {
|
public void mouseDragged() {
|
||||||
|
// Intentionally left blank
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void mouseMoved( MouseEvent e ) {
|
public final void mouseMoved( MouseEvent e ) {
|
||||||
saveMousePosition(e);
|
mouseEvent = e;
|
||||||
mouseMoved();
|
mouseMoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void mouseMoved() {
|
public void mouseMoved() {
|
||||||
|
// Intentionally left blank
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveMousePosition( MouseEvent e ) {
|
private void saveMousePosition( MouseEvent event ) {
|
||||||
pmouseX = mouseX;
|
if( mouseEvent != null && event.getComponent() == canvas ) {
|
||||||
pmouseY = mouseY;
|
pmouseX = mouseX;
|
||||||
|
pmouseY = mouseY;
|
||||||
|
|
||||||
mouseX = e.getX();
|
mouseX = event.getX();
|
||||||
mouseY = e.getY();
|
mouseY = event.getY();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveMousePosition() {
|
private void saveMousePosition() {
|
||||||
@@ -493,7 +851,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void keyTyped() {
|
public void keyTyped() {
|
||||||
|
// Intentionally left blank
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -504,7 +862,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void keyPressed() {
|
public void keyPressed() {
|
||||||
|
// Intentionally left blank
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -515,12 +873,13 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void keyReleased() {
|
public void keyReleased() {
|
||||||
|
// Intentionally left blank
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void saveKeys( KeyEvent e ) {
|
private final void saveKeys( KeyEvent event ) {
|
||||||
key = e.getKeyChar();
|
keyEvent = event;
|
||||||
keyCode = e.getKeyCode();
|
key = event.getKeyChar();
|
||||||
|
keyCode = event.getKeyCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
class Zeichenthread extends Thread {
|
class Zeichenthread extends Thread {
|
||||||
@@ -528,7 +887,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
@Override
|
@Override
|
||||||
public final void run() {
|
public final void run() {
|
||||||
// Wait for full initialization before start
|
// Wait for full initialization before start
|
||||||
while( !initialized ) {
|
while( state != Options.AppState.INITIALIZED ) {
|
||||||
delay(1);
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,12 +907,13 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
// call setup of subclass
|
// call setup of subclass
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
|
state = Options.AppState.RUNNING;
|
||||||
while( running ) {
|
while( running ) {
|
||||||
// delta in seconds
|
// delta in seconds
|
||||||
delta = (System.nanoTime() - beforeTime) / 1000000000.0;
|
delta = (System.nanoTime() - beforeTime) / 1000000000.0;
|
||||||
beforeTime = System.nanoTime();
|
beforeTime = System.nanoTime();
|
||||||
|
|
||||||
//saveMousePosition();
|
saveMousePosition(mouseEvent);
|
||||||
|
|
||||||
handleUpdate(delta);
|
handleUpdate(delta);
|
||||||
handleDraw();
|
handleDraw();
|
||||||
@@ -588,29 +948,30 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
|||||||
tick = _tick;
|
tick = _tick;
|
||||||
runtime = _runtime;
|
runtime = _runtime;
|
||||||
}
|
}
|
||||||
|
state = Options.AppState.STOPPED;
|
||||||
|
|
||||||
teardown();
|
teardown();
|
||||||
|
state = Options.AppState.TERMINATED;
|
||||||
|
|
||||||
if( quitAfterTeardown ) {
|
if( quitAfterTeardown ) {
|
||||||
quit();
|
quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleUpdate( double delta ) {
|
public void handleUpdate( double delta ) {
|
||||||
if( isUpdating ) {
|
if( state == Options.AppState.RUNNING ) {
|
||||||
return;
|
state = Options.AppState.UPDATING;
|
||||||
|
update(delta);
|
||||||
|
state = Options.AppState.RUNNING;
|
||||||
}
|
}
|
||||||
isUpdating = true;
|
|
||||||
update(delta);
|
|
||||||
isUpdating = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleDraw() {
|
public void handleDraw() {
|
||||||
if( isDrawing ) {
|
if( state == Options.AppState.RUNNING ) {
|
||||||
return;
|
state = Options.AppState.DRAWING;
|
||||||
|
draw();
|
||||||
|
state = Options.AppState.RUNNING;
|
||||||
}
|
}
|
||||||
isDrawing = true;
|
|
||||||
draw();
|
|
||||||
isDrawing = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user