0

I searched but I didn't find any solution to a similar problem. I have a problem with an Observer/Observable pattern. The Observable is implemented at a class called "firstmap" and the classes are:

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]);
  }
}
}

The problem is that the update is only executed when the window "firstmap" is on the foreground. Otherwise, it is not updated until I bring the window to the foreground. Is there any way to make it update even when it's running on the background? Thanks.

edit: I didn't mention that "firstmap" is a JFrame.

edit2: Some more details:

The "firstmap" is a map showing the movement of objects. When an object reaches a specific position, I want a message to appear to another JFrame ("multiwindow"). The way the code is now, the message appears only when the "firstmap" is on the foreground.

In the "firstmap" class there is

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);}
            }
        }
Thomasp
  • 1
  • 2

1 Answers1

0

I think you might be able to get away with calling repaint() on the JFrame object in the background - this should add the offending dimensions to the painting algorithm running on the EDT.

If this fails to update the GUI then it is a sign that the changes to the observed model have not been propagated to the JFrame model.

Lee
  • 738
  • 3
  • 13
  • I already have the repaint() method in the "firstmap" class. The "firstmap" implements ActionListener and I have the method: `@Override public void actionPerformed(ActionEvent e) { updateCraft(); repaint(); }` – Thomasp May 04 '16 at 11:48
  • are you sure the actionPerformed event is being fired? – Lee May 04 '16 at 11:50
  • Yes, it is being fired when the window is on the foreground because I can see the changes on it. – Thomasp May 04 '16 at 11:53
  • Is the paint() method of the background JFrame being called by the EDT? Override paint() with super.paint(); System.out.println(this) to see. If you see the println then the issue is with the model, if you don't then you need to trigger a revalidation. – Lee May 04 '16 at 12:15
  • I only see it when the window is on the foreground. When i take it to the background it stops. So? – Thomasp May 04 '16 at 12:32
  • Therefore, you need to signal to the EDT that you want to recalc that window too when you do your action - call revalidate() to the background window. – Lee May 04 '16 at 12:38
  • Unfortunately not working, seems like it has no effect at all. – Thomasp May 04 '16 at 12:52