JLabel animazione JPanel
Domanda
Dopo aver grattato in giro ho trovato che è meglio per implementare un componente un'immagine personalizzata estendendo un JLabel. Finora che ha funzionato grande come posso aggiungere più "immagini" (jlabels senza il layout rompersi. Ho solo una domanda che spero che qualcuno può rispondere per me.
- Ho notato che per animare JLabels attraverso lo schermo che ho bisogno di
setlayout(null);
esetbounds
del componente e poi animare finesetlocation(x,y);
. Si tratta di una delle migliori pratiche o di un modo terribile per animare un componente? Ho intenzione di fare finalmente una classe di animazione, ma io non voglio farlo e finiscono per dover buttarla.
Ho incluso relativo codice per un controllo rapido esame.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.Timer;
public class GraphicsPanel extends JPanel {
private Timer timer;
private long startTime = 0;
private int numFrames = 0;
private float fps = 0.0f;
private int x = 0;
GraphicsPanel() {
final Entity ent1 = new Entity();
ent1.setBounds(x, 0, ent1.getWidth(), ent1.getHeight());
add(ent1);
//ESSENTIAL
setLayout(null);
//GAMELOOP
timer = new Timer(30, new ActionListener() {
public void actionPerformed(ActionEvent e) {
getFPS();
incX();
ent1.setLocation(x, 0);
repaint();
}
});
timer.start();
}
public void incX() { x++; }
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setClip(0, 0, getWidth(), getHeight());
g2.setColor(Color.BLACK);
g2.drawString("FPS: " + fps, 1, 15);
}
public void getFPS()
{
++numFrames;
if (startTime == 0) {
startTime = System.currentTimeMillis();
} else {
long currentTime = System.currentTimeMillis();
long delta = (currentTime - startTime);
if (delta > 1000) {
fps = (numFrames * 1000) / delta;
numFrames = 0;
startTime = currentTime;
}
}
}
}
Grazie!
Soluzione
Ho notato che, al fine di animare JLabels sullo schermo ho bisogno di setLayout (null); e setBounds della componente e poi animare casualmente setLocation (x, y) ;. È questo una best practice o un modo terribile per animare una componente?
Bene, questo non è del tutto vero. Si può solo giocare con la posizione e l'etichetta si muoverà intorno allo schermo. Tuttavia, se mai ridimensiona la cornice o nulla allora il gestore di layout verrà invocato e l'etichetta verrà riposizionato e la posizione definita dal gestore di layout, che nel caso di un FlowLayout sarà la parte superiore / sinistra del pannello. Animazione proseguirà poi da quella posizione. Quindi, in realtà, sì, questo è esattamente ciò che devi fare.
Lo trovo il modo più semplice per fare animazione in quanto Swing ridisegnare automaticamente l ' "ultima" posizione del componente (per ripristinare lo sfondo), così come dipingere la nuova posizione del componente. Tutto ciò si ottiene con un metodo singolo setLocation ().
Alcune persone piace fare pittura personalizzata disegnando l'immagine direttamente sul pannello, ma poi si sono responsabili per cancellare la vecchia posizione dell'immagine in modo che il fondo viene ridisegnato e quindi disegnare l'immagine nella nuova posizione. Trovo che questo sia troppo lavoro.