java - 用Java模拟触摸滚动

标签 java touch javafx desktop-application

我正在寻找一种在 Java 中创建具有触摸滚动支持的触摸应用程序(不适用于移动设备)的方法。 到目前为止我一直在搜索,我正在研究如何做到这一点 - 我发现的是 MT4J ( http://www.mt4j.org/ ),但它似乎不支持这一点(如果我错了,请纠正我)。 所以我的问题是,如何模拟水平触摸/滑动的滚动事件?

感谢您的帮助! 亲切的问候, 亚历克斯

最佳答案

这通过子类化 JScrollPane 实现了触摸和拖动滚动条。

因为触摸和拖动本身是不够的,所以我添加了动力 这样当释放鼠标按钮时它会“抛出”滚动。

卷轴末端没有“弹跳”,因为我承受不起 对“bounce”所有者提起诉讼。

它没有完全封装,因为尽管如果 View 是一个jlist, View 上可能有需要的组件 如果当时正在拖动面板,则可以修改他们的响应。 还有一些组件,例如JRadioButton、JCheckBox等消耗 鼠标单击而不将它们传递到容器,因此您将 需要给它们添加TouchScroll的MouseListener和MouseMotionListener。

import java.awt.Component;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JScrollBar;
import javax.swing.JScrollPane;

public class TouchScroll extends JScrollPane implements MouseListener,   MouseMotionListener {
private JScrollBar vbar = this.getVerticalScrollBar();

public TouchScroll(Component view){ // 1-arity CONSTRUCTOR
    super(view);
    view.addMouseListener(this);
    view.addMouseMotionListener(this);
}
public TouchScroll() {  super();    }   // 0-arity CONSTRUCTOR

public void setViewportView(Component view) {
    super.setViewportView(view);
    view.addMouseListener(this);
    view.addMouseMotionListener(this);
}

private static boolean wasdragged = false;  // other MouseListeners may need to know this ...
public boolean wasDragged() {       return wasdragged;  }   // ... this gives them safe access

static int lastY = 0, distY = 0;
double momentum = 0;    // not really physical momentum but it will be used to 'throw' the scroll when the mouse button is released
static boolean lbdown = false;
@Override
public void mouseDragged(MouseEvent e) {
    wasdragged = true;      
    distY = 0;
    int currentY = e.getYOnScreen();
    if(lbdown) {
        distY =  lastY - currentY;
        vbar.setValue(distY + vbar.getValue());
        if(Math.abs(distY) > 1)
            momentum = distY + distY;   // magnify and log the momentum for later use
    }
    lastY = currentY;
}

@Override
public void mousePressed(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
        lastY = e.getYOnScreen();
        lbdown = true;
    }
}

@Override
public void mouseReleased(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1)
        lbdown = false;
    if(wasdragged)
        wasdragged = false;

    if(Math.abs(momentum) <= 4.0)   // then assume that the mouse wasn't moving (much) when the button was released
        return;
    // otherwise 'throw' the scroll
    int max = vbar.getMaximum();
    int count;
    double brakingforce = 1.04;     // set an initial braking force
    for(count = 1000; count > 0; count--){  // don't allow it to accidentally go on forever
        momentum = momentum / brakingforce; // apply the brake
        if(Math.abs(momentum) < 1.5)
            brakingforce = 1.02;    // ease off the brake towards the end (gives a slight overrun ala iOS)
        if(Math.abs(momentum) < 1.0)    // bring it to a halt
            break;
        int val = vbar.getValue();
        if(val < 0 || val > max)    // prevent overrun
            break;
        vbar.setValue((int) momentum + val);    // increment the scroll bar
        try {
            Thread.sleep(10);       // slow the loop down so the user can see the scroll
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }
}

public void mouseMoved(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}

}

这是一个“简单的”示例,说明如何应用它:

panel = new JPanel();
jlist = new JList(list);
scroller = new TouchScroll(jlist);
panel.add(scroller);

任何响应鼠标释放的组件可能需要执行如下操作:

public void mouseReleased(MouseEvent e) {   
    if(scroller.wasDragged())
        return;
    actionENTER();
}

最后,如前所述,消耗鼠标事件的组件需要 像这样通知滚动条:

JCheckBox checkbox = new JCheckBox(text);
checkbox.addMouseMotionListener(scroller);
checkbox.addMouseListener(scroller);

关于java - 用Java模拟触摸滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16470605/

相关文章:

javascript - 在使用触摸和鼠标的设备(例如 Surface)上收听 mousedown 和 touchstart

windows - 触摸屏隐藏光标

JavaFX 检查 Node 属性是否正在被监听

java - 如何将 TreeTableView 列中的文本居中?

java - 为什么通过扩展类来测试类被认为是一种不好的做法?

java - Rust 在 Java 中函数式接口(interface)和方法引用的等价性是什么

java - 方法调用与可变参数运算符不明确

java - 如何在 Android 中为 facebook 设置 SessionDefaultAudience

linux - 如何使用touch命令在指定目录创建文件

java - 如何在java FXML中使用按下的按键?我想使用快捷键来执行按钮操作