Java 如何通过鼠标移动检测JLabel中的单击?(像吉布顿)?

Java 如何通过鼠标移动检测JLabel中的单击?(像吉布顿)?,java,swing,click,jbutton,jlabel,Java,Swing,Click,Jbutton,Jlabel,我想在JLabel中检测鼠标单击事件,其方式类似于JButton可用的“ActionListener.actionPerformed()”功能我该怎么做?其他细节如下 MouseAdapter类的功能与JButton可用的ActionListener功能不同。如果鼠标指针在mousePressed和MouseRelease事件之间移动(甚至轻微移动),则mouseDapter.mouseClicked()函数将不会注册鼠标单击,这使得界面有时会“错过”预期的单击 或者,MouseAdapter.

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

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

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

在JButton ActionListener.actionPerformed()事件中,即使您按下鼠标按钮,四处移动指针,然后释放鼠标按钮,也会注册鼠标单击。(只要指针不离开JButton边界,这是正确的)。我想知道如何为一次单击和/或双击JLabel实现这种更健壮的单击检测行为

谢谢。

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

使用MouseLiberAlaAdapter类的说明:

  • 将类复制到项目中
  • 扩展MouseLiberAlaAdapter类,并覆盖希望捕获的鼠标事件
  • mouseLiberalClick()和mouseLiberalDoubleClick()事件提供了您描述的功能。这些将检测鼠标点击,即使鼠标在点击过程的“按下鼠标”和“释放鼠标”之间移动
  • 如果您还不熟悉如何捕获swing事件,那么您可能还希望查看如何使用标准Java“MouseAdapter”类的示例。MouseLiberAlaAdapter类的使用方式与MouseAdapter类类似
  • 另请参见:MouseLiberAlaAdapter类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.");
        }
    });

MouseLiberAlaAdapter类:

package com.project.utilities;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.event.mouseweelEvent;
/**
*鼠标适配器。
*
*此类扩展了MouseAdapter类,以包含两个附加事件。添加的事件是
*mouseLiberalClick()和mouseLiberalDoubleClick()。默认情况下,中的mouseClick()事件
*MouseAdapter有一个限制。如果鼠标单击,则mouseClick()事件无法注册单击
*在鼠标按下和鼠标释放事件之间,指针甚至轻微移动。相比之下
*mouseLiberalClick()将注册“自由鼠标点击”,即使鼠标移动(任意数量)
*在单击事件期间,只要鼠标指针不离开
*正在生成鼠标事件的组件。(此“自由鼠标单击”行为重复
*JButton类中存在的“actionPerformed()”功能。)
*
*注意:此类经常用于检测JLabel中的单击,但它可以用于任何swing
*将接受MouseAdapter的组件。
*
*使用此类类似于使用MouseAdapter类。(另请参见:MouseAdapter
*要使用这个类,您需要扩展这个类并覆盖任何(非最终)事件
*感兴趣的方法。
*
*原始MouseAdapter函数已标记为final,无法重写。然而,
*该类仍然提供所有原始函数(函数名略有修改)。这个
*还提供了两个新函数:mouseLiberalClick()和mouseLiberalDoubleClick()。用法
*示例如下所示。
*
*用法示例:
*{@code
*JLabel labelSingleClick=新的JLabel(“单击我”);
*JLabel labelDoubleClick=新建JLabel(“双击我”);
*labelSingleClick.addMouseListener(新的mouseliberadapter(){
*@覆盖
*公共无效mouseLiberalClick(MouseEvent e){
*showMessageDialog(null,“检测到单次单击”);
* }
* });
*labelDoubleClick.addMouseListener(新的MouseLiberAlaAdapter(){
*@覆盖
*公共无效mouseLiberalDoubleClick(MouseEvent e){
*showMessageDialog(null,“双击检测到”);
* }
* });
* }
*/
公共抽象类MouseLiberAlaAdapter扩展了MouseAdapter{
/**
*isComponentPressedDown,这表示组件当前是否处于可用状态
*(概念上)“按下”。要理解“按下”的含义,请考虑
*JButton的行为。当您在按钮内按鼠标时,按钮会将自身重新绘制为
*指示“按下”状态。如果在按钮内释放鼠标,则按钮
*点击将被注册,按钮将切换到“不按下”状态。按钮
*如果鼠标指针离开按钮的边界,也会变成“未按下”
*没有先释放鼠标。
*/
私有布尔值isComponentPressedDown=false;
/**
*lastUnusedLiberalSingleClickTimeStamp,用于存储鼠标释放的时间戳
*上次未使用的单击。如果单击作为双击的一部分“使用”,则
*它的时间戳将不再存储在这里。如果没有合适的单键点击
*ab
    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);
        }
    }