tags:

views:

176

answers:

5

I'm writing some experimental GUI code. I'm trying to set it up so calling main generates two windows, each with a button and a label. The label displays how many times the button has been clicked. However, I want it so if you click the button in one window, the label in the other updates. How would I do this?

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

@SuppressWarnings("serial")
public class TestGUI extends JFrame {

    private static int count;
    private JButton button = new JButton("odp"); 
    private JLabel label = new JLabel();

    public TestGUI() {
     setDefaultCloseOperation(EXIT_ON_CLOSE);
     add(button);
     setLayout(new FlowLayout(FlowLayout.RIGHT));

     labelUpdateText();
     add(label);

     button.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
       count++;
       labelUpdateText();
      }
     });

     pack();
     setVisible(true);
    }

    private void labelUpdateText() {
     label.setText("Count: " + count);
    }

    public static void main(String[] args) {
     new TestGUI();
     new TestGUI();
    }

}
+1  A: 

You're going to need to setup an eventListener and have the buttons fire an event that updates a shared variable (AtomicInteger comes to mind) and update the button text when the event is caught.

Gandalf
A: 

You could do something like this:

In the main method:

TestGUI a, b;
a = new TestGUI(b);
b = new TestGUI(a);

Then add to the constructor:

public TestGUI(TestGUI other)

And then from either GUI do:

other.labelUpdateText();
nalo
I understand what you're trying to do. You may want to revise how the instances are associated with each other. The `b` variable cannot be passed to the `TestGUI` constructor before `b` has been instantiated (compiler error: "The local variable b may not have been initialized").
Adam Paynter
You could associated the labels like that, but it would create a high coupling between them. Sometimes that's not always desirable.
OscarRyz
Yes, i understand what you mean and this should only be seen as a quick fix to the problem. Oscar Reyes solution below is of course a much better solution.
nalo
+1  A: 

I would start by not extending JFrame and avoiding mutable statics.

The simplest way to proceed would be to break construction down into phases. Create both labels first. Then construct the rest. Call a constructor method twice for each frame, with the labels as different arguments each time.

More sophisticated is to have a model. The action listener (controller) updates a model, and the model fires a state changed event that a change listener (view) associated with the label in the other frame listens to.

Tom Hawtin - tackline
+2  A: 
OscarRyz
+1 because you use a Mac. Also the answer is good, but mainly the Mac... ;-)
Smalltown2000
A: 

do you really need 2 JFrames?

you could instead have a master and a slave: one could be the JFrame, the other could be a non-modal dialog.

(non-modal so that it doesn't steal and keep the focus till it is minimized)

Jill Renee