繁体   English   中英

如何通过鼠标移动检测 JLabel 中的点击? (比如 JButton)?

[英]How can I detect a click in a JLabel with mouse movement? (like JButton)?

我想以类似于 JButton 可用的“ActionListener.actionPerformed()”功能的方式检测 JLabel 中的鼠标单击事件。
我怎样才能做到这一点? 其他详细信息如下。

MouseAdapter 类的功能与 JButton 可用的 ActionListener 功能不同。 如果鼠标指针在 mousePressed 和 mouseReleased 事件之间移动(即使是轻微移动),则 MouseAdapter.mouseClicked() 函数将不会注册鼠标单击,这会使界面有时“错过”预期的点击。

或者, MouseAdapter.mousePressed() 事件可以检测所有点击,但在这种情况下,每次点击都会在释放鼠标按钮之前注册。 (对于某些用户来说,这可能是意外行为。)

在 JButton ActionListener.actionPerformed() 事件中,即使您按下鼠标按钮,移动指针,然后释放鼠标按钮,鼠标单击也会被注册。 (只要指针不离开 JButton 边界就是如此)。 我想知道如何为 JLabel 上的单击和/或双击实现这种更强大的点击检测行为?

谢谢你。

您描述的“稳健点击”功能可以使用自定义 MouseAdapter 类来实现。 下面粘贴的是我编写的 MouseLiberalAdapter 类的副本,用于在 JLabel(或其他摆动组件)中正确捕获“移动”鼠标单击事件。

使用 MouseLiberalAdapter 类的说明:

  • 将类复制到您的项目中。
  • 扩展 MouseLiberalAdapter 类,并覆盖您希望捕获的鼠标事件。
  • mouseLiberalClick() 和 mouseLiberalDoubleClick() 事件提供您描述的功能。 这些将检测鼠标点击,即使鼠标在点击过程的“鼠标按下”和“鼠标释放”部分之间移动。
  • 如果您还不熟悉如何捕获摆动事件,那么您可能还希望查找有关如何使用标准 Java“MouseAdapter”类的示例。 MouseLiberalAdapter 类的使用方式与 MouseAdapter 类类似。
  • 另请参阅:MouseLiberalAdapter 类 javadoc 注释。

用法示例:

    JLabel labelSingleClick = new JLabel("Single click me.");
    JLabel labelDoubleClick = new JLabel("Double click me.");
    labelSingleClick.addMouseListener(new MouseLiberalAdapter() {
        @Override
        public void mouseLiberalClick(MouseEvent e) {
            JOptionPane.showMessageDialog(null, "Single click detected.");
        }
    });
    labelDoubleClick.addMouseListener(new MouseLiberalAdapter() {
        @Override
        public void mouseLiberalDoubleClick(MouseEvent e) {
            JOptionPane.showMessageDialog(null, "Double click detected.");
        }
    });


