poseid poseid - 12 days ago 5
Java Question

How to access multiple JPanels inside JFrame?

I have a

JFrame
that contains a "display"
JPanel
with
JTextField
and a "control"
JPanel
with buttons that should access the contents of the display
JPanel
. I think my problem is related on how to use the observer pattern, which in principle I understand. You need to place listeners and update messages, but I don't have a clue where to put these, how to get access from one panel to the other and maybe if necessary to introduce a "datamodel" class. For example, I want to access the contents of the
JTextField
from the control panel and I use an anonymous action listener as follows:

JButton openfile = new JButton("Convert file");
openfile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openButtonPressed();
}
});

Answer

You need to reduce the coupling between these objects.

You can have a master object, that owns all the text fields and the button ( the panels are irrelevant )

Then a separete actionlistener within that master object ( I call it mediator see mediator pattern )

That action listener performs a method on the mediator which in turn take the values from the textfields and create perhaps a transfer object.

This way you reduce the coupling between the panels, textfields etc. and let the control in one place ( the mediator ) that is, you don't let them know each other.

You can take a look at the code in this question: http://stackoverflow.com/questions/324554/#324559

It shows these concepts in running code.

BTW the observer pattern is already implemented in the JTextField, JButton, ActionListener etc. You just need to add the hooks.

I hope this helps.

EDIT Joined two answers into one.

This is the code.

class App { // this is the mediator

    // GUI components.
    private JFrame frame;
    private JTextField name;
    private JTextField count;
    private JTextField date;
    // Result is displayed here.
    private JTextArea textArea;

    // Fired by this button.
    private JButton   go;

    private ActionListener actionListener;


    public App(){
        actionListener = new ActionListener(){
            public void actionPerformed( ActionEvent e ){
                okButtonPressed();
            }
        };
    }

    private void okButtonPressed(){
         // template is an object irrelevant to this code.
         template.setData( getData() );
         textArea.setText( template.getTransformedData() );
    }


    public void initialize(){

        frame     = new JFrame("Code challenge v0.1");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        name     = new JTextField();
        count    = new JTextField();
        date     = new JTextField();
        textArea = new JTextArea();
        go       = new JButton("Go");
        go.addActionListener( actionListener ); // prepare the button.

        layoutComponents(); // a lot of panels are created here. Irrelevant.
    }
}

Complete and running code can be retrieved here:

It is important to favor composition over inheritance when possible.