简体   繁体   中英

Multiple Jbutton and ActionListener using inner class

There are two buttons for this app. One is for randomly changing color when clicked and the other is for changing a label in the app.

The problem is although I've write sepreate ActionListener classes and registered them with correspondence methods respectively.

Every time I click the "change label" button, the color changes as well. What's going on here?

package my;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.ArrayList;

    import javax.swing.*;

    public class SimpleGui3C {

        JFrame frame;
        JLabel label;

        public static void main(String[] args){
            SimpleGui3C gui = new SimpleGui3C();
            gui.go();
        }

        public void go(){
            frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            JButton labelButton = new JButton("Change Label");
            labelButton.addActionListener(new LabelListener());

            JButton colorButton = new JButton("Change Circle");
            colorButton.addActionListener(new ColorListener());

            label = new JLabel("I'm a label");

            MyDrawPanel drawPanel = new MyDrawPanel();

            frame.getContentPane().add(BorderLayout.SOUTH,colorButton);
            frame.getContentPane().add(BorderLayout.CENTER,drawPanel);
            frame.getContentPane().add(BorderLayout.EAST, labelButton);
            frame.getContentPane().add(BorderLayout.WEST, label);

            frame.setSize(300,300);
            frame.setVisible(true);


        }

        class LabelListener implements ActionListener{
            public void actionPerformed(ActionEvent event1) {
                ArrayList<String> labelContent = new ArrayList<String>();
                labelContent.add("Ouch!");
                labelContent.add("Damn!");
                labelContent.add("Holy shit!");
                labelContent.add("WTF?!");
                labelContent.add("Stop it!");
                labelContent.trimToSize();

                int i = (int)(Math.random()*5);
                String a = (String)labelContent.get(i);
                label.setText(a);
            }
        }

        class ColorListener implements ActionListener{
            public void actionPerformed(ActionEvent event2) {
                frame.repaint();
            }
        }
    }

            package my;
            import java.awt.*;
            import javax.swing.*;

            public class MyDrawPanel extends JPanel{
                /**
                 * 
                 */
                private static final long serialVersionUID = 1L;

                public void paintComponent(Graphics g){
                    Graphics2D g2d = (Graphics2D) g;

                    int red = (int)(Math.random()*255);
                    int blue = (int)(Math.random()*255);
                    int green = (int)(Math.random()*255);
                    Color startColor = new Color(red,blue,green);

                    red = (int)(Math.random()*255);
                    blue = (int)(Math.random()*255);
                    green = (int)(Math.random()*255);
                    Color endColor = new Color(red,blue,green);

                    int startPositionX = (int)(Math.random()*70);
                    int startPositionY = (int)(Math.random()*70);

                    int endPositionX = (int)(Math.random()*150);
                    int endPositionY = (int)(Math.random()*150);

                    GradientPaint gradient = new GradientPaint(startPositionX,startPositionY,startColor,endPositionX,endPositionY,endColor);
                    g2d.setPaint(gradient);
                    g2d.fillOval(20,60,100,100);

                }
            }

Most probably when you change label a repaint() is called and MyDrawPanel.paintComponent() is called and frame repainted with random color.
Better implementation can be:

class SimpleGui3C {
  Color startColor;
  Color endColor;

  ColorListener() {
    startColor = <code to generate a random color>;
    endColor = <code to generate a random color>;
    repaint();
  }
}

and in MyDrawPanel.paintComponent() use startColor and endColor generated by listener; remember to init Color variables to avoid NPE!

Each time you click labelButton it is firing a repaint event for MyDrawPanel .

This causes the color to be randomly generated again, changing the color of MyDrawPanel .

I suggest fixing this by calling a method from ColorListener on MyDrawPanel which changes its color. This will keep the panel from changing color every repaint.

And here's precisely how to do it:

class ColorListener implements ActionListener{
    MyDrawPanel colorPanel;
    public ColorListener(MyDrawPanel panel){
        this.colorPanel = panel;
    }

    public void actionPerformed(ActionEvent event2) {
        colorPanel.generateRandomColor();
        frame.repaint();
    }
}

public class MyDrawPanel extends JPanel{
    GradientPaint gradient;
    public MyDrawPanel(){ 
        generateRandomColor();
    }
    public void generateRandomColor(){
        int red = (int)(Math.random()*255);
        int blue = (int)(Math.random()*255);
        int green = (int)(Math.random()*255);
        Color startColor = new Color(red,blue,green);

        red = (int)(Math.random()*255);
        blue = (int)(Math.random()*255);
        green = (int)(Math.random()*255);
        Color endColor = new Color(red,blue,green);

        int startPositionX = (int)(Math.random()*70);
        int startPositionY = (int)(Math.random()*70);

        int endPositionX = (int)(Math.random()*150);
        int endPositionY = (int)(Math.random()*150);

        gradient = new GradientPaint(startPositionX,startPositionY,
            startColor, endPositionX,endPositionY,endColor);
     }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM