Анимация JLabel в JPanel
Вопрос
Поковырявшись, я обнаружил, что лучше всего реализовать пользовательский компонент изображения, расширив JLabel.До сих пор это отлично работало, так как я могу добавить несколько "изображений" (jlabels) без нарушения макета.У меня просто есть вопрос, на который, я надеюсь, кто-нибудь сможет ответить за меня.
- Я заметил, что для анимации JLabels по экрану мне нужно
setlayout(null);
иsetbounds
компонента, а затем, в конечном счете, анимироватьsetlocation(x,y);
.Это лучшая практика или ужасный способ анимировать компонент?Я планирую в конечном итоге создать класс анимации, но я не хочу этого делать, и в конечном итоге мне придется отказаться от него.
Я включил соответствующий код для быстрой проверки.
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;
}
}
}
}
Спасибо!
Решение
Я заметил, что для анимации JLabels по экрану мне нужно setlayout(null);и установить границы компонента, а затем анимировать в конечном итоге setlocation(x,y);.Это лучшая практика или ужасный способ анимировать компонент?
Ну, это не совсем так.Вы можете просто поиграть с местоположением, и метка будет перемещаться по экрану.Однако, если вы когда-либо измените размер рамки или чего-либо еще, тогда будет вызван менеджер компоновки, и метка будет перемещена, а местоположение определено менеджером компоновки, которое в случае FlowLayout будет в верхней / левой части панели.Затем анимация продолжится с этого места.Так что на самом деле, да, это именно то, что вам нужно сделать.
Я нахожу это самым простым способом создания анимации, поскольку Swing автоматически перерисовывает "последнее" местоположение компонента (для восстановления фона), а также рисует новое местоположение компонента.Все это достигается с помощью одного метода setLocation().
Некоторым людям нравится создавать пользовательские рисунки, рисуя изображение непосредственно на панели, но тогда вы несете ответственность за очистку старого расположения изображения, чтобы перерисовать фон, а затем нарисовать изображение в новом месте.Я нахожу это слишком большой работой.