所以我有一个JSplitPane和两个JPanels - 一个在顶部,一个在底部。在两个面板中,我覆盖了paintComponent方法并添加了我自己的图形。在底部面板中,我想添加一个动画。当面板没有重新绘制时,它很好,但是一旦Timer(javax.swing.Timer)开始调用重绘,底部面板就会模仿顶部面板的外观并出现故障。实际动画不会刷新,而是继续添加(如拖动的画笔而不是移动的对象)。
以下是Bottom Panel类的代码:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import javax.swing.Timer;
public class WaitControls extends JPanel {
private int pos;
public WaitControls(){
setBackground(Color.gray);
pos = 0;
}
public void progress(){
//animation timer:
Timer timer = new Timer(30, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
pos++;
repaint();
}
});
timer.start();
}
@Override
public void paintComponent(Graphics g){
g.fillRect(pos, pos, 10, 20);
}
}
这是Splitpane类的代码:
//my classes (imported packages)
import rcc.controls.ControlPanel;
import rcc.controls.InitControls;
import rcc.controls.WaitControls;
import rcc.video.Screen;
import javax.swing.JSplitPane;
public class MainPanel extends JSplitPane{
public RCC rcc;
public Screen screen;
private int height;
public ControlPanel curPanel;
public MainPanel(RCC rcc, Screen screen, int height){
super(JSplitPane.VERTICAL_SPLIT);
this.rcc = rcc;
this.screen = screen;
this.height = height;
setDividerSize(2);
setEnabled(false);
setTopComponent(screen);
setToInitControls();
}
//sets the control panel to init controls ***WORKS FINE***
public void setToInitControls(){
InitControls initCtrls = new InitControls(this);
setBottomComponent(initCtrls);
curPanel = initCtrls;
setDividerLocation(height / 4 * 3);
}
//sets the control panel to wait controls (trying to connect) ***GLITCHES***
public void setToWaitControls(){
WaitControls waitCtrls = new WaitControls();
setBottomComponent(waitCtrls);
curPanel = waitCtrls;
setDividerLocation(height / 4 * 3);
waitCtrls.progress();
}
}
顶部面板有点复杂。它涉及鼠标操作(包括MouseEntered侦听器)和动画以与用户鼠标输入交互。 奇怪的是,我有另一个底部面板被换掉,它也使用动画和计时器,并没有这个小故障。
任何可能导致这种情况的想法?谢谢你的帮助!
答案 0 :(得分:2)
我无法想象你的动画是如何运作的,
1 /但如果动画取决于Listener
中的任何一项,则Timer
必须为Timer#restart();
2 /检查(示例),如何通过addNotify()
/ removeNotify()
来启动/停止动画
注意需要全高清监视器以获得更好的输出或更改代码行
for (int iPanels = 0; iPanels < 3; iPanels++) {
到
for (int iPanels = 0; iPanels < 2; iPanels++) {
示例:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class AnimationBackground {
public AnimationBackground() {
Random random = new Random();
JFrame frame = new JFrame("Animation Background");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLayout(new GridLayout(0, 3, 10, 10));
for (int iPanels = 0; iPanels < 3; iPanels++) {
final MyJPanel panel = new MyJPanel();
panel.setBackground(Color.BLACK);
for (int i = 0; i < 50; i++) {
Star star = new Star(new Point(random.nextInt(490), random.nextInt(490)));
star.setColor(new Color(100 + random.nextInt(155), 100 + random.nextInt(155), 100 + random.nextInt(155)));
star.setxIncr(-3 + random.nextInt(7));
star.setyIncr(-3 + random.nextInt(7));
panel.add(star);
}
panel.setLayout(new GridLayout(10, 1));
JLabel label = new JLabel("This is a Starry background.", JLabel.CENTER);
label.setForeground(Color.WHITE);
panel.add(label);
JPanel stopPanel = new JPanel();
stopPanel.setOpaque(false);
stopPanel.add(new JButton(new AbstractAction("Stop this madness!!") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
panel.stopAnimation();
}
}));
panel.add(stopPanel);
JPanel startPanel = new JPanel();
startPanel.setOpaque(false);
startPanel.add(new JButton(new AbstractAction("Start moving...") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
panel.startAnimation();
}
}));
panel.add(startPanel);
frame.add(panel);
}
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
AnimationBackground animationBackground = new AnimationBackground();
}
});
}
class Star extends Polygon {
private static final long serialVersionUID = 1L;
private Point location = null;
private Color color = Color.YELLOW;
private int xIncr, yIncr;
static final int WIDTH = 500, HEIGHT = 500;
Star(Point location) {
int x = location.x;
int y = location.y;
this.location = location;
this.addPoint(x, y + 8);
this.addPoint(x + 8, y + 8);
this.addPoint(x + 11, y);
this.addPoint(x + 14, y + 8);
this.addPoint(x + 22, y + 8);
this.addPoint(x + 17, y + 12);
this.addPoint(x + 21, y + 20);
this.addPoint(x + 11, y + 14);
this.addPoint(x + 3, y + 20);
this.addPoint(x + 6, y + 12);
}
public void setColor(Color color) {
this.color = color;
}
public void move() {
if (location.x < 0 || location.x > WIDTH) {
xIncr = -xIncr;
}
if (location.y < 0 || location.y > WIDTH) {
yIncr = -yIncr;
}
translate(xIncr, yIncr);
location.setLocation(location.x + xIncr, location.y + yIncr);
}
public void setxIncr(int xIncr) {
this.xIncr = xIncr;
}
public void setyIncr(int yIncr) {
this.yIncr = yIncr;
}
public Color getColor() {
return color;
}
}
class MyJPanel extends JPanel {
private static final long serialVersionUID = 1L;
private ArrayList<Star> stars = new ArrayList<Star>();
private Timer timer = new Timer(20, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for (Star star : stars) {
star.move();
}
repaint();
}
});
public void stopAnimation() {
if (timer.isRunning()) {
timer.stop();
}
}
public void startAnimation() {
if (!timer.isRunning()) {
timer.start();
}
}
@Override
public void addNotify() {
super.addNotify();
timer.start();
}
@Override
public void removeNotify() {
super.removeNotify();
timer.stop();
}
MyJPanel() {
this.setPreferredSize(new Dimension(520, 520));
}
public void add(Star star) {
stars.add(star);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (Star star : stars) {
g.setColor(star.getColor());
g.fillPolygon(star);
}
}
}
}