I am asking about the right way to make a component that holds some state. This includes a Jbutton that saves a color in it, or a list item that saves a certain object. So when those GUI components fire an event, I can use the saved states to do something with it.
My way is like this:
Make a subclass of the required component, like a subclass from Jbutton.
Make a Listener for this new subclass: in the listener check, if the event source is the subclass, convert it and then use the stored data.
class ColorButton extends JButton
{
static class Listener implements ActionListener{
@Override
public void actionPerformed(ActionEvent actionEvent) {
Object source = actionEvent.getSource();
if( source.getClass() == ColorButton.class)
{
ColorButton t = (ColorButton) source;
t.getComponent().setBackground(t.getColor());
}
}
}
//states i want to be saved
private Color c;
private Component comp;
ColorButton(Component comp, Color c) {
setColorChanger(comp, c);
}
/* ......
......
rest of constructors added with those additions
......
*/
private void setColorChanger(Component comp, Color c)
{
this.comp = comp;
this.c = c;
}
Color getColor() {
return c;
}
Component getComponent() {
return comp;
}
}
And I use it this way:
JPanel panel = new JPanel();
ColorButton.Listener l = new ColorButton.Listener();
JButton b = new ColorButton("Blue", panel, Color.BLUE);
JButton r = new ColorButton("Red", panel, Color.RED);
r.addActionListener(l);
b.addActionListener(l);
panel.add(b);
panel.add(r);
add(panel);
I am wondering: is this way okay? I feel it is very boring to make this for every component that should hold a certain state. Is there a better way?
1 Answer 1
Instead of comparing the class with if( source.getClass() == ColorButton.class)
you can use if (source instanceof ColorButton)
. This is preferable in case you would make a subclass of ColorButton
. If it's an instance of a subclass of ColorButton
it is still an instanceof
but source.getClass() != ColorButton.class
.
With the way that you are using the code above, I would save the color in the listener instead of in the button. This way you don't need the if statement in your code at all, since you can pass the appropriate type to the Listener. In this case, .setBackground
is declared in the JComponent
class so all you need to make sure is that it's a JComponent
that gets passed to the Listener, which is no problem:
static class Listener implements ActionListener {
private Color color;
private JComponent comp;
public Listener(JComponent comp, Color color) {
this.color = color;
this.comp = comp;
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
comp.setBackground(this.color);
}
}
By using this, you don't need the ColorButton
subclass, instead you create multiple instances of your listener:
JPanel panel = new JPanel();
JButton b = new JButton("Blue");
JButton r = new JButton("Red");
r.addActionListener(new Listener(panel, Color.BLUE));
b.addActionListener(new Listener(panel, Color.RED));
panel.add(b);
panel.add(r);
add(panel);
-
1\$\begingroup\$ much better than making contructors for the subclass which saves time and it and less code \$\endgroup\$Karim Tarabishy– Karim Tarabishy2013年11月08日 10:45:07 +00:00Commented Nov 8, 2013 at 10:45