Java GUI: exchanging values ​​in different JFrames

I am writing some experimental GUI code. I'm trying to customize it, so the call main

creates two windows, each with a button and a label. The label shows how many times the button has been pressed. However, I want it to be, if you click a button in one window, a shortcut in other updates. How should I do it?

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

}

      

+2


source to share


5 answers


1 - I would rather not extend the JFrame since you are not actually creating a new JFrame class.

So instead of having your entire class subclassing JFrame (it is not), you could instantiate them with more actions added.

2 - If you want to have two labels reflecting the meaning of the same "thing", you have to share with this thing between them (or someone to update this value for you)

So, using the famous MVC , you will need.

  • The counter model you want to show in both labels.

  • Look at the labels on which the model will be displayed.

  • Controller Something that has between itself.



They all belong to the application, they are attributes of the application instance.

To see how they fit together, I am pasting the code here:

import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.*;

 // TwoWindows is the Application 
public class TwoWindows {
    // shared state ( model ) 
    private int clickCount = 0;

    // UI
    private List<JLabel> toUpdate = new ArrayList<JLabel>();

    // listener ( listens for clicks on buttons kind of controller  )
    private ActionListener actionListener = new ActionListener() {

        // Each time update the UI 
        public void actionPerformed( ActionEvent e ) {
            clickCount++; 
            for( JLabel label : toUpdate ) {
                label.setText( "Count: " + ( clickCount ) );
            }
        }
    };

    // Createsa winddow with a label and a button
    public void showWindow( String named ) {
        JFrame f = new JFrame( named );
        f.add( createButtonAndLabel() );
        f.pack();
        f.setVisible( true );
    }

    // Creates the label and button and adds this.actionListener
    // to each button. 
    private JComponent  createButtonAndLabel() {
        JPanel panel = new JPanel();
        JLabel label =  new JLabel("Count: 0");
        JButton clickMe = new JButton("Click me");
        // adding the label to a "view" list.
        toUpdate.add( label );
        // adding the listener to each button 
        clickMe.addActionListener( actionListener );
        panel.add( label );
        panel.add( clickMe );
        return panel;
    }

    // Run the app
    public static void main( String [] args ) {
        TwoWindows t = new TwoWindows();
        t.showWindow("A");
        t.showWindow("B");
    }
 }

      

This way you can have a common model and update as many views as you like.

alt text http://img387.imageshack.us/img387/1106/capturadepantalla200910d.png

+4


source


You will need to set up an eventListener and fire buttons that update the shared variable (AtomicInteger comes to mind) and update the button text when an event is detected.



+1


source


I would start by not continuing JFrame

and avoiding volatile static.

The easiest way is to split the construction into phases. First create both labels. Then build the rest. Call the constructor method twice for each frame, using the labels as different arguments each time.

More complicated is the presence of a model. The action listener (controller) updates the model, and the model fires a stateful event that the change listener (view) associated with a label in another frame listens to.

+1


source


You can 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 any GUI do:

other.labelUpdateText();

      

0


source


Do you really need 2 JFrames?

instead you can have a master and a slave: one can be a JFrame, the other can be a modeless dialog.

(non-modal so it doesn't steal and hold focus until it's minimized)

0


source







All Articles