0

I want to update a JPanel according to the value of a ComboBox in another JPanel.

I have a JFrame in which I am adding two panels:

package gui;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class MainFrame extends JFrame {
    public MainFrame() {
    }

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainFrame frame = new MainFrame();

                    frame.setSize(1200, 1200);

                    PanelClass1 panelClass1= new PanelClass1 ();
                    PanelClass2 panelClass2= new PanelClass2 ();


                    frame.getContentPane().add(panelClass1.contentPanel, BorderLayout.PAGE_START);
                    frame.getContentPane().add(panelClass2.contentPanel, BorderLayout.PAGE_END);
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Now in Panel1 I have a ComboBox in which depending on its value I need to hide or show fields in Panel2. I am saving the value of this ComboBox in a singleton.

public class PanelClass1 extends JPanel {

testComboBox = new JComboBox<ComboItem>();
                testComboBox.setEditable(true);
                testComboBox.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {
                        POJOSingleton.getInstance().setValor(testComboBox.getSelectedItem().toString());
                        checkFields();
                    }
                });
 }

Then in PanelClass2 I am reading that variable and then making some components visible or not according to the value. The whole logic of the panelClass2 is based on the value I set in the first JPanel.

public class panelClass2 extends JPanel {

  public panelClass2 () {

    if(POJOSingleton.getInstance().getValor() != null) {
        int value1 = posicionesTenion.get(0);

        pos1.setVisible(true);
        lblPos1TensionAT.setVisible(true);
        ...

What should I do so when I change the ComboBox I trigger a refresh in my second panel?.

Eduardo
  • 19,928
  • 23
  • 65
  • 73

1 Answers1

2

The best way is probably to use an Observer pattern.

The way to do that is to add an Observable field to your PanelClass1, and let it notify all Observers when the ActionListener of the JComboBox gets triggered.

public class PanelClass1 extends JPanel {

    private JComboBox<?> testComboBox;
    private Observable obs;

    public PanelClass1() {

        obs = new Observable();

        testComboBox = new JComboBox<SingletonClass>();
        testComboBox.setEditable(true);
        testComboBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                SingletonClass.getInstance().setValue(testComboBox.getSelectedIndex());
                obs.notifyObservers();
            }
        });
    }

    public void addObserver(Observer observer) {
        obs.addObserver(observer);
    }

    public void removeObserver(Observer observer) {
        obs.deleteObserver(observer);
    }
}

Now let your PanelClass2 implement Observer and let your code execute when it gets notified, like so:

public class PanelClass2 extends JPanel implements Observer {

    public PanelClass2() {

    }

    @Override
    public void update(Observable o, Object arg) {
        int value = SingletonClass.getInstance().getValue();
        // do your stuff here
    }
}

Saying your singleton object looks somewhat like this:

public class SingletonClass {

    private static final SingletonClass singleton = new SingletonClass();
    private int value; // this doesn't have to be an integer, I am just using this as an example

    private SingletonClass() {

    }

    public static SingletonClass getInstance() {
        return singleton;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

}

you now are able to access the value field of your SingletonClass instance in the update() method of PanelClass2.

Your MainFrame class needs only one change: You need to add your PanelClass2 object to your PanelClass1 object as an observer.

public class MainFrame extends JFrame {

    public MainFrame() {

    }

    /**
     * Launch the application.
     */
     public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    MainFrame frame = new MainFrame();

                    frame.setSize(1200, 1200);

                    PanelClass1 panelClass1 = new PanelClass1();
                    PanelClass2 panelClass2 = new PanelClass2();

                    panelClass1.addObserver(panelClass2);

                    frame.getContentPane().add(panelClass1,BorderLayout.PAGE_START);
                    frame.getContentPane().add(panelClass2, BorderLayout.PAGE_END);
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

I hope this helped you solve your problem.

Cheers

xoX Zeus Xox
  • 195
  • 1
  • 14