2

我有一个图标,旁边有一个复选框,包含在面板中。面板有悬停效果,我想在点击面板时选择框。

我想消耗或阻止复选框的所有事件,仅以编程方式选择它。我希望该框在屏幕上显示为“启用”,而“在幕后”它几乎没有功能。(可以通过单击面板进行选择。)

此外,当我鼠标进入/退出复选框时,我不希望发生任何事情。我在面板上有悬停效果。现在,我可以进入面板,但是当我进入该框时,面板退出,并且看起来没有悬停。

那么,如何防止此复选框上的所有与鼠标相关的活动- 进入、退出、单击等。从以前的研究中,我记得流行词“消费事件”,但我似乎无法鼓起适当的搜索来做到这一点发生:)

=============

编辑

在此处输入图像描述

这个面板(紫色)有一个图标(汉堡)和一个复选框(UI LAF)。我想悬停面板,当我输入复选框时不会失去悬停,并在单击(父)面板时切换复选框。

4

5 回答 5

3

覆盖dispatchEvent()并创建一个新实例,然后替换旧实例EventQueuepush()在您的新实现中,调用与您的复选框相关的事件之外super.dispatchEvent()的所有事件。相关示例可以在这里找到,完整的实现可以在Disabled Panel中找到。

或者,使用Toolkit.getDefaultToolkit().addAWTEventListener()(如此处所示)省略不需要的事件。

附录:还考虑使用复选框按钮模型的这种更用户友好的替代方案:

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/a/10238761/230513 */
public class PanelClick extends JPanel {

    JCheckBox jcb = new JCheckBox("Check");
    private boolean selected = jcb.isSelected();

    public PanelClick() {
        this.setPreferredSize(new Dimension(320, 240)); // room to click
        this.add(jcb);
        this.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                selected = !jcb.isSelected();
                jcb.setSelected(selected);
            }
        });
    }

    private void display() {
        JFrame f = new JFrame("PanelClick");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new PanelClick().display();
            }
        });
    }
}
于 2012-04-20T00:35:44.303 回答
2

这可以作为解决方案吗?

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

public class PanelCheckBox {

    private JPanel panel = new JPanel();
    private JCheckBox checkBox = new JCheckBox();
    private JLabel icon = new JLabel(new SquareIcon());

    private void showGui() {
        final JFrame frame = setupGui();

        SwingUtilities.invokeLater(new Runnable() {
            @Override public void run() { 
                frame.setVisible(true);
            }
        });
    }

    private JFrame setupGui() {
        panel.add(icon);
        panel.add(checkBox);
        panel.setOpaque(true);
        JFrame frame = new JFrame("Hello");
        frame.add(panel, BorderLayout.CENTER);

        setupListeners();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 200);
        return frame;
    }

    private void setupListeners() {
        panel.addMouseListener(new MouseAdapter() {
            Color origColor = null;
            Color hoverColor = new Color(200, 180, 180);

            @Override public void mouseEntered(MouseEvent me) {
                if (origColor == null) {
                    origColor = panel.getBackground();
                }
                panel.setBackground(hoverColor);
            }

            @Override public void mouseExited(MouseEvent me) {
                Point location = me.getPoint();

                if (!panel.contains(location)) {
                    panel.setBackground(origColor);
                }
            }

            @Override public void mouseClicked(MouseEvent me) {
                checkBox.doClick();
            }
        });
    }

    public static void main(String[] args) {
        PanelCheckBox thing = new PanelCheckBox();
        thing.showGui();
    }

    static class SquareIcon implements Icon {

        @Override
        public void paintIcon(Component cmpnt, Graphics grphcs,
                              int i, int i1) {
            Color origColor = grphcs.getColor();
            grphcs.setColor(Color.BLUE);
            grphcs.fillRect(0, 0, 25, 25);
            grphcs.setColor(origColor);
        }

        @Override public int getIconWidth() { return 25; }

        @Override public int getIconHeight() { return 25; }
    }
}
于 2012-04-20T02:13:15.130 回答
1

我希望该框在屏幕上显示为“启用”,而“在幕后”它几乎没有功能。

我会发现重复单击一个应该启用的复选框以查看它做..nothing 是非常令人沮丧的。也许你应该弹出一个:

JOptionPane.showErrorMessage(checkbox, "Click the panel!"); 
于 2012-04-20T01:03:18.323 回答
1

您可以覆盖该复选框的 mouselistener 以不执行任何操作:

class MyBox extends JCheckBox {

    @Override
    protected void processMouseEvent(MouseEvent e) {
    //this will prevent all mouse actions 
    }
}

然后只使用 MyBox 而不是复选框?

于 2012-07-24T08:48:28.913 回答
0

我对此的最终解决方案是使用EmptyBorder复选框左侧的一个,以及 BlackPanda 的鼠标侦听器解决方案:

public class CheckboxPanel extends JPanel {
    private final JCheckBox checkBox = new JCheckBox();
    private final Image img;

    public CheckboxPanel (final Image img0) {
        super();
        this.img = img0;

        // Left padding of 20 allows mouseovers on image that trigger the box.
        checkBox.setBorder(new EmptyBorder(0, 20, 0, 0)); 

        add(checkBox);

        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(final MouseEvent me) {
                checkBox.doClick();
            }
        });
    }

    public JCheckBox getCheckBox() {
        return this.checkBox;
    }

    @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);
        g.drawImage(img, 0, 0, null);
    }
}
于 2012-05-20T06:57:27.337 回答