【问题标题】:What is causing JLabel not to update?是什么导致 JLabel 不更新?
【发布时间】:2015-03-25 21:14:48
【问题描述】:

我正在使用观察者模式来显示轮到谁来玩。我从我的 Observable 中获得了正确的数据,这就是我不发布它的原因。如您所见,正在设置文本,因为我可以调用 label.getText()。 标签怎么不更新了?

我尝试过重新绘制、重新验证、SwingUtilities.invokeLater、updateUI 和各种东西。我不知道我做错了什么。

先谢谢你了。

public class PlayersTurnPane extends JPanel implements Observer {

    private JLabel label = new JLabel();

    public PlayersTurnPane() {
        setLayout(new BorderLayout());
        setBackground(Color.gray);
        label.setText("White");
        label.setHorizontalAlignment(getWidth() / 2);
        label.setFont(new Font("Serif", Font.PLAIN, 25));
        add(label);

    }

    @Override
    public void update(Observable arg0, Object arg1) {
        label.setText((String)arg1); //But it will not update label
        System.out.println(label.getText()); //The text is being set
    }

}

我的观察者

 public class TurnObserver extends Observable {

    public TurnObserver(PlayersTurnPane playersTurnPane) {
        addObserver(playersTurnPane);
    }

    public void setTurn(String turn){
        setChanged();
        notifyObservers(turn);
        clearChanged();
    }

}

我发送数据的地方

private TurnObserver turnObserver = new TurnObserver(new PlayersTurnPane());    

public void grabPiece(BoardTile boardTile) {
        if(focusedPiece != null && playerTurn.getCurrentTurn() == focusedPiece.getPieceColor()) {
            boardTile.add(focusedPiece);
            updateUI();
            playerTurn.changeTurn();
            turnObserver.setTurn(playerTurn.getCurrentTurn());
        }
    }

面板添加到这里

public class EastPanel extends JPanel {

    public EastPanel() {
        setLayout(new GridLayout(3,0));
        add(new TimePane());
        add(new MoveHistoryPane());
        add(new PlayersTurnPane());
    }

}

【问题讨论】:

  • 考虑提供一个可运行的示例来演示您的问题

标签: java swing observer-pattern


【解决方案1】:

如果正在打印System.out.println(label.getText());,那么您在未显示的代码中遇到了 Swing 线程问题,这可能是由于在 Swing 事件线程上运行了长时间运行的代码,从而阻止了该线程完成其工作——比如在 JLabel 上绘制更新的文本。确保所有长时间运行的代码都在后台线程上完成,并且 Swing 状态更改和查询是在 Swing 事件线程上进行的。阅读Concurrency in Swing了解详情。

重新,

我从我的 Observable 中获得了正确的数据,这就是我不发布它的原因。

但正是未发布的代码才是解决问题的关键。


该死,Mad 是对的:你在模仿:

public TurnObserver() {
    addObserver(new PlayersTurnPane());
}

您正在添加一个 PlayersTurnPane 作为您的观察者,但它可能不是显示的 PlayersTurnPane!关键:每次在构造函数上调用 new 时,都会创建一个 new 对象,这里是 PlayersTurnPane。您应该传入显示的 PlayersTurnPane,而不是新的。

你遇到了这样的代码问题:

public class EastPanel extends JPanel {

    public EastPanel() {
        setLayout(new GridLayout(3,0));
        add(new TimePane());
        add(new MoveHistoryPane());
        add(new PlayersTurnPane());
    }
}

dsiplayed PlayersTurnPane 正在匿名创建 - object 正在添加到显示中,但该对象没有被任何变量引用,如果您要这样做,则需要这样做将完全相同的 PlayersTurnPane 对象传递给使其成为可观察对象的方法。

我建议您在需要引用对象的地方使用类字段而不是匿名对象。所以在这里,也许更好的是:

public class EastPanel extends JPanel {

    public EastPanel(PlayersTurnPane playersTurnPane) {
        setLayout(new GridLayout(3,0));
        add(new TimePane()); // you likely need parameters for 
        add(new MoveHistoryPane());  // these two objects as well
        add(playersTurnPane);
    }
}

您似乎缺少的关键概念是 references 的重要性之一,它是指向感兴趣对象的指针。阅读此内容。

【讨论】:

  • @MadProgrammer:啊,是的。没错,我们需要一个可运行的示例。
  • @user2891133: 是的,疯子是对的——你通知了错误的 PlayersTurnPane 对象,而不是显示的那个!
  • 嗯,这是一个不错的改变,你能告诉我妻子吗:P
  • @MadProgrammer:那没有用。就像那句老佛说:男人说了什么,女人不在,他还是错了吗?
  • 嗯,这解释了很多:P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-23
  • 1970-01-01
  • 2019-10-23
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
相关资源
最近更新 更多