MouseLiberalAdapter 类:

    package com.project.utilities;

    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseWheelEvent;

    /**
     * MouseLiberalAdapter.
     *
     * This class extends the MouseAdapter class, to include two additional events. The added events are
     * the mouseLiberalClick() and the mouseLiberalDoubleClick(). By default, the mouseClick() event in
     * the MouseAdapter has a limitation. The mouseClick() event cannot register a click if the mouse
     * pointer moves even slightly, between the mouse press and mouse release events. By contrast, the
     * mouseLiberalClick() will register a "liberal mouse click" even if the mouse moves (by any amount)
     * during the click event, as long as the mouse pointer does not leave the boundaries of the
     * component which is generating the mouse events. (This "liberal mouse click" behavior duplicates
     * the "actionPerformed()" functionality that exists in the JButton class.)
     *
     * Note: This class is frequently used to detect clicks in a JLabel, but it can be used in any swing
     * component that will accept a MouseAdapter.
     *
     * Using this class is similar to using the MouseAdapter class. (See also: The MouseAdapter
     * javadocs.) To use this class, you would extend this class and override any (non-final) event
     * methods that are of interest.
     *
     * The original MouseAdapter functions have been marked as final, and cannot be overridden. However,
     * the class still provides all the original functions (with slightly modified function names). The
     * two new functions are also provided: mouseLiberalClick() and mouseLiberalDoubleClick(). A usage
     * example is shown below.
     *
     * Usage example:
     * <pre> {@code
     * JLabel labelSingleClick = new JLabel("Single click me.");
     * JLabel labelDoubleClick = new JLabel("Double click me.");
     * labelSingleClick.addMouseListener(new MouseLiberalAdapter() {
     * @Override
     * public void mouseLiberalClick(MouseEvent e) {
     * JOptionPane.showMessageDialog(null, "Single click detected.");
     * }
     * });
     * labelDoubleClick.addMouseListener(new MouseLiberalAdapter() {
     * @Override
     * public void mouseLiberalDoubleClick(MouseEvent e) {
     * JOptionPane.showMessageDialog(null, "Double click detected.");
     * }
     * });
     * }</pre>
     */
    public abstract class MouseLiberalAdapter extends MouseAdapter {

        /**
         * isComponentPressedDown, This indicates whether or not the component is currently
         * (conceptually) "pressed down". To understand the meaning of "pressed down", consider the
         * behavior of a JButton. When you press the mouse inside a button, the button redraws itself to
         * indicate a "press down" state. If you release the mouse while inside the button, a button
         * click will be registered, and the button will switch to a "not press down" state. The button
         * can also become "not pressed down" if the mouse pointer leaves the boundaries of the button
         * without first releasing the mouse.
         */
        private boolean isComponentPressedDown = false;
        /**
         * lastUnusedLiberalSingleClickTimeStamp, This stores a timestamp for the mouse release of the
         * last unused liberal single click. If a single click is "used" as part of a double click, then
         * it's timestamp will no longer be stored here. If there is no liberal single click which fits
         * the above description, then this will contain the value zero.
         */
        private long lastUnusedLiberalSingleClickTimeStamp = 0;
        /**
         * slowestDoubleClickMilliseconds, This constant indicates the maximum time window in which a
         * liberal double click can occur. More specifically, this indicates the maximum time, in
         * milliseconds, between liberal single click mouse releases, that will be considered to
         * constitute a liberal double click.
         */
        private final int slowestDoubleClickMilliseconds = 1800;

        /**
         * mouseLiberalClick, Override this function to catch liberal single click events.
         *
         * Note: The mouse event which is passed to this function will be the mouse event that was
         * received from the "mouseRelease" event at the end of the liberal single click.
         */
        public void mouseLiberalClick(MouseEvent e) {
        }

        /**
         * mouseLiberalDoubleClick, Override this function to catch liberal double click events.
         *
         * Note: The mouse event which is passed to this function will be the mouse event that was
         * received from the "mouseRelease" event at the end of the liberal double click.
         */
        public void mouseLiberalDoubleClick(MouseEvent e) {
        }

        /**
         * mouseClick, Override this function to catch standard mouse click events.
         */
        public void mouseClick(MouseEvent e) {
        }

        /**
         * mousePress, Override this function to catch standard mouse press events.
         */
        public void mousePress(MouseEvent e) {
        }

        /**
         * mouseRelease, Override this function to catch standard mouse release events.
         */
        public void mouseRelease(MouseEvent e) {
        }

        /**
         * mouseEnter, Override this function to catch standard mouse enter events.
         */
        public void mouseEnter(MouseEvent e) {
        }

        /**
         * mouseExit, Override this function to catch standard mouse exit events.
         */
        public void mouseExit(MouseEvent e) {
        }

        /**
         * mouseWheelMove, Override this function to catch standard mouse wheel move events.
         */
        public void mouseWheelMove(MouseWheelEvent e) {
        }

        /**
         * mouseDrag, Override this function to catch standard mouse drag events.
         */
        public void mouseDrag(MouseEvent e) {
        }

        /**
         * mouseMove, Override this function to catch standard mouse move events.
         */
        public void mouseMove(MouseEvent e) {
        }

        /**
         * mousePressed, Final function. Handles mouse pressed events.
         */
        @Override
        final public void mousePressed(MouseEvent e) {
            // Record that the component is "pressed down".
            isComponentPressedDown = true;
            // Call the mouse press event.
            mousePress(e);
        }

        /**
         * mouseReleased, Final function. Handles mouse released events. This function also detects
         * liberal single clicks, and liberal double clicks.
         */
        @Override
        final public void mouseReleased(MouseEvent e) {
            // Check to see if this mouse release completes a liberal single click.
            if (isComponentPressedDown) {
                // A liberal single click has occurred.
                mouseLiberalClick(e);
                // Check to see if we had two liberal single clicks within the double click time window.
                long now = System.currentTimeMillis();
                long timeBetweenUnusedClicks = now - lastUnusedLiberalSingleClickTimeStamp;
                if (timeBetweenUnusedClicks <= slowestDoubleClickMilliseconds) {
                    // A liberal double click has occurred.
                    mouseLiberalDoubleClick(e);
                    // Mark the single click timestamp as "used" by this double click.
                    lastUnusedLiberalSingleClickTimeStamp = 0;
                } else {
                    // Save the single click timestamp as part of a possible future double click.
                    lastUnusedLiberalSingleClickTimeStamp = System.currentTimeMillis();
                }
            }
            // Record the mouse release.
            isComponentPressedDown = false;
            // Call the mouse release event.
            mouseRelease(e);
        }

        /**
         * mouseEntered, Final function. Handles mouse entered events.
         */
        @Override
        final public void mouseEntered(MouseEvent e) {
            // Call the mouse enter event.
            mouseEnter(e);
        }

        /**
         * mouseExited, Final function. Handles mouse exited events.
         */
        @Override
        final public void mouseExited(MouseEvent e) {
            // Since the mouse left the component, the component is no longer considered "press down".
            isComponentPressedDown = false;
            // Call the mouse exit event.
            mouseExit(e);
        }

        /**
         * mouseClicked, Final function. Handles mouse clicked events.
         */
        @Override
        final public void mouseClicked(MouseEvent e) {
            // Call the mouse click event.
            mouseClick(e);
        }

        /**
         * mouseWheelMoved, Final function. Handles mouse wheel moved events.
         */
        @Override
        final public void mouseWheelMoved(MouseWheelEvent e) {
            // Call the mouse wheel move event.
            mouseWheelMove(e);
        }

        /**
         * mouseDragged, Final function. Handles mouse dragged events.
         */
        @Override
        final public void mouseDragged(MouseEvent e) {
            // Call the mouse drag event.
            mouseDrag(e);
        }

        /**
         * mouseMoved, Final function. Handles mouse moved events.
         */
        @Override
        final public void mouseMoved(MouseEvent e) {
            // Call the mouse move event.
            mouseMove(e);
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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