【问题标题】:Java: JSplitPane duplicates top panel's contents to bottom panel when Timer is activeJava:当计时器处于活动状态时,JSplitPane 将顶部面板的内容复制到底部面板
【发布时间】:2011-10-11 22:06:05
【问题描述】:

所以我有一个 JSplitPane 和两个 JPanel - 一个在顶部,一个在底部。在两个面板中,我都覆盖了paintComponent 方法并添加了我自己的图形。在底部面板中,我想添加一个动画。当面板不重新绘制时,这很好,但是一旦 Timer (javax.swing.Timer) 开始调用重新绘制,底部面板就会模仿顶部面板的外观并出现故障。实际动画并未刷新,而是不断添加(就像拖动的画笔而不是移动的对象)。

这是底部面板类的代码:

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 侦听器)和动画以与用户鼠标输入进行交互。 奇怪的是,我有另一个底部面板被换掉了,它也使用动画和一个计时器,并且没有这个故障。

任何想法可能导致这种情况?感谢您的所有帮助!

【问题讨论】:

    标签: java swing graphics jsplitpane


    【解决方案1】:

    我无法想象你的动画是如何工作的,

    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);
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      相关资源
      最近更新 更多