【问题标题】:Java: Let GUI change between different states with pausesJava:让 GUI 在不同状态之间切换
【发布时间】:2015-08-28 14:21:58
【问题描述】:

在 Java 中有没有一种方法可以让 GUI 在几个状态之间切换,但在每次切换之间暂停,让它看起来像一个动画? (不使用 JavaFX 预定义动画)

举个简单的例子:让我们有一个包含 100 个字符串的数组。每 50 毫秒,GUI/文本字段中描述的字符串应该更改一次,并遍历给定的数组。同时,GUI 应该保持响应,并且“动画”应该可以通过单击按钮来停止。

除了使用 Thread.wait() 或 sleep() 之外,还有其他方法吗?或者这是 Java 中唯一可能的选择? GUI 如何保持响应?

【问题讨论】:

  • 你应该看看Swing Timers
  • Thread.wait()sleep() 甚至都不是选项。忘记你曾经在 GUI 代码中听说过它们。
  • @BackSlash 为什么要将 Swing 与 JavaFX 混合使用?
  • 是的,有一种方法可以为 GUI 设置动画。您的示例将在 5 秒内遍历 100 个字符串的数组。没有人能够读取字符串。看看我的Java Swing Marquee 文章,了解如何创建动画。

标签: java multithreading user-interface javafx


【解决方案1】:

也许它有点过时了,但是看看this classpaint 方法被覆盖,它的工作依赖于 turnFactor,它由第二个线程以所需的节奏进行更改:

/**
 * A single, flippable tile in the GUI of the memory game.
 */
public class Tile extends JComponent {

    private static final long serialVersionUID = 3832294699261778944L;

    private static final Logger LOGGER = LoggerFactory.getLogger(Tile.class);

    private final TileGroup _tileGroup;

    private float turnFactor = -1.0f;

    private boolean flipping = false;

    private boolean uncovered = false;

    public Tile(TileGroup tileGroup) {
        _tileGroup = tileGroup;
    }

    @Override
    public void paint(Graphics g) {
        LOGGER.trace("drawing..." + getX() + "/" + getY() + " " + getWidth() + "x" + getHeight());
        final Graphics2D graphics2d = (Graphics2D) g;
        final int y = 0;
        if (turnFactor > 0) {
            final BufferedImage image = getTileGroup().getImage();
            final float scale = Math.min(((float) getWidth()) / image.getWidth(),
                    ((float) getHeight()) / image.getHeight());
            final int x = Math.round((getWidth() / 2.0f) - (image.getWidth() * scale * turnFactor * 0.5f));
            final AffineTransform translateInstance = AffineTransform.getTranslateInstance(x, y);
            final AffineTransform scaleInstance = AffineTransform.getScaleInstance(turnFactor * scale, scale);
            translateInstance.concatenate(scaleInstance);
            graphics2d.drawImage(image, translateInstance, null);
            // graphics2d.drawImage(getTileGroup().getImage(), x, y, width,
            // height, null);
        } else {
            final int x = Math.round((getWidth() / 2.0f) * (1.0f - Math.abs(turnFactor)));
            final int width = Math.round(getWidth() * Math.abs(turnFactor)) - 1;
            final int height = getHeight() - 1;
            graphics2d.setPaint(new GradientPaint(0, 0, Color.GRAY, 0, height * 2, Color.BLUE));
            graphics2d.fillRect(x, y, width, height);
        }
    }

    public synchronized void flip() {
        if (!isFlipping()) {
            setFlipping(true);
            final boolean uncovered = isUncovered();
            setUncovered(!uncovered);
            Thread t = new Thread((Runnable) () -> {
                if (uncovered) {
                    LOGGER.debug("covering tile");
                    for (turnFactor = 1.0f; turnFactor > -1.0; turnFactor -= 0.1) {
                        try {
                            Thread.sleep(15);
                        } catch (InterruptedException e) {
                            LOGGER.error("interrupted", e);
                        }
                        repaint();
                    }
                } else {
                    LOGGER.debug("uncovering tile");
                    for (turnFactor = -1.0f; turnFactor < 1.0; turnFactor += 0.1) {
                        try {
                            Thread.sleep(15);
                        } catch (InterruptedException e) {
                            LOGGER.error("interrupted", e);
                        }
                        repaint();
                    }
                }
                setFlipping(false);
            });
            t.start();
        }
    }

    public TileGroup getTileGroup() {
        return _tileGroup;
    }

    public boolean isFlipping() {
        return flipping;
    }

    public void setFlipping(boolean flipping) {
        this.flipping = flipping;
    }

    public boolean isUncovered() {
        return uncovered;
    }

    public void setUncovered(boolean uncovered) {
        this.uncovered = uncovered;
    }

}

这是你要找的吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 2021-05-09
    • 2023-02-05
    相关资源
    最近更新 更多