【问题标题】:Java Observer does not update when GUI window is not on top当 GUI 窗口不在顶部时,Java Observer 不会更新
【发布时间】:2016-05-04 10:29:09
【问题描述】:

我进行了搜索,但没有找到类似问题的任何解决方案。我对 Observer/Observable 模式有疑问。 Observable 在名为“firstmap”的类中实现,这些类是:

class ObservableValue extends Observable{
    private String n;
    public ObservableValue(String n)
       {
          this.n = n;
       }
    public void setValue(String n)
       {
          this.n = n;
          setChanged();
          notifyObservers();

       }
       public String getValue()
       {
          return n;
       }
}

public class TextObserver implements Observer
{
private ObservableValue ov = null;
private multiwindow window1;
public TextObserver(ObservableValue ov, multiwindow window1)
{
  this.ov = ov;
  this.window1=window1;
}
public void update(Observable obs, Object obj)
{
  if (obs == ov)
  {
     System.out.println(ov.getValue());
     String[] tmp = ov.getValue().split(",");
     window1.destMessage(tmp[0], tmp[1]);
  }
}
}

问题是只有当窗口“firstmap”在前台时才会执行更新。否则,在我将窗口置于前台之前,它不会更新。有没有办法让它在后台运行时更新? 谢谢。

编辑:我没有提到“firstmap”是一个 JFrame。

edit2:更多细节:

“firstmap”是显示物体运动的地图。当一个对象到达特定位置时,我希望一条消息出现在另一个 JFrame(“多窗口”)中。现在的代码方式,只有当“firstmap”在前台时才会出现消息。

在“firstmap”类中有

ObservableValue ov = new ObservableValue("");
TextObserver to = new TextObserver(ov, window1);
public firstmap() {
    this.setTitle("Map");
    ov.addObserver(to);
    window1.setVisible(true);
    canvas = new DrawCanvas();
    this.setContentPane(canvas);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);
    this.pack();
    this.setSize(width, height);
    canvas.setPreferredSize(new Dimension(width, height));
    this.setAlwaysOnTop(true);
    timer = new Timer(DELAY, this);
    timer.start();
    this.setVisible(true);
}

...

for (int i = 0; i < window1.getaircraftlist().size(); i++) {

            if (window1.getaircraftlist().get(i).getReached()==false) {
                g.drawImage(window1.getaircraftlist().get(i).getImage(), window1.getaircraftlist().get(i).getX(), 
                    window1.getaircraftlist().get(i).getY(), this);

            }
            else {
                if (((window1.getaircraftlist().get(i).getDestFixPointName()=="IAF")||(window1.getaircraftlist().get(i).getDestFixPointName()=="AIRPORT")) && k[i]==0){
                    g.drawImage(window1.getaircraftlist().get(i).getImage(), window1.getaircraftlist().get(i).getX(), 
                            window1.getaircraftlist().get(i).getY(), this);
                    ov.setValue(window1.getaircraftlist().get(i).name+","+window1.getaircraftlist().get(i).getDestFixPointName());
                    k[i]=1;

                }
                else if (((window1.getaircraftlist().get(i).getDestFixPointName()=="IAF")||(window1.getaircraftlist().get(i).getDestFixPointName()=="AIRPORT")) & k[i]==1){
                    g.drawImage(window1.getaircraftlist().get(i).getImage(), window1.getaircraftlist().get(i).getX(), 
                            window1.getaircraftlist().get(i).getY(), this);
                }
                else
                {
                    ov.setValue(window1.getaircraftlist().get(i).name+","+window1.getaircraftlist().get(i).getDestFixPointName());
                    window1.getaircraftlist().remove(i);}
            }
        }

【问题讨论】:

    标签: java observer-pattern observable


    【解决方案1】:

    我认为您可以通过在后台对 JFrame 对象调用 repaint() 来侥幸 - 这应该会在 EDT 上运行的绘画算法中添加有问题的尺寸。

    如果更新 GUI 失败,则表明对观察模型的更改尚未传播到 JFrame 模型。

    【讨论】:

    • 我已经在“firstmap”类中有repaint() 方法。 “firstmap”实现了 ActionListener,我有方法:@Override public void actionPerformed(ActionEvent e) { updateCraft(); repaint(); }
    • 您确定正在触发 actionPerformed 事件吗?
    • 是的,当窗口在前台时它会被触发,因为我可以看到它的变化。
    • EDT是否调用了后台JFrame的paint()方法?用 super.paint() 覆盖paint(); System.out.println(this) 看看。如果您看到 println,则问题出在模型上,如果没有,则需要触发重新验证。
    • 我只在窗口位于前台时看到它。当我把它带到后台时,它停止了。那么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 2015-01-09
    相关资源
    最近更新 更多