Java Jinput:重新扫描/重新加载控制器

kaj*_*acx 3 java controller reload jinput

我正在使用java jinput库从joypad读取数据,我无法重新加载Controllers,我使用它来加载它们:

public Controller[] findStickControllers() {
    ControllerEnvironment ce =
            ControllerEnvironment.getDefaultEnvironment();

    Controller[] cs = ce.getControllers();

    System.out.println(cs.length); //test

    ArrayList<Controller> sel = new ArrayList<>();

    for (Controller c: cs) {
        if(c.getType() == Type.STICK) {
            sel.add(c);
        }
    }

    return sel.toArray(new Controller[]{});
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但如果我断开我的控制器,调用它将再次找到它,反之亦然(在第一次检查后连接它将根本找不到它).

我试图在第一次查找前放置睡眠,结果如下:

  1. 首次调用此方法时(而不是程序启动时)会对控制器进行实际扫描
  2. 再次调用时,它总是返回与第一次返回的控制器相同的控制器.
  3. 第一次打电话也会写下警告
  4. 即使控制器连接(并且工作),然后断开连接(它仍会找到它)并重新连接,它将无法工作

点3的警告:(列表格式不正确)

WARNING: Found unknown Windows version: Windows 8
Attempting to use default windows plug-in.
Loading: net.java.games.input.DirectAndRawInputEnvironmentPlugin
Run Code Online (Sandbox Code Playgroud)

我正在使用Win 8,并在Win 7上遇到同样的问题.我也用鼠标试过这个,结果相同.

如何在第2次,第3次等时间内重新加载控制器?

Flo*_*ner 7

我遇到了同样的问题.原因是每个DefaultControllerEnvironment对象只发生一次实际的硬件扫描.由于唯一可访问的实例化是单例,因此它永远不会进行另一次扫描.

强制硬件扫描的一种简单方法是创建一个新对象,但类和构造函数都不是公共的.但是,您可以通过反射调用构造函数来解决此限制.

重新扫描

private static ControllerEnvironment createDefaultEnvironment() throws ReflectiveOperationException {

    // Find constructor (class is package private, so we can't access it directly)
    Constructor<ControllerEnvironment> constructor = (Constructor<ControllerEnvironment>)
        Class.forName("net.java.games.input.DefaultControllerEnvironment").getDeclaredConstructors()[0];

    // Constructor is package private, so we have to deactivate access control checks
    constructor.setAccessible(true);

    // Create object with default constructor
    return constructor.newInstance();
}
Run Code Online (Sandbox Code Playgroud)

用法

// Be aware that creating a new environment is fairly expensive
Controller[] controllers = createDefaultEnvironment().getControllers();
Run Code Online (Sandbox Code Playgroud)

删除Windows 8警告

/**
 * Fix windows 8 warnings by defining a working plugin
 */
static {

    AccessController.doPrivileged(new PrivilegedAction<Object>() {
        public Object run() {
            String os = System.getProperty("os.name", "").trim();
            if (os.startsWith("Windows 8")) {  // 8, 8.1 etc.

                // disable default plugin lookup
                System.setProperty("jinput.useDefaultPlugin", "false");

                // set to same as windows 7 (tested for windows 8 and 8.1)
                System.setProperty("net.java.games.input.plugins", "net.java.games.input.DirectAndRawInputEnvironmentPlugin");

            }
            return null;
        }
    });

}
Run Code Online (Sandbox Code Playgroud)