【问题标题】:Why does my public String not change its string?为什么我的公共字符串不改变它的字符串?
【发布时间】:2017-10-08 20:17:17
【问题描述】:

我觉得我在某处看到了类似的东西:
这是我制作public static String iron = IronCount + " iron";的地方。
我觉得我看到的是,如果我的public int IronCount 改变了,弦铁会改变,但它不会改变,至少在 IronCount 在 Timer 中改变时不会改变。
我的完整代码在这里(没有所有g.fillRect()s):

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JComponent;

public class GeneratorAndGraphics extends JComponent {

private static final long serialVersionUID = 1L;

public int IronCount = 0, GoldCount = 0, DiamondCount = 0;
public String iron = IronCount + " iron"; //$NON-NLS-1$

public void paint(Graphics g) {
    // vertical lines
    Graphics2D g2d = (Graphics2D) g;
    // iron generator
    g.setColor(Color.BLACK);
    g.drawRect(20, 20, 40, 40);
    g.drawLine(20, 30, 60, 30);
    g.setFont(new Font("Arial", Font.PLAIN, 9)); //$NON-NLS-1$
    g.drawString("Iron Gen", 22, 30); //$NON-NLS-1$
    new java.util.Timer().schedule( 
            new java.util.TimerTask() {
                @Override
                public void run() {
                    IronCount++;
                    iron = IronCount + " iron"; // doesn't do anything
                    System.out.println(iron); // doens't print
                }
            }, 
            500
    );
    g.drawString(iron, 25, 45);
}
}

我认为只要 IronCount 改变,铁就会改变,但它并不像 g.drawString(iron, 25, 45); 总是在我的 JFrame 上显示:0 iron
也许这是 Timer 的错误,我希望有一个更好的替代方案 - 例如减慢 for 循环的重复速度。

【问题讨论】:

  • 您可以在代码中包含minimal reproducible example 吗?您可能不想覆盖paint,而且您几乎肯定不想在每次调用paint 时都创建一个新的计时器任务。

标签: java string swing timer


【解决方案1】:

建议:

  • 从绘画方法中取出那个计时器,它不应该在那里。您无法控制该方法,并且可以多次调用它
  • 创建并启动一次计时器,可能在您的类的构造函数中。
  • 同样,正如之前告诉您的,绘画应该在 paintComponent 方法中完成。
  • 请务必从您的绘画方法中调用超级的绘画方法,此处为 super.paintComponent(g) 在您自己的绘画方法中。
  • 在您的计时器中,您更改字段的状态并调用repaint()
  • 在 paintComponent 方法中,您检查字段的状态并根据其值更改您的绘画。
  • 这些字段不应该是静态的
  • 不要使用java.util.Timer,因为这不是 Swing 线程安全的,而是 Swing 计时器,例如 javax.swing.Timer。谷歌教程。
  • 按照无数次的要求发布有效的 MCVE。如果没有您的 MCVE,我们真的不知道您还做错了什么,也不知道您是如何将这一切联系在一起的。
  • 请阅读教程,避免猜测,因为我们已多次向您推荐

是一个 MCVE:

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;

public class Mcve extends JPanel {
    private static final int TIMER_DELAY = 1000;
    private static final String IRON_FORMAT = "%03d iron";
    private int ironCount = 0;

    public Mcve() {
        setPreferredSize(new Dimension(400, 300));
        new Timer(TIMER_DELAY, e -> {
            ironCount++;
            repaint();
        }).start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawString(String.format(IRON_FORMAT, ironCount), 25, 45);
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("Mcve");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new Mcve());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

【讨论】:

  • 我的画是用paint方法画的,因为大概有100行,所以我把它拿出来了。至于让 Timer 脱离paint 方法,它可以去哪里,我是 Timers 的新手,for 循环对我没有帮助。
  • @BlazeDaBlur2:创建并发布您的minimal reproducible example。请让我们避免猜测您还做错了什么。
  • @BlazeDaBlur2l:你已经编辑了你的问题,仍然还没有发布我们可以编译或运行的代码,一个 MCVE。请查看我上面的代码,因为这是 you 应该发布的,我们可以编译运行和测试的代码。
  • @BlazeDaBlur2:你被问了无数次——这意味着你还没有阅读我们提供给你的链接。又是:minimal reproducible example。请研究一下。同样,让我们​​避免沮丧和猜测。
  • 哈!因此,如果您坚持不妥协,您可能会被推得更远,向某人提出问题,对其发表评论,根据您自己的评论对其进行编辑(可能添加一个 MCVE),然后回答它。
猜你喜欢
  • 1970-01-01
  • 2019-11-12
  • 2019-05-29
  • 2021-05-03
  • 2021-05-19
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多