Hallo liebes Forum,
ich arbeite mich derzeit in Swing und AWT ein und mir sind zwei Dinge grundsätzlich unklar. Es wäre super, wenn mir jemand helfen könnte und die Unklarheiten beseitigen könnte. Anbei ein Codeschnipsel aus dem Buch "Handbuch der Java Programmierung" (Listing3409), das ich deutlich reduziert und auf Swing umgestellt (JFrame statt Frame) habe. Ich hoffe, ihr verzeiht mir, dass das hier sicher nicht als Minimalbeispiel durchgeht, aber ich kann so am besten mein Problem erklären.
[Java] package code;
/*basiert auf Listing3409.java aus Handbuch der Java-Programmierung */
import java.awt.*;
import java.util.*;
import javax.swing.JFrame;
public class Minimalbeispiel
extends JFrame
implements Runnable
{
//Konstanten
private static final int SLEEP = 200;
//Instanzvariablen
private Thread th;
private Vector snake;
protected int dx;
protected int dy;
public static void main(String[] args)
{
Minimalbeispiel frame = new Minimalbeispiel();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize(d);
frame.setVisible(true);
frame.startAnimation();
}
public Minimalbeispiel()
{
super("Animierte Schlange");
setBackground(Color.LIGHT_GRAY);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
snake = new Vector();
}
public void startAnimation()
{
th = new Thread(this);
th.start();
}
public void run()
{
//Schlange konstruieren
Rectangle cr;
int x = 100;
int y = 100;
for (int i=0; i < 5; ++i) {
cr = new Rectangle(x, y, 20, 20);
x += 20;
snake.addElement(cr);
}
//Vorzugsrichtung festlegen
dx = 1;
dy = 0;
//Schlange laufen lassen
while (true) {
try {
Thread.sleep(SLEEP);
} catch (InterruptedException e){
//nichts
}
moveSnake();
//Was macht hier repaint()? Scheinbar nicht alles neu zeichnen, was passiert, wenn ich die Fenstergröße ändere
repaint();
}
}
public void moveSnake()
{
Dimension size = getSize();
int sizex = size.width-getInsets().left-getInsets().right;
int sizey = size.height-getInsets().top-getInsets().bottom;
Rectangle cr = (Rectangle)snake.firstElement();
int xalt, yalt;
int xtmp, ytmp;
xalt = cr.x + 20 * dx;
yalt = cr.y + 20 * dy;
//Rest der Schlange hinterherziehen
Enumeration e = snake.elements();
while (e.hasMoreElements()) {
cr = (Rectangle)e.nextElement();
xtmp = cr.x;
ytmp = cr.y;
cr.x = xalt;
cr.y = yalt;
xalt = xtmp;
yalt = ytmp;
}
}
//public void paintComponent(Graphics g) funktioniert nicht
public void paint(Graphics g)
{
Rectangle cr;
Enumeration e = snake.elements();
while (e.hasMoreElements()) {
cr = (Rectangle)e.nextElement();
g.setColor(Color.black);
g.fillRect(cr.x,cr.y,cr.width,cr.height);
}
}
}[/Java]
Wenn ihr das Beispiel kompiliert, sollte sich eine Schlange von links nach rechts auf den Weg machen. Zwei Verständnisfragen nun: Wenn man die Fenstergröße ändert, wird die Schlange auf ihre ursprüngliche Größe reduziert, ansonsten wächst sie. Ich kann mir das nur so erklären: Fenster ändert sich ==> System-triggered Event ==> Paint() wird aufgerufen ==> Schlange wird neu gezeichnet und Schlange ist nunmal nur 5 Rechtecke groß. Tut man nichts, wächst die Schlange für den Betrachter einfach deshalb, weil die alten Rechtecke nicht gelöscht werden.
Falls ich das aber richtig verstehe, was macht dann repaint in der run-Methode (Zeile 69) ? Sollte repaint() nicht auch paint aufrufen und damit die Schlange neu zeichnen (damit ich eben eine immer gleich große Schlange und keine wachsende habe).
Meine zweite Frage bezieht sich auf paint(): Dieser Link von Sun (Painting in AWT and Swing) empfiehlt, nie paint zu überschreiben, stattdessen nur paintComponent(). Das klingt dort so, als ob es immer vollkommen ausreichend sei, nur paintComponent zu überschreiben. Mache ich das aber hier (Zeile 97), tut sich einfach nichts. Warum? Wo liegt mein Denkfehler?
Verzeiht die langen Ausführungen zu später Stunde. Trotzdem hoffe ich auf Eure Hilfe.
Grüße Christoph
ich arbeite mich derzeit in Swing und AWT ein und mir sind zwei Dinge grundsätzlich unklar. Es wäre super, wenn mir jemand helfen könnte und die Unklarheiten beseitigen könnte. Anbei ein Codeschnipsel aus dem Buch "Handbuch der Java Programmierung" (Listing3409), das ich deutlich reduziert und auf Swing umgestellt (JFrame statt Frame) habe. Ich hoffe, ihr verzeiht mir, dass das hier sicher nicht als Minimalbeispiel durchgeht, aber ich kann so am besten mein Problem erklären.
[Java] package code;
/*basiert auf Listing3409.java aus Handbuch der Java-Programmierung */
import java.awt.*;
import java.util.*;
import javax.swing.JFrame;
public class Minimalbeispiel
extends JFrame
implements Runnable
{
//Konstanten
private static final int SLEEP = 200;
//Instanzvariablen
private Thread th;
private Vector snake;
protected int dx;
protected int dy;
public static void main(String[] args)
{
Minimalbeispiel frame = new Minimalbeispiel();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize(d);
frame.setVisible(true);
frame.startAnimation();
}
public Minimalbeispiel()
{
super("Animierte Schlange");
setBackground(Color.LIGHT_GRAY);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
snake = new Vector();
}
public void startAnimation()
{
th = new Thread(this);
th.start();
}
public void run()
{
//Schlange konstruieren
Rectangle cr;
int x = 100;
int y = 100;
for (int i=0; i < 5; ++i) {
cr = new Rectangle(x, y, 20, 20);
x += 20;
snake.addElement(cr);
}
//Vorzugsrichtung festlegen
dx = 1;
dy = 0;
//Schlange laufen lassen
while (true) {
try {
Thread.sleep(SLEEP);
} catch (InterruptedException e){
//nichts
}
moveSnake();
//Was macht hier repaint()? Scheinbar nicht alles neu zeichnen, was passiert, wenn ich die Fenstergröße ändere
repaint();
}
}
public void moveSnake()
{
Dimension size = getSize();
int sizex = size.width-getInsets().left-getInsets().right;
int sizey = size.height-getInsets().top-getInsets().bottom;
Rectangle cr = (Rectangle)snake.firstElement();
int xalt, yalt;
int xtmp, ytmp;
xalt = cr.x + 20 * dx;
yalt = cr.y + 20 * dy;
//Rest der Schlange hinterherziehen
Enumeration e = snake.elements();
while (e.hasMoreElements()) {
cr = (Rectangle)e.nextElement();
xtmp = cr.x;
ytmp = cr.y;
cr.x = xalt;
cr.y = yalt;
xalt = xtmp;
yalt = ytmp;
}
}
//public void paintComponent(Graphics g) funktioniert nicht
public void paint(Graphics g)
{
Rectangle cr;
Enumeration e = snake.elements();
while (e.hasMoreElements()) {
cr = (Rectangle)e.nextElement();
g.setColor(Color.black);
g.fillRect(cr.x,cr.y,cr.width,cr.height);
}
}
}[/Java]
Wenn ihr das Beispiel kompiliert, sollte sich eine Schlange von links nach rechts auf den Weg machen. Zwei Verständnisfragen nun: Wenn man die Fenstergröße ändert, wird die Schlange auf ihre ursprüngliche Größe reduziert, ansonsten wächst sie. Ich kann mir das nur so erklären: Fenster ändert sich ==> System-triggered Event ==> Paint() wird aufgerufen ==> Schlange wird neu gezeichnet und Schlange ist nunmal nur 5 Rechtecke groß. Tut man nichts, wächst die Schlange für den Betrachter einfach deshalb, weil die alten Rechtecke nicht gelöscht werden.
Falls ich das aber richtig verstehe, was macht dann repaint in der run-Methode (Zeile 69) ? Sollte repaint() nicht auch paint aufrufen und damit die Schlange neu zeichnen (damit ich eben eine immer gleich große Schlange und keine wachsende habe).
Meine zweite Frage bezieht sich auf paint(): Dieser Link von Sun (Painting in AWT and Swing) empfiehlt, nie paint zu überschreiben, stattdessen nur paintComponent(). Das klingt dort so, als ob es immer vollkommen ausreichend sei, nur paintComponent zu überschreiben. Mache ich das aber hier (Zeile 97), tut sich einfach nichts. Warum? Wo liegt mein Denkfehler?
Verzeiht die langen Ausführungen zu später Stunde. Trotzdem hoffe ich auf Eure Hilfe.
Grüße Christoph