如何以编程方式禁用覆盖滚动条(Ubuntu Java)

时间:2017-02-05 04:38:56

标签: java eclipse ubuntu swt

尝试移植到Ubuntu SWT我在Windows工作正常的overlay scrollbars应用程序,我遇到了Eclipse的问题。当我从JAR下运行应用程序时,一切正常,滚动条看起来和行为正常。但是当我将应用程序打包到JAR并执行此export LIBOVERLAY_SCROLLBAR=0时,应用程序中的滚动条将变为“叠加滚动条”,看起来像细橙色条带和滚动条我需要处理的事件应该有一些奇怪的字段值,所以我的应用程序完全忽略它们。这对我来说是不可接受的,我的应用程序以特殊的非标准方式处理滚动条很重要,因此我需要正常查看滚动条和它们的正常事件。

通过向~/.profile添加 System.setProperty("LIBOVERLAY_SCROLLBAR", "0"); 可以轻松修复此问题,但我不想强制最终用户进行自定义系统设置以运行我的应用程序,我想要它们只需点击JAR就可以运行它,无需任何特别的努力。

我是Linux编程的新手,我不知道如何以编程方式设置环境。放置

  new ProcessBuilder("export LIBOVERLAY_SCROLLBAR=0").start();

在我的代码开头没有效果,也没有

$( "#getvalue" ).on( "click", function() {
    .
    .
    value = $("#spinner").val(); 
      alert(value);
    });

如何从我的代码中禁用此“叠加滚动条”

P.S。任何其他语言的解决方案也许也可能是一个线索

2 个答案:

答案 0 :(得分:1)

更改当前进程(您的Java程序)的环境变量很困难,可能并不总是有效。但是,您可以使用您的jar分发shell脚本,Linux上的人可以使用它来启动您的应用程序。这样的事情可以解决问题:

>prepare<-function() return(list(f=function(x) x+1, g=function(x) x+2))
> p<-prepare()
> p$f(1)
[1] 2
> p$g(1)
[1] 3

答案 1 :(得分:0)

存在为当前运行的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?

的答案

但在我的情况下,我需要env vars来影响在VM外部执行的库,因此这种方法无法解决我的问题。

在思考了一点之后我意识到我想为JVM的父进程设置环境,所以我首先需要设置所需的变量,然后递归运行另一个将执行我的app的JVM实例 - 然后是变量即使代码在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脚本运行jar,我们必须等待子进程完成,然后退出原始进程,因此这个解决方案会导致同时运行两个JVM实例的开销。如果不需要提供从脚本运行它的可能性,p.waitFor(12, TimeUnit.HOURS);可能会替换为p.waitFor(12, TimeUnit.MILLISECONDS);,或者可能会被删除(我没有测试过它),所以我们可以有一个JVM实例,就像通常的Java程序一样。

包含text窗口小部件和scrollbar的工作代码段位于http://ideone.com/eRjePQ