如何外部化 MouseListener?

How to externalize a MouseListener?

(注意: 我知道 MouseAdapter-class 的存在,但由于我稍后可能会覆盖所有方法,所以它的优势消失了?)

我有一个 class MainProgram.java,我在其中添加了几个组件。它们中的大多数都有一个 Listener(ActionListener、MouseListener,...),这在我的主 class 中有点拥挤。

因此我正在尝试 "externalize" 那些听众进入他们自己的 classes。到目前为止,我在我的 main-class 中使用了内部 classes,这使得访问变量、组件……非常简单直接。

但是对于外部侦听器,我不确定实现它们的最佳方式是什么。

例如,当我想知道点击了哪个标签时,我正在获取事件,获取事件源,将其转换为 JLabel 然后获取文本在我比较字符串的标签上!

这有效,但似乎很容易出错(如果我在主 class 中更改 JLabel 文本怎么办?-> 监听器中断)并且非常不干净。

我试图通过 google 和 Whosebug 搜索更好的方法,但只找到了内部 class 方法。

那么有没有更好的方法来访问我的组件/外部化我的听众?

public class MainProgram extends JFrame {
    public MainProgram() {
        super("Landing Page");
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel westPanel = new JPanel();

        JLabel lbl_orderStatus = new JLabel("Order Status");
        JLabel lbl_technicalDocu = new JLabel("Technical Documentation");
        JLabel lbl_checkReport = new JLabel("Check Report");

        MouseListenerBoldFont mouseListenerLabelBoldPlain = new MouseListenerBoldFont();

        lbl_orderStatus.addMouseListener(mouseListenerLabelBoldPlain);
        lbl_technicalDocu.addMouseListener(mouseListenerLabelBoldPlain);
        lbl_checkReport.addMouseListener(mouseListenerLabelBoldPlain);

        westPanel.add(lbl_orderStatus);
        westPanel.add(lbl_technicalDocu);
        westPanel.add(lbl_checkReport);
        add(westPanel);
    }

    public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                MainProgram window = new MainProgram();
                window.setVisible(true);
            } 
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

MouseListenerBoldFont.java:

public class MouseListenerBoldFont implements MouseListener{

    Object lbl_westPanel;

    @Override
    public void mouseClicked(MouseEvent e) {
        if(((JLabel)e.getSource()).getText().equals("Order Status")){
            System.out.println("Order Status clicked");
        };
        if(((JLabel)e.getSource()).getText().equals("Technical Documentation")){
            System.out.println("Technical Documentation clicked");
        };
        if(((JLabel)e.getSource()).getText().equals("Check Report")){
            System.out.println("Check Report clicked");
        };
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        lbl_westPanel = e.getSource();
        ((JComponent) lbl_westPanel).setFont(new Font("tahoma", Font.BOLD, 12));
    }

    @Override
    public void mouseExited(MouseEvent e) {
        lbl_westPanel = e.getSource();
        ((JComponent) lbl_westPanel).setFont(new Font("tahoma", Font.PLAIN, 11));
    }

    @Override
    public void mousePressed(MouseEvent e) {    
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }
}

您可能仍想使用扩展 MouseAdapter 的 class,因为它可以同时用作 MouseListener、MouseMotionListener 和 MouseWheelListener(您只需添加它作为所有这些成一个组件)。我不确定为什么您需要获取 JLabel 上的文本以检测它是否已被单击。您应该创建一个扩展 MouseAdapter 的 class 并使其专用于 JLabel,然后将其添加到该 JLabel。如果您希望将 JLabel 作为参数,您应该定义一个自定义构造函数,以便它自动知道正在与什么 JLabel 进行交互。然后,您可以添加一个将事件传递给主 class.

的方法

我的建议是编写内联 (anonymous-class) 处理程序,将实际处理转发给另一个 non-anonymous 函数。这会给你类似的东西:

    JLabel lblOrderStatus = new JLabel("Order Status");
    lblOrderStatus.addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent evt) { 
            doWhateverClickOnOrderStatusRequires();
        }
    });

    // much later
    private void doWhateverClickOnOrderStatusRequires() { ... }

外部not-quite-handler方法的名称(doWhateverClickOnOrderStatusRequires)应该捕获它试图完成的任务(例如,launchRockets);使用此模式,您可以从多个处理程序调用相同的 not-quite-handler 方法。由于编译器将检查调用是否有效 compile-time,因此不涉及脆弱的 string-constants。

确定这不是最好的方法,但可能对您的问题有用

public class MyLabel extends JLabel implements MouseListener {
    public MyLabel() {
        addMouseListener(this);
    }
    public MyLabel(String txt) {
        super(txt);
        addMouseListener(this);
    }
    public void mouseClicked(MouseEvent e) {
        System.out.println(getText() + " clicked");
    }
    public void mouseEntered(MouseEvent e) {
        setFont(new Font("tahoma", Font.BOLD, 12));
    }
    public void mouseExited(MouseEvent e) {
        setFont(new Font("tahoma", Font.PLAIN, 11));
    }
    public void mousePressed(MouseEvent e) { }
    public void mouseReleased(MouseEvent e) { }
}

然后

    JLabel lbl_orderStatus = new MyLabel("Order Status");
    JLabel lbl_technicalDocu = new MyLabel("Technical Documentation");
    JLabel lbl_checkReport = new MyLabel("Check Report");

//        MouseListenerBoldFont mouseListenerLabelBoldPlain = new MouseListenerBoldFont();
//
//        lbl_orderStatus.addMouseListener(mouseListenerLabelBoldPlain);
//        lbl_technicalDocu.addMouseListener(mouseListenerLabelBoldPlain);
//        lbl_checkReport.addMouseListener(mouseListenerLabelBoldPlain);