We want two panels, with three buttons each labelled Red, Blue and Yellow. Clicking a button should change the colour of both panels to the appropriate colour.
Here, we make both panels listen to all six buttons. However, each panel has a reference only to the three buttons that are defined within it. Thus, we cannot directly use getSource() to decode the identity of a button from the other panel.
An alternative solution is to use the ActionCommand associated with a button. In the ButtonPanel, we set an ActionCommand with each button when we create it. In ActionPerformed we examine the ActionCommand of the button that was pressed to decide which colour to choose. We do not associate a listener with each button in the panel when we construct the panel. Instead, we provide a method addListener that adds a listener to all three buttons in the panel. This is invoked by the surrounding ButtonFrame, which defines two ButtonPanels and makes both of them listeners for each other.