如何在Java Swing中检测用户是否使用Trackpad而不是鼠标?

20

我有一个使用'可平移'的JComponent显示大数据的Java Swing应用程序。当用户移动鼠标滚轮时,我监听这些事件,并从滚动量更新JComponent的内容。

我想根据用户是

  • 使用传统鼠标
  • 使用现代Mac笔记本电脑上找到的触摸板。

根据不同的行为方式,我该如何检测用户使用鼠标滚轮还是触摸板生成滚动事件?我依赖于java 1.6 swing,所以无法转到javaFX。

问题背后的故事:我只想在用户使用鼠标滚轮时添加一个酷炫的惯性感。但是,在MacOSX上,触摸板具有自己内置的惯性效果。因此,我想决定是否应该生成惯性运动。

4个回答

5

Java Swing是一种旧的技术,它支持传统的鼠标滚轮旋转事件。

当您使用旧式滚轮鼠标或轨迹板时,它会读取硬件滚轮的旋转。

当您使用现代激光鼠标时,鼠标移动将被转换为旋转运动。

当您使用像现代Mac笔记本电脑中那样的触摸板时,滚动手势将被转换为旋转运动,单击和双击将被视为左右键(基于操作系统鼠标设置)。

您可以使用库详细检查输入设备,如果您的鼠标或轨迹板通过USB连接到计算机,则可以尝试使用J-USB library

至于内部硬件,您首先必须确定操作系统的类型,然后可以获取有关Java中系统和硬件的信息

最后,如果您的应用程序与用户交互,建议询问用户他们正在使用哪种类型的鼠标,并将其存储在配置文件或其他地方。


1
好的,这正是我担心的。所以明确地说,你告诉我用 Swing 没办法知道对吗? - Jean-Yves
@Jean-Yves 是的,Swing无法告诉您那个信息。 - Khaled.K
1
@Jean-Yves 我知道已经过了一段时间,但我已经在答案中添加了一个最终子句。 - Khaled.K

1

0

鼠标滚轮监听器API

虽然MouseWheelListener只有一个方法,但它有相应的适配器类-MouseAdapter。这种能力使得应用程序只需为组件管理来自鼠标指针的所有类型事件拥有一个适配器类实例。

mouseWheelMoved(MouseWheelEvent)    //Called when the mouse wheel is rotated.

以下代码片段与鼠标滚轮事件处理相关:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

import javax.swing.*;

public class MouseWheelEventDemo extends JPanel
        implements MouseWheelListener {
    JTextArea textArea;
    JScrollPane scrollPane;
    static final String NEWLINE = System.getProperty("line.separator");

    public static void main(String[] args) {
        /* Use an appropriate Look and Feel */
        try {
            //UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
            //UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
        } catch (UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        /* Turn off metal's use of bold fonts */
        UIManager.put("swing.boldMetal", Boolean.FALSE);

        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("MouseWheelEventDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        JComponent newContentPane = new MouseWheelEventDemo();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public MouseWheelEventDemo() {
        super(new BorderLayout());

        textArea = new JTextArea();
        textArea.setEditable(false);
        scrollPane = new JScrollPane(textArea);
        scrollPane.setVerticalScrollBarPolicy(
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setPreferredSize(new Dimension(400, 250));
        add(scrollPane, BorderLayout.CENTER);
        textArea.append("This text area displays information "
                + "about its mouse wheel events."
                + NEWLINE);

        //Register for mouse-wheel events on the text area.
        textArea.addMouseWheelListener(this);

        setPreferredSize(new Dimension(450, 350));
        setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
    }

    //Append to the text area and make sure the new text is visible.
    void eventOutput(String eventDescription, MouseWheelEvent e) {
        textArea.append(e.getComponent().getClass().getName()
        + ": "
                + eventDescription);
        textArea.setCaretPosition(textArea.getDocument().getLength());
    }

    public void mouseWheelMoved(MouseWheelEvent e) {
        String message;
        int notches = e.getWheelRotation();
        if (notches < 0) {
            message = "Mouse wheel moved UP "
                    + -notches + " notch(es)" + NEWLINE;
        } else {
            message = "Mouse wheel moved DOWN "         
                    + notches + " notch(es)" + NEWLINE;
        }
        if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
            message += "    Scroll type: WHEEL_UNIT_SCROLL" + NEWLINE;
            message += "    Scroll amount: " + e.getScrollAmount()
            + " unit increments per notch" + NEWLINE;
            message += "    Units to scroll: " + e.getUnitsToScroll()
            + " unit increments" + NEWLINE;
            message += "    Vertical unit increment: "
                    + scrollPane.getVerticalScrollBar().getUnitIncrement(1)
                    + " pixels" + NEWLINE;
        } else { //scroll type == MouseWheelEvent.WHEEL_BLOCK_SCROLL
            message += "    Scroll type: WHEEL_BLOCK_SCROLL" + NEWLINE;
            message += "    Vertical block increment: "
                    + scrollPane.getVerticalScrollBar().getBlockIncrement(1)
                    + " pixels" + NEWLINE;
        }
        eventOutput(message, e);
    }
}

对于使用鼠标滚轮的单位增量的系统,MouseWheelEventDemo 的输出可能如下所示:

javax.swing.JTextArea: Mouse wheel moved UP 1 notch(es)
    Scroll type: WHEEL_UNIT_SCROLL
    Scroll amount: 3 unit increments per notch
    Units to scroll: -3 unit increments
    Vertical unit increment: 16 pixels

完整的解释请参见 - https://docs.oracle.com/javase/tutorial/uiswing/events/mousewheellistener.html - Saket Mittal
谢谢!但是,这不是问题。我只是想知道是否有一种方法可以知道这些事件是由鼠标还是触摸板触发的。 - Jean-Yves

0

尝试这段代码

  1. MetaDown 用于右键单击

  2. AltDown 用于鼠标滚轮

.

public class Exp extends JFrame {

    private String string;
    private JLabel l;

    public Exp() {
        super("Title");    
        l = new JLabel("Status");
        add(l, BorderLayout.SOUTH);
        addMouseListener(new MouseClass());         
    }

    private class MouseClass extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {                
            string = String.format("Clicked %d Times", e.getClickCount());              
            if(e.isMetaDown())
                string += " With Right Mouse Button";
            else if(e.isAltDown())
                string += " With Centre Mouse Button";
            else
                string += " With Left Mouse Button";                
            l.setText(string);
        }
    }   
}

还可以尝试这个:

通过 SwingUtilities 中的以下三种方法,您可以确定哪个鼠标按钮被按下:

isLeftMouseButton

isMiddleMouseButton

isRightMouseButton


更多信息请参见:http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingUtilities.html#isMiddleMouseButton%28java.awt.event.MouseEvent%29 - Programmer
谢谢!但实际上,我想知道鼠标滚轮事件是由触摸板还是实际的鼠标生成的。 - Jean-Yves

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接