Class extension error

I'm new to Java so don't know what will go wrong. I have code here that when it is executed should "open" the window once, but whenever I extend the class ColoredWordsExperiment

in the class ButtonHandler

, the window opens infinitely very quickly, which almost causes my computer to crash every time. If I give up the extension, it works fine, but then I cannot use class objects ColoredWordsExperiment

in the class ButtonHandler

... You can find the code below (I left some irrelevant things, otherwise it would 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");
    }
}
}

      

+3


source to share


4 answers


In this case, there is no reason to expand ColoredWordsExperiment

. You should just implement ActionListener

.

You are essentially initializing another instance ColoredWordsExperiment

within yourself with one additional method. This causes your constructor to be called again, which forces the GUI window to recreate.
See Inheritance for details .

If you want to change a field in ColoredWordsExperiment

from your implementation ActionListener

, you will want to pass a reference at build time.

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 to create an anonymous inner class. With this technique, you can get rid of the class entirely ButtonHandler

.
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

+2


source


In the constructor of the parent class, you create one of those ButtonHandlers, which in turn runs the constructor code again. You must not instantiate this class in the constructor (or use a different name for it if you are trying to use it with the same name)



+1


source


Ok I can see what the problem is. Now I don't know why you want to extend it, I'm just trying to answer your question (b / c there is no need to extend the action listener for your main class). when you define a method of a class that you did not put to the public and then when you put it under the main method to run it, it can get confused and create infinite frames. You have to change it to this:

public class ColoredWordsExperiment {
    JFrame frame;
    ButtonHandler buttonHandler;

   public ColoredWordsExperiment(){//add the public!
    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();
    }

}

      

Also, it is not recommended to define your variable buttonHandler

as your ButtonHandler class in your main class, but then you will have your ButtonHandler class from the main class. which can trigger the cycle. you must either not extend your second class or define your variable buttonHandler

differently.

0


source


It sounds like you need to read and understand the difference between classes and objects . To help you with this, I want to illustrate the problem with how you originally thought of your code with a simplified example:

class A {
    int x;
    B b = new B();
}

class B extends A {
}

class Main {
    public static void main(String args[]) {
        A a = new A();
        a.x = 42;
        a.b.x = 53;

        System.out.println(a.x);
        System.out.println(a.b.x);
    }
}

      

As expected, the object a

in main()

has a field named x

, and we can set it to 42. However, the object b

inside a

has its own named name x

, which is completely unrelated to the field x

inside the object a

.

If you can dive into the concept of objects, you will be well on your way to becoming a good Java programmer.

0


source







All Articles