I've hit a roadblock on this one and was hoping for some insight.
Here's the basic gist of what I'm trying to accomplish:
-I have a piece
class (extending JPanel
) that has an array of JRadioButton
, as well as a JLabel
that updates according to which button is selected. This part works fine.
-I have a "master" JFrame
class that calls a couple different piece
s and puts them on a frame - did this to keep things from getting unwieldy, it's easier to have each piece be its own class.
-For various purposes, I want to put a JLabel
on the master
frame that also shows which button is selected - in essence, I want to put a JLabel
that is a copycat of the one in the piece
class and updates whenever the piece
label does. I don't know if I'm just being dumb but I can't get the one on the master
to update whenever the piece
one does - it just stays at the initial one. Is there a way to have this label update whenever the other one does?
"Piece" (basic example, not the real thing):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
public class Piece2 extends JPanel {
//variables
final JLabel on = new JLabel("NONE");
String names[] = {
"button 1","button 2","button 3"
};
private ActionListener buttonAction = new ActionListener(){
public void actionPerformed (ActionEvent ae){
String buttonText = ((JRadioButton) ae.getSource()).getText();
on.setText(buttonText);
}
};
void createList(){
Box contentPanel = Box.createVerticalBox();
ButtonGroup buttons123 = new ButtonGroup();
final JRadioButton choiceButtons[]=new JRadioButton[names.length];
for(int i=0;i<(names.length);i++){
choiceButtons[i] = new JRadioButton(names[i]);
choiceButtons[i].addActionListener(buttonAction);
buttons123.add(choiceButtons[i]);
contentPanel.add(choiceButtons[i]);
}
contentPanel.add(on);
this.add(contentPanel);
setVisible(true);
};
public static void main(String[] args) {
// TODO Auto-generated method stub
new Piece2().createList();
}
}
"MASTER" (again, very bare-bones example):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;
import javax.swing.event.*;
import java.util.*;
public class CollectGUI extends JFrame{
JLabel p2on = new JLabel("NONE");
private void createDialog(){
this.setSize(2000,1000);
this.setLocation(0,0);
this.setTitle("TITLE");
JPanel mainpanel = new JPanel();
mainpanel.setLayout(new BorderLayout());
final Piece2 piece = new Piece2();
piece.createList();
mainpanel.add(piece, BorderLayout.WEST);
//THIS IS THE PART WHERE I GET STUCK
p2on.setText(piece.on.getText());
//I KNOW IT ONLY SETS IT ONCE, HOW DO I GET IT TO UPDATE WHEN ON DOES?
mainpanel.add(p2on, BorderLayout.EAST);
this.add(mainpanel);
this.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new CollectGUI().createDialog();
}
}
So like I said I can get the label on there and set it once, but haven't figured out how to get it to update whenever on does... is there a way to "append" to the piece-class action listener from the master class? Or some kind of listener I can add to the p2on label that listens for when the on label changes? I'm pretty stumped. Thank you for your help!!
You could use some kind of Observer Pattern, where both the
JPanel
and frame use a common object/model to make changes to the current state of the game, but which also provides event notifications so that the two can update themselves accordinglyThis would also be related to Model-View-Controller, which would allow you to separate the visuals from the logic, decoupling your code
I'd prefer to have a model which controlled the logic and notified interested parties, but in your case, you "could" just use a
PropertyChangeListener
...So, in your
Piece2
class'sActionListener
, you would need to trigger a property change event...And in your
CollectionGUI
, monitor for that eventI'd also discourage you from extending directly from a top level container like
JFrame
, it locks you into a single use-case and reduces the re-usability of your class and you're not really adding any new functionality to the class either