Search code examples
javaextend

Error when extending class


I'm pretty new to Java, so I don't know what's going wrong. What I have here is a code that is, when it's executed, supposed to "open" a window once, but whenever I extend the class ColoredWordsExperiment in the ButtonHandler class, the window opens infinitely really quickly which nearly causes my computer to crash everytime. If I leave out the extension then it works fine, but then I won't be able to use the objects from the ColoredWordsExperiment class in the ButtonHandler class... Below you can find the code (I left some unimportant stuff out otherwise it'd become too long).

public class ColoredWordsExperiment {
    JFrame frame;
    ButtonHandler buttonHandler;

ColoredWordsExperiment(){
    frame = new JFrame("Colored Words Experiment");
    frame.setSize(1200, 150);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    button1 = new JButton("Matching");

    label1 = new JLabel("test");
    label1.setPreferredSize(new Dimension(90, 40));

    JPanel labelContainer = new JPanel();
    labelContainer.add(label1);

    JPanel buttonContainer = new JPanel();
    buttonContainer.add(button1);

    frame.add(buttonContainer, BorderLayout.SOUTH);
    frame.add(labelContainer, BorderLayout.NORTH);

    buttonHandler = new ButtonHandler();
    button1.addActionListener(buttonHandler);
}

public static void main(String[] arg) {
     new ColoredWordsExperiment();
}

}

-

public class ButtonHandler extends ColoredWordsExperiment implements ActionListener {
@Override
public void actionPerformed(ActionEvent e){
    if (e.getActionCommand().equals("Matching")) {
        System.out.println("Matching");
        label1.setText("Text changed");
    }
}
}

Solution

  • There's no reason to extend ColoredWordsExperiment in this case. You should simply be implementing ActionListener.

    You're essentially initializing another instance of ColoredWordsExperiment inside itself with a single additional method. This causes your constructor be called again, which causes the GUI window to be recreated.
    See Inheritance for more details.

    If you want to change a field in ColoredWordsExperiment from your ActionListener implementation, you'll want to pass a reference during construction.

    public class ButtonHandler implements ActionListener {
        ColoredWordsExperiment coloredWords;
        public ButtonHandler(ColoredWordsExperiment coloredWords) {
            this.coloredWords = coloredWords;
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getActionCommand().equals("Matching")) {
                System.out.println("Matching");
                coloredWords.label1.setText("Text changed");
            }
        }
    }
    

    In this case, you also have the option of creating an anonymous inner class. With this technique, you can completely get rid of the ButtonHandler class.
    Inside ColoredWordsExperiment instead of

    buttonHandler = new ButtonHandler();
    button1.addActionListener(buttonHandler);
    

    You can use

    button1.addActionListener(new ActionListener() {
        if (e.getActionCommand().equals("Matching")) {
            System.out.println("Matching");
            label1.setText("Text changed");
        }
    });
    

    See Anonymous Classes