Java Jinput:重新扫描/重新加载控制器 [英] Java Jinput: rescan / reload controllers

查看:168
本文介绍了Java Jinput:重新扫描/重新加载控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用java jinput 库从joypad读取数据,我无法重新加载控制器这将加载它们:

  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 [] {});
}

这很好,但如果我断开我的控制器,调用这将找到它



我试图在第一次查找之前将睡眠,这些结果:


  1. 当第一次调用此方法时(不是程序开始时),控制器会被检测。

  2. <
  3. 第一次呼叫也会写入以下警告:

  4. 即使在第一次呼叫时,

  5. $ b

    警告从这个控制器连接(工作),然后断开连接(它仍然会找到它并重新连接,点3:(在列表中格式不正确)

     警告:找到未知的Windows版本:Windows 8 
    正在尝试使用默认的Windows插件。
    正在加载:net.java.games.input.DirectAndRawInputEnvironmentPlugin

    并且在Win 7上也有同样的问题。我也用鼠标试过这个,结果一样。



    我如何重新加载控制器的第二,第三, ?

    解决方案

    我遇到了同样的问题。原因是实际的硬件扫描对每个DefaultControllerEnvironment对象只发生一次。因为唯一可访问的实例化是单例,所以它从不进行另一次扫描。



    强制硬件扫描的一个简单方法是创建一个新对象,构造函数是公共的。



    重新扫描

     <$> c $ c> private static ControllerEnvironment createDefaultEnvironment()throws ReflectiveOperationException {

    //查找构造函数(类是包私有的,所以我们不能直接访问它)
    构造函数< ControllerEnvironment> constructor =(Constructor< ControllerEnvironment>)
    Class.forName(net.java.games.input.DefaultControllerEnvironment)。getDeclaredConstructors()[0];

    //构造函数是包私有的,所以我们必须停用访问控制检查
    constructor.setAccessible(true);

    //使用默认构造函数创建对象
    return constructor.newInstance();
    }

    使用

      //注意创建一个新的环境是相当昂贵的
    Controller [] controllers = createDefaultEnvironment()。getControllers();

    删除Windows 8警告

      / ** 
    *通过定义一个工作插件修复Windows 8警告
    * /
    static {

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

    //禁用默认插件查找
    System.setProperty(jinput.useDefaultPlugin,false);

    //设置为与Windows 7相同(针对Windows 8和8.1测试)
    System.setProperty(net.java.games.input.plugins,net.java.games.input .DirectAndRawInputEnvironmentPlugin);

    }
    return null;
    }
    });

    }


    I am using java jinput library to read data from joypad, and I have trouble reloading Controllers, I use this to load them:

    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[]{});
    }
    

    This works fine, but if I disconnect my controller, calling this will find it again, and vice versa (connecting it after the first check will not find it at all).

    I have tried to put sleep before the fist lookup, with these results:

    1. Controllers are acctually scanned when this method is called first time (not at start of the program)
    2. When called again, this always returns same controllers as it returned for the first time.
    3. First call will also write warning bellow
    4. Even when controller is connected (and works), then disconnected (it will still find it though) and reconnected, it will not work

    Warning from point 3: (didn't format well in the list)

    WARNING: Found unknown Windows version: Windows 8
    Attempting to use default windows plug-in.
    Loading: net.java.games.input.DirectAndRawInputEnvironmentPlugin
    

    I am using Win 8, and had same problem on Win 7. I had also tried this with mouse, same results.

    How can I acctually reload controllers for the 2nd, 3rd, and so on time?

    解决方案

    I encountered the same problem. The reason is that the actual hardware scan happens only once for each DefaultControllerEnvironment object. Since the only accessible instantiation is a singleton, it never does another scan.

    A simple way to force a hardware scan is to create a new object, but neither the class nor the constructor are public. You can however work around this limitation by calling the constructor via reflection.

    Rescan

    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();
    }
    

    Usage

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

    Remove Windows 8 Warnings

    /**
     * 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;
            }
        });
    
    }
    

    这篇关于Java Jinput:重新扫描/重新加载控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