如何以编程方式禁用覆盖滚动条 (Ubuntu Java)
How to disable overlay scrollbars programmatically (Ubuntu Java)
尝试移植到 Ubuntu
我的 SWT
应用程序在 Windows
中运行良好,我遇到了 overlay scrollbars
的问题。当我 运行 来自 Eclipse
下的应用程序时,一切正常,滚动条看起来和行为正常。但是当我将应用程序打包成 JAR
并执行此 JAR
时,应用程序中的滚动条将变为 "overlay scrollbars" 并且看起来像橙色细条,我需要处理的滚动条事件应该有一些奇怪的字段值,所以我的应用程序完全忽略它们。这对我来说是不可接受的,对于我的应用程序来说,以特殊的、非标准的方式处理滚动条很重要,所以我需要滚动条的正常外观和来自它们的正常事件。
通过将 export LIBOVERLAY_SCROLLBAR=0
添加到 ~/.profile
可以轻松解决此问题,但我不想强迫最终用户进行自定义系统设置以 运行我的应用程序,我希望他们能够 运行 只需单击 JAR,无需任何特殊努力。
我是 Linux 的编程新手,我不知道如何以编程方式设置环境。放置
System.setProperty("LIBOVERLAY_SCROLLBAR", "0");
在我的代码开头没有效果,也没有
new ProcessBuilder("export LIBOVERLAY_SCROLLBAR=0").start();
如何从我的代码中禁用此 "overlay scrollbars"?
P.S。任何其他语言的解决方案也可能是一个线索
更改当前进程(您的 java 程序)的环境变量很困难,而且可能并不总是有效。不过,您可以做的是使用您的 jar 分发 shell 脚本,Linux 上的人可以使用它来启动您的应用程序。这样的事情应该可以解决问题:
#!/bin/sh
export LIBOVERLAY_SCROLLBAR=0
java -jar yourjar.jar
存在为当前 运行ning VM 设置环境变量的方法,例如:
private static void setEnv(Map<String, String> newEnv) throws Exception {
Map<String, String> env = System.getenv();
Class<?> cl = env.getClass();
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
@SuppressWarnings("unchecked")
Map<String, String> envMap = (Map<String, String>) field.get(env);
envMap.putAll(newEnv);
}
(思路取自How do I set environment variables from Java?的答案)
但在我的情况下,我需要环境变量来影响在 VM 外部执行的库,因此此方法无法解决我的问题。
稍微思考后我意识到我想为JVM的父进程设置环境,所以我需要先设置所需的变量然后递归运行另一个JVM实例来执行我的app——那么变量会影响库,即使它们的代码是在 VM 之外执行的。
所以逻辑应该是这样的:
if (required vars are absent) {
start a process that {
set required vars;
run another instance of the JVM with the application inside;
}
exit;
}
// here the vars already set
do whatever we need in the proper environment
至于 Java,代码可能如下所示:
public class SecondVM {
public static void main(String[] args) {
if ( System.getenv("SWT_GTK3") == null
|| System.getenv("LIBOVERLAY_SCROLLBAR") == null )
{
URL classResource = SecondVM.class.getResource("SecondVM.class");
boolean fromJar = classResource.getProtocol().equals("rsrc");
String exePath = ClassLoader.getSystemClassLoader().getResource(".").getPath();
exePath = new File(exePath).getAbsolutePath().replaceFirst("\.$", "").replaceFirst("bin$", "");
if (!exePath.endsWith(System.getProperty("file.separator")))
exePath += System.getProperty("file.separator");
String[] script = {
"/bin/bash", "-c",
"export SWT_GTK3=0; "
+ "export LIBOVERLAY_SCROLLBAR=0; "
+ (fromJar? // TODO: Put the proper paths, packages and class names here
"java -jar " + exePath + "SecondVM.jar" : // if runs from jar
"java -cp ./bin/:../ExtLibs/swt_linux64/swt.jar " // if runs from under Eclipse or somewhat alike
+ "com.m_v.test.SecondVM")
};
try {
Process p = new ProcessBuilder(script).start();
// When jar is run from a bash script, it kills the second VM when exits.
// Let it has some time to take a breath
p.waitFor(12, TimeUnit.HOURS);
} catch (Exception e) { e.printStackTrace(); }
System.exit(0);
}
// Now the env vars are OK. We can use SWT with normal scrollbars
Display display = Display.getDefault();
// .... do watever we need
}
}
在 运行 从 shell 脚本中 ning jar 的情况下,我们必须等待子进程完成,然后才能退出原始进程,因此此解决方案会导致开销运行同时连接两个 JVM 实例。如果不需要从脚本中提供 运行 的可能性,则 p.waitFor(12, TimeUnit.HOURS);
可能会被 p.waitFor(12, TimeUnit.MILLISECONDS);
替换,或者可能根本被删除(我没有在没有它的情况下进行测试) ,所以我们可以有一个 JVM 实例,就像通常的 Java 程序一样。
带有 text
小部件和 scrollbar
的工作片段位于 http://ideone.com/eRjePQ
尝试移植到 Ubuntu
我的 SWT
应用程序在 Windows
中运行良好,我遇到了 overlay scrollbars
的问题。当我 运行 来自 Eclipse
下的应用程序时,一切正常,滚动条看起来和行为正常。但是当我将应用程序打包成 JAR
并执行此 JAR
时,应用程序中的滚动条将变为 "overlay scrollbars" 并且看起来像橙色细条,我需要处理的滚动条事件应该有一些奇怪的字段值,所以我的应用程序完全忽略它们。这对我来说是不可接受的,对于我的应用程序来说,以特殊的、非标准的方式处理滚动条很重要,所以我需要滚动条的正常外观和来自它们的正常事件。
通过将 export LIBOVERLAY_SCROLLBAR=0
添加到 ~/.profile
可以轻松解决此问题,但我不想强迫最终用户进行自定义系统设置以 运行我的应用程序,我希望他们能够 运行 只需单击 JAR,无需任何特殊努力。
我是 Linux 的编程新手,我不知道如何以编程方式设置环境。放置
System.setProperty("LIBOVERLAY_SCROLLBAR", "0");
在我的代码开头没有效果,也没有
new ProcessBuilder("export LIBOVERLAY_SCROLLBAR=0").start();
如何从我的代码中禁用此 "overlay scrollbars"?
P.S。任何其他语言的解决方案也可能是一个线索
更改当前进程(您的 java 程序)的环境变量很困难,而且可能并不总是有效。不过,您可以做的是使用您的 jar 分发 shell 脚本,Linux 上的人可以使用它来启动您的应用程序。这样的事情应该可以解决问题:
#!/bin/sh
export LIBOVERLAY_SCROLLBAR=0
java -jar yourjar.jar
存在为当前 运行ning VM 设置环境变量的方法,例如:
private static void setEnv(Map<String, String> newEnv) throws Exception {
Map<String, String> env = System.getenv();
Class<?> cl = env.getClass();
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
@SuppressWarnings("unchecked")
Map<String, String> envMap = (Map<String, String>) field.get(env);
envMap.putAll(newEnv);
}
(思路取自How do I set environment variables from Java?的答案)
但在我的情况下,我需要环境变量来影响在 VM 外部执行的库,因此此方法无法解决我的问题。
稍微思考后我意识到我想为JVM的父进程设置环境,所以我需要先设置所需的变量然后递归运行另一个JVM实例来执行我的app——那么变量会影响库,即使它们的代码是在 VM 之外执行的。
所以逻辑应该是这样的:
if (required vars are absent) {
start a process that {
set required vars;
run another instance of the JVM with the application inside;
}
exit;
}
// here the vars already set
do whatever we need in the proper environment
至于 Java,代码可能如下所示:
public class SecondVM {
public static void main(String[] args) {
if ( System.getenv("SWT_GTK3") == null
|| System.getenv("LIBOVERLAY_SCROLLBAR") == null )
{
URL classResource = SecondVM.class.getResource("SecondVM.class");
boolean fromJar = classResource.getProtocol().equals("rsrc");
String exePath = ClassLoader.getSystemClassLoader().getResource(".").getPath();
exePath = new File(exePath).getAbsolutePath().replaceFirst("\.$", "").replaceFirst("bin$", "");
if (!exePath.endsWith(System.getProperty("file.separator")))
exePath += System.getProperty("file.separator");
String[] script = {
"/bin/bash", "-c",
"export SWT_GTK3=0; "
+ "export LIBOVERLAY_SCROLLBAR=0; "
+ (fromJar? // TODO: Put the proper paths, packages and class names here
"java -jar " + exePath + "SecondVM.jar" : // if runs from jar
"java -cp ./bin/:../ExtLibs/swt_linux64/swt.jar " // if runs from under Eclipse or somewhat alike
+ "com.m_v.test.SecondVM")
};
try {
Process p = new ProcessBuilder(script).start();
// When jar is run from a bash script, it kills the second VM when exits.
// Let it has some time to take a breath
p.waitFor(12, TimeUnit.HOURS);
} catch (Exception e) { e.printStackTrace(); }
System.exit(0);
}
// Now the env vars are OK. We can use SWT with normal scrollbars
Display display = Display.getDefault();
// .... do watever we need
}
}
在 运行 从 shell 脚本中 ning jar 的情况下,我们必须等待子进程完成,然后才能退出原始进程,因此此解决方案会导致开销运行同时连接两个 JVM 实例。如果不需要从脚本中提供 运行 的可能性,则 p.waitFor(12, TimeUnit.HOURS);
可能会被 p.waitFor(12, TimeUnit.MILLISECONDS);
替换,或者可能根本被删除(我没有在没有它的情况下进行测试) ,所以我们可以有一个 JVM 实例,就像通常的 Java 程序一样。
带有 text
小部件和 scrollbar
的工作片段位于 http://ideone.com/eRjePQ