3
\$\begingroup\$

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:

  1. Make a subclass of the required component, like a subclass from Jbutton.

  2. 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?

\$\endgroup\$
4
\$\begingroup\$

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);
\$\endgroup\$
1
  • 1
    \$\begingroup\$ much better than making contructors for the subclass which saves time and it and less code \$\endgroup\$ Nov 8 '13 at 10:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.