【问题标题】:Button can't find the Listener class按钮找不到监听器类
【发布时间】:2023-03-19 12:04:01
【问题描述】:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JPanel;

class Painter extends JPanel implements ActionListener{
private int x = 30, y = 30;
//remove the blocked comment to make it run
/*public Painter(){
    Buttons b = new Buttons(new String("Click to paint"));
    b.addActionListener(this);
    add(b);
}*/
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(new Color(44,55,66));
g.fillRect(200,200,x,y);
}
public void actionPerformed(ActionEvent e){
    x = 600;
    y = 600;
    repaint();
}
}
import javax.swing.JButton;


public class Buttons extends JButton{
public Buttons(String Tag){
    super(Tag);
    setBounds(20, 20, 150, 50);
    Painter p = new Painter();//comment it out
    addActionListener(p);//comment it out
}
}
import java.awt.Color;

import javax.swing.JFrame;


public class Window extends JFrame{
public Window(){
    Buttons b = new Buttons("Click Me");//comment it out
    Painter p = new Painter();
    getContentPane().add(b);//comment it out
    getContentPane().add(p);
    getContentPane().setBackground(Color.WHITE);
    setSize(700,700);
    setVisible(true);
    setResizable(false);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}

public class PaintOnEvent {
public static void main(String[] args){
    Window w = new Window();
}
}

这是一个测试程序。我使用addActionListener()方法将Painter类注册到Buttons类,那为什么还是找不到actionperformed方法呢?然后,当我在画家类本身中创建一个按钮时,它就起作用了。为什么会这样?

【问题讨论】:

    标签: java swing event-handling listener


    【解决方案1】:

    您至少有两个 Painter 对象。显示的不是用作 ActionListener 对象的那个。例如,如果您将显示的 Painter 对象的引用传递给您的 Button 类会怎样(更改由 \!! cmets 表示):

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    class Painter extends JPanel implements ActionListener {
        private int x = 30, y = 30;
    
        // remove the blocked comment to make it run
        /*
         * public Painter(){ Buttons b = new Buttons(new String("Click to paint"));
         * b.addActionListener(this); add(b); }
         */
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(new Color(44, 55, 66));
            g.fillRect(200, 200, x, y);
        }
    
        public void actionPerformed(ActionEvent e) {
            x = 600;
            y = 600;
            repaint();
        }
    }
    
    class Buttons extends JButton {
        public Buttons(String Tag, Painter p) {  \\!!
            super(Tag);
            setBounds(20, 20, 150, 50);
            // !! Painter p = new Painter();// comment it out
            addActionListener(p);// comment it out
        }
    }
    
    class Window extends JFrame {
        public Window() {
            Painter p = new Painter();// !!
            Buttons b = new Buttons("Click Me", p);// comment it out //!!
            getContentPane().add(b);// comment it out
            getContentPane().add(p);
            getContentPane().setBackground(Color.WHITE);
            setSize(700, 700);
            setVisible(true);
            setResizable(false);
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        }
    }
    
    public class PaintOnEvent {
        public static void main(String[] args) {
            Window w = new Window();
        }
    }
    

    一个考虑到 contentPane 的 BorderLayout 的例子如下:

    class Window extends JFrame {
        public Window() {
            Painter p = new Painter();
            Buttons b = new Buttons("Click Me", p); // !!
            b.setPreferredSize(new Dimension(150, 50));
    
            JPanel btnPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); // !!
            btnPanel.setOpaque(false); // !!
            btnPanel.add((b)); // !!
            p.setOpaque(false); // !!
    
            getContentPane().add(btnPanel, BorderLayout.NORTH); // !!
            getContentPane().add(p, BorderLayout.CENTER); // !!
            getContentPane().setBackground(Color.WHITE);
            ((JPanel) getContentPane()).setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); // !!
            // !! setSize(700, 700);
            setPreferredSize(new Dimension(700, 700)); // !!
            pack(); // !!
            setLocationRelativeTo(null); // !!
            setVisible(true);
            setResizable(false);
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        }
    }
    

    【讨论】:

    • 你是对的,它实际上有两个画家实例。但是,当我按照您所说的进行操作时,该按钮会经常显示。是不是因为按钮和面板是分开添加到窗口的?
    • 您的代码中存在一些布局问题。摆脱按钮的 setBounds 方法并使用适当的布局管理器可能会有很大帮助。你要明白顶层的window contentPanes默认使用BorderLayout,所以如果你添加组件而不考虑这一点,你会遇到麻烦。
    • 例如,请参阅上面关于考虑到 BorderLayout 的布局管理器更改的代码附录
    猜你喜欢
    • 2013-12-24
    • 2021-02-15
    • 1970-01-01
    • 2016-08-27
    • 2013-07-31
    • 2012-02-04
    • 2020-12-21
    • 1970-01-01
    相关资源
    最近更新 更多