java - 使用 TimerTask 移动 JPanel

标签 java swing timer jpanel timertask

所以我设置了一个如下图所示的 Java GUI(对于糟糕的游戏绘制表示歉意):

Java GUI 布局

Target GUI

所有 JPanel 的大小都相同(图中未很好地显示)。我想做的是,当我用进度条做某事(即读取一些文本文件)时,JPanels 将循环通过。红色的会到底部,橙色的会到顶部,如此循环下去。我希望它们每半秒改变一次,并在程序打开后等待 2 秒才能开始移动。我还希望它们在其中一个进度条达到 100% 时停止。

经过一些阅读后,我认为 Java TimerTask 类非常适合此操作,但我没有使用它的经验,并且不太确定如何用它来做这样的事情。

任何有关如何进行此操作的提示或想法将不胜感激!

最佳答案

保留颜色模型(和文本,如果“Red JPanel”是用户看到的内容的一部分)并简单地更改现有面板的 BG 颜色以适合用作索引的计数器,会简单得多这些颜色(/文本)组合的数组。

正如 @MadProgrammer 所提到的,Swing Timer 会更合适,因为 Swing 计时器可确保在 EDT 上进行更新。或者更确切地说是两个计时器。第一个是单次计时器,延迟两秒。第二个将循环颜色。

像这样(根据需要调整颜色和数字):

enter image description here

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class ColorCycler {

    private JComponent ui = null;
    Color[] colors = {
        Color.RED,
        Color.ORANGE,
        Color.YELLOW,
        Color.GREEN,
        Color.CYAN.darker(),
        Color.MAGENTA.darker(),
        Color.MAGENTA.darker().darker()
    };
    int counter = 0;
    JPanel[] panels = new JPanel[colors.length];

    ColorCycler() {
        initUI();
    }

    public void initUI() {
        if (ui!=null) return;

        ui = new JPanel(new BorderLayout(4,4));
        ui.setBorder(new EmptyBorder(4,4,4,4));
        ui.setBackground(Color.CYAN);

        ui.add(new JLabel(
                "Clock", SwingConstants.CENTER), BorderLayout.PAGE_START);
        ui.add(new JLabel(
                "Progress Bars", SwingConstants.CENTER), BorderLayout.PAGE_END);

        JPanel colorPanel = new JPanel(new GridLayout(0, 1));
        Border border = new EmptyBorder(new Insets(10, 200, 10, 200));
        for (int ii=0; ii<colors.length; ii++) {
            JPanel p = new JPanel();
            p.setBorder(border);
            panels[ii] = p;
            colorPanel.add(p);
        }
        ui.add(colorPanel, BorderLayout.CENTER);

        ActionListener colorListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                counter++;
                setColors();
            }
        };
        final Timer colorCycleTimer = new Timer(50, colorListener);

        ActionListener delayListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                colorCycleTimer.start();
            }
        };
        Timer delayTimer = new Timer(2000, delayListener);
        delayTimer.setRepeats(false);
        delayTimer.start();

        setColors();
    }

    private void setColors() {
        for (int ii=0; ii<colors.length; ii++) {
            panels[(counter+ii)%colors.length].setBackground(colors[ii]);
        }
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                ColorCycler o = new ColorCycler();

                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

关于java - 使用 TimerTask 移动 JPanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42310947/

相关文章:

java - 手动操作ArrayList

java - 我必须在 Java 中覆盖哪种方法才能使用 ">"来比较我的类的实例

java - Android android.intent.action.SEND youtube 视频

java - java中圆弧的半径

Java Swing 计时器未启动?

Java错误和初始化: java_lang_NullPointerException

java - ActionListeners 不适用于模态 JDialog

java - 选项卡内的面板不显示

c# - 如何使用 System.Threading.Timer 和 Thread.Sleep?

Angular rxjs Observable.interval() 无法在 Chrome 中的后台选项卡上正确触发