无法更改JPanel上的内容。

huangapple go评论163阅读模式
英文:

Cant change content on a JPanel

问题

我有一个JFrame,其中添加了一个名为gamePanel的JPanel。在主窗口设置为可见后,游戏多次调用renderPlayerInfo方法。然而,在第一次调用该方法后,面板没有改变。

renderPlayerInfo

void renderPlayerInfo(JPanel gamePanel) {
        Font renderFontBold = new Font("Arial", Font.BOLD, 16);
        Font renderFont = new Font("Arial", Font.PLAIN, 16);

        renderPanel.removeAll();
        System.out.println("e");

        int yRender = 0;
        for (int i = 0; i < players.size(); i++) {
            JPanel playerPanel = new JPanel(null);
            playerPanel.setBounds(0, yRender, 300, 110);
            playerPanel.setBackground(new Color(204, 227, 199));

            JLabel playerLabel = new JLabel("Player " + String.valueOf(i + 1));
            playerLabel.setFont(renderFontBold);
            playerLabel.setBounds(10, 10, 300, 18);

            JLabel playerToken = players.get(i).getPlayerToken(244, 0);
            playerPanel.add(playerToken);

            JLabel moneyIcon = new JLabel(new ImageIcon("./res/money.jpg"));
            moneyIcon.setBounds(30, 40, 64, 32);
            playerPanel.add(moneyIcon);
            JLabel moneyAmount = new JLabel("£" + moneyFormatter.format(players.get(i).playerMoney));
            moneyAmount.setFont(renderFont);
            moneyAmount.setBounds(100, 48, 200, 18);
            playerPanel.add(moneyAmount);

            JPanel separatorPanel = new JPanel();
            separatorPanel.setBounds(0, 108, 300, 2);
            separatorPanel.setBackground(new Color(146, 159, 149));
            playerPanel.add(separatorPanel);

            playerPanel.add(playerLabel);
            renderPanel.add(playerPanel);

            if (i + 1 == playerTurn) {
                JLabel turnPointer = new JLabel(new ImageIcon("./res/turnPointer.png"));
                turnPointer.setBounds(70, -12, 64, 64);
                playerPanel.add(turnPointer);
            }

            yRender += 110;
        }
        renderPanel.repaint();

        gamePanel.add(renderPanel);
        gamePanel.repaint();
    }

我尝试添加了renderPanel.repaint(),但似乎没有改变任何内容。

英文:

I have a JFrame, which has a JPanel called gamePanel added to it. The game calls the method renderPlayerInfo multiple times after the main frame is set to visible. However, the panel does not change after the first time I call the method.

renderPlayerInfo

void renderPlayerInfo(JPanel gamePanel) {
Font renderFontBold = new Font(&quot;Arial&quot;, Font.BOLD, 16);
Font renderFont = new Font(&quot;Arial&quot;, Font.PLAIN, 16);
renderPanel.removeAll();
System.out.println(&quot;e&quot;);
int yRender = 0;
for (int i = 0; i &lt; players.size(); i++) {
JPanel playerPanel = new JPanel(null);
playerPanel.setBounds(0, yRender, 300, 110);
playerPanel.setBackground(new Color(204, 227, 199));
JLabel playerLabel = new JLabel(&quot;Player &quot; + String.valueOf(i + 1));
playerLabel.setFont(renderFontBold);
playerLabel.setBounds(10, 10, 300, 18);
JLabel playerToken = players.get(i).getPlayerToken(244, 0);
playerPanel.add(playerToken);
JLabel moneyIcon = new JLabel(new ImageIcon(&quot;./res/money.jpg&quot;));
moneyIcon.setBounds(30, 40, 64, 32);
playerPanel.add(moneyIcon);
JLabel moneyAmount = new JLabel(&quot;&#163;&quot; + moneyFormatter.format(players.get(i).playerMoney));
moneyAmount.setFont(renderFont);
moneyAmount.setBounds(100, 48, 200, 18);
playerPanel.add(moneyAmount);
JPanel separatorPanel = new JPanel();
separatorPanel.setBounds(0, 108, 300, 2);
separatorPanel.setBackground(new Color(146, 159, 149));
playerPanel.add(separatorPanel);
playerPanel.add(playerLabel);
renderPanel.add(playerPanel);
if (i + 1 == playerTurn) {
JLabel turnPointer = new JLabel(new ImageIcon(&quot;./res/turnPointer.png&quot;));
turnPointer.setBounds(70, -12, 64, 64);
playerPanel.add(turnPointer);
}
yRender += 110;
}
renderPanel.repaint();
gamePanel.add(renderPanel);
gamePanel.repaint();
}

I tried adding renderPanel.repaint() but this does not seem to change anything.

答案1

得分: 2

"不能在 JPanel 上更改内容

可以。

但一般来说,人们不会以你尝试的方式实现这一点。而是会更新现有组件的模型,以便在重绘时视图会按照你的要求显示。例如,使用 JLabel.setText() 而不是创建一个全新的 JLabel。当然,这需要你以一种能够清晰地进行修改的方式保持对要更新的组件的引用。在某些情况下,创建自定义组件来帮助你可能是有意义的。

另外,从你调用 renderPlayerPanel() 的上下文来看,如果它修改了 GUI 组件,那么它需要在事件分发线程上运行。如果它尚未在那里运行,你可以通过让调用者通过 SwingUtilities.invokeAndWait()SwingUtilities.invokeLater() 来运行它来修复这个问题。

我尝试添加 renderPanel.repaint(),但似乎没有任何变化。

这并不奇怪。你已经在重绘该面板的容器;直接重绘面板没有额外的效果。

英文:

> Cant change content on a JPanel

It can.

But generally speaking, one would not achieve that in the way you are trying to do. Instead of ripping out all of the components and replacing them with new, one would ordinarily update the models of the existing components so that when they are repainted, the view will be as you want. For example, use JLabel.setText() instead of creating a whole new JLabel. Of course, this does require you to keep references to the components you will want to update in a way that enables you to perform such modifications cleanly. Under some circumstances, it might make sense to create custom components to help you with that.

Also, however, it is unclear from what context you are calling renderPlayerPanel(), but inasmuch as it modifies GUI components, it needs to run on the event dispatch thread. If it's not running there already, then you can fix that by having the invoker(s) go through SwingUtilities.invokeAndWait() or SwingUtilities.invokeLater() to run it.

> I tried adding renderPanel.repaint() but this does not seem to change anything.

Not surprising. You're already repainting that panel's container; it has no additional effect to also repaint the panel directly.

huangapple
  • 本文由 发表于 2023年7月31日 23:13:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76804963.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定