Rya*_*van 2 javafx virtual-keyboard java-15
我在打开的 jdk 8 中使用 javafx 虚拟键盘。有时我必须访问虚拟键盘,以防止它在某些文本字段获得焦点时显示。操作员必须扫描多个条形码的屏幕就是一个例子。这个虚拟键盘很碍事。使用 open jdk 8,我们可以像这样禁用虚拟键盘:
FXVK.detach(); //导入“com.sun.javafx.scene.control.skin.FXVK”后
我们现在正在升级到 open jdk 15 并使用 gradle 构建我们的 UI。“com.sun.javafx.scene.control.skin.FXVK”不再可以通过带有 gradle 的模块化项目进行访问。我不相信使用不同的虚拟键盘是一种选择,所以任何人都可以解释如何在 java 8 之后访问这个 FXVK 类吗?
有没有办法使用 --add-exports 或 --patch-module 与 JAR 来修补 JavaFX 以访问内部类?
下面是显示此问题的示例项目的代码。
这是 JavaFX 应用程序类,它仅显示一个文本字段并显示我可以与 java 8 一起使用以不显示虚拟键盘的代码。
package com.test.sampleapp.application;
////not accessible in java 15
//import com.sun.javafx.scene.control.skin.FXVK;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application{
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception
{
Label label = new Label("Text field below");
TextField textField = new TextField();
VBox vbox = new VBox(label);
vbox.getChildren().add(textField);
Scene scene = new Scene(vbox);
primaryStage.setScene(scene);
primaryStage.show();
textField.focusedProperty().addListener(new ChangeListener<Boolean>()
{
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
Boolean newValue)
{
// If focused
if (newValue)
{
//Need this to disable the virtual keyboard when using a textfield with scanning
//FXVK.detach();
}
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
然后我需要添加一个包装类来显示虚拟键盘。请注意,大多数时候,当文本字段获得焦点时,我确实会使用虚拟键盘,但有时我需要能够在某些情况下以编程方式禁用它。
包装类:
package com.test.sampleapp.application;
import java.lang.reflect.Method;
public class AppWrapper
{
public static void main(String[] args) throws Exception
{
Class<?> app = Class.forName("com.test.sampleapp.application.Main");
Method main = app.getDeclaredMethod("main", String[].class);
System.setProperty("com.sun.javafx.isEmbedded", "true");
System.setProperty("com.sun.javafx.touch", "true");
System.setProperty("com.sun.javafx.virtualKeyboard", "javafx");
Object[] arguments = new Object[]{args};
main.invoke(null, arguments);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您需要其他任何内容(例如 build.gradle 文件),请告诉我,但这主要只是使用 java 9 或更高版本的问题。
该类FXVK仍然存在于同一个包中,因此唯一的问题是模块未导出其包javafx.controls。如果必须使用这个内部类,那么您可以--add-exports在编译时和运行时传递适当的 JVM 参数。
这是一个简单的应用程序,它调用FXVK#detach():
// Will fail at compile-time if the '--add-exports` argument is not
// passed to 'javac'
import com.sun.javafx.scene.control.skin.FXVK;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
var root = new StackPane(new Label("Hello, World!"));
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.show();
// Will fail at run-time if the '--add-exports' argument is
// not passed to 'java'
FXVK.detach();
}
}
Run Code Online (Sandbox Code Playgroud)
假设您将该Main.java文件放在工作目录中,您可以使用以下命令编译它:
javac -p <path-to-fx> --add-modules javafx.controls --add-exports javafx.controls/com.sun.javafx.scene.control.skin=ALL-UNNAMED Main.java
Run Code Online (Sandbox Code Playgroud)
并运行它:
java -p <path-to-fx> --add-modules javafx.controls --add-exports javafx.controls/com.sun.javafx.scene.control.skin=ALL-UNNAMED Main
Run Code Online (Sandbox Code Playgroud)
如果您的代码是模块化的,那么您可以删除--add-modules,并且必须更改ALL-UNNAMED为模块的名称。--module另外,请确保通过(或)启动您的应用程序-m。注意-p上面是 的简写--module-path。
如果您使用构建工具(例如 Maven、Gradle 等),那么您必须查找如何为该工具设置这些 JVM 参数。您还必须考虑如何部署应用程序。例如,如果您使用jpackagethen 您可以使用其--java-options参数来设置--add-exports应用程序启动时的选项。
您可能还需要告诉 IDE 您正在授予自己访问内部包的权限。否则,您的 IDE 可能会因为您尝试使用无法访问的类型而对您大喊大叫。
| 归档时间: |
|
| 查看次数: |
299 次 |
| 最近记录: |