I made a desktop application to handle the configuration of some web services, it works but the code is hard to maintain because all de logic view is in the same class (main class), so I decided to redo it and apply the MVC architecture and the React philosophy to split the complex app into simple and reusable components. I end up whit this:

My app has a JFrame that has a main JPanel, this main JPanel has many other JPanels but the mains ones are centerJPanel and SaveJPanel for demonstration purposes. The centerJPanel has my Composite Component (blue rectangle), ContenedorSwtBtn.
My ContenedorSwtBtn consists of JPanel, JLabel for the title, and SwitchToggleBtn component, and I can have as many SwitchToggleBtn as I want because the idea is to add them dynamically.

My SwitchToggleBtn consists of a JPanel, JLabel for the name, and JToggleButton.

The code (Sorry for the Spanish word) for MyComponent: SwitchToggleBtn:
public class SwitchToggleBtn extends JPanel
{
private JToggleButton SwtBtn;
private JLabel nombLogs;
private String Name;
public SwitchToggleBtn(String Nombre, boolean bandera)
{
super(new BorderLayout(10,10));
this.Name = Nombre;
this.setBackground(new java.awt.Color(255, 255, 255));
this.setBorder( new EmptyBorder( 5, 5, 5, 12));
this.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(153, 153, 153)));
this.nombLogs = new JLabel(Nombre);
this.nombLogs.setFont(new java.awt.Font("Segoe UI Symbol", 0, 14));
this.add(nombLogs, BorderLayout.WEST);
this.SwtBtn = new JToggleButton();
this.SwtBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/principal/icon/btnToggleOff.png"))); // NOI18N
this.SwtBtn.setBorder(null);
this.SwtBtn.setBorderPainted(false);
this.SwtBtn.setContentAreaFilled(false);
this.SwtBtn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
this.SwtBtn.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/principal/icon/btnToggleOffDisabled.png"))); // NOI18N
this.SwtBtn.setDisabledSelectedIcon(new javax.swing.ImageIcon(getClass().getResource("/principal/icon/btnToggleOnDisable.png"))); // NOI18N
this.SwtBtn.setFocusPainted(false);
this.SwtBtn.setMaximumSize(new java.awt.Dimension(70, 34));
this.SwtBtn.setMinimumSize(new java.awt.Dimension(70, 34));
this.SwtBtn.setPreferredSize(new java.awt.Dimension(70, 34));
this.SwtBtn.setSelected(bandera);
this.SwtBtn.setName(Nombre);
IsSelected();
this.SwtBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
IsSelected();
}
});
this.add(SwtBtn, BorderLayout.EAST);
this.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
mouseclicked(evt);
}
});
}
private void IsSelected()
{
if (this.SwtBtn.isSelected())
this.SwtBtn.setIcon(new ImageIcon(getClass().getResource("/principal/icon/btnToggleOn.png")));
else
this.SwtBtn.setIcon(new ImageIcon(getClass().getResource("/principal/icon/btnToggleOff.png")));
}
}
The code (Sorry for the Spanish word) for ContenedorSwtBtn:
public class ContenedorSwtBtn extends JPanel
{
public ContenedorSwtBtn(String Nombre)
{
super();
this.setBackground(new java.awt.Color(255, 255, 255));
this.setBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(153, 153, 153)));
this.setToolTipText("");
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JLabel titulo = new JLabel();
titulo.setBackground(new java.awt.Color(0, 0, 0));
titulo.setFont(new java.awt.Font("Dialog", 1, 14)); // NOI18N
titulo.setForeground(new java.awt.Color(0, 51, 51));
titulo.setText(Nombre);
titulo.setAlignmentX(Component.CENTER_ALIGNMENT);
this.add(titulo);
}
public void AddComponent(String nombreLog, boolean bandera)
{
SwitchToggleBtn log = new SwitchToggleBtn(nombreLog, bandera);
this.add(log);
}
}
This is the final result :

when I clicked the JToggleButton inside of my SwichToggleBtn component it changes his state and changes the icon from off to on or vice versa.
And finally is matter of create the new component and add it into the main JPanel like this:
JPanel MainPanel= new JPanel();
MainPanel.setBackground(new java.awt.Color(255, 255, 255));
MainPanel.setEnabled(true);
MainPanel.setMaximumSize(new java.awt.Dimension(300, 280));
MainPanel.setMinimumSize(new java.awt.Dimension(300, 280));
MainPanel.setPreferredSize(new java.awt.Dimension(300, 280));
MainPanel.setVisible(true);
ContenedorSwtBtn myComponent= new ContenedorSwtBtn("SETTINGS");
myComponent.AddComponent("ONE", true);
myComponent.AddComponent("TWO", false);
myComponent.AddComponent("THREE",true);
MainPanel.add(myComponent);
When I clicked the JToggleButton and changes its state I want the exact component and its current state but from the main Jpanel or the center panel so that way I can "Save change" (red button from SaveJpanel) and implement some logic to save the configuration. How I pass the event from the child component to the parent's components or how from the parent's components can know when a child component changes its state. I read about creating a class that implements the actionlistener interface or implements the PropertyChangesListener interface but I don understand. thanks a lot for your help.
I am not sure what you are wanting to do given your question has anything to do with MVC (For an example of an MVC Swing app please look here), as far as I can tell all you really need is to bubble up events from your custom control so that you can register to receive these events in your main panel.
This can easily be done. Check my below example.
Essentially:
ButtonPanelis its own "component" (it doesnt extendJPanelas I dont think thats necessary, instead has a gettergetPanel()for the component it creates).ButtonPanelalso implements anActionListenerfor the buttons events it createsButtonPanelhas the ability to add anActionListenerviaaddActionListenerso others may register forActionEvents sent from theButtonPanel.TestApp.java:
ButtonPanel.java: