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

时间:2016-05-10 21:44:27

标签: java swing click jbutton jlabel

我想在JLabel中检测鼠标点击事件,其方式类似于可用于JButton的“ActionListener.actionPerformed()”功能。
我该怎么做?其他细节如下。

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

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

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

谢谢。

1 个答案:

答案 0 :(得分:1)

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

使用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);
        }
    }