Workaround for Slow Java Swing Menus

2019-06-16 01:49发布

In Java 7 and 8 there is a bug in Swing menus that causes it to be slow when running an application remotely over X11 while other X11 applications are running. This issue was introduced in Java 7 and has never been fixed. Does anyone have any suggestions on a workaround. Using nxclient addresses this Swing menu issue, but introduces its own unwelcome issues.

The steps to reproduce the Swing menu issue are: - run any X11 application locally with some activity - log into a remote server using ssh -Y someserver - execute any Java GUI application (e.g. jvisualvm) running Java 7 or 8 - select a menu and observe a several second delay in response

标签: java swing menu
4条回答
家丑人穷心不美
2楼-- · 2019-06-16 02:34

Just spent an entire day trying to solve the same issue. There's barely any info out there.

Local machines:

  1. Linux FedoraCore 20, KDE desktop, NVIDIA GeForce 7300 LE
  2. Linux FedoraCore 20, KDE desktop, NVIDIA GeForce GT 720

Running remote Java GUI over ssh, swing popups are extremely slow for PC2. Desktop freezes until popup appears. On the other hand, PC1 runs very fast/smooth, with no problems at all.

Turns out, in my case, the problem is that PC2 has 2 monitors. The closest bug report I could find is: JDK-8004103 : sun.awt.X11.XToolkit.getScreenInsets() may be very slow and it appears to be still open.

Temporary Workarounds:

  1. In KDE, Disable second monitor, Launch Application, Enable second monitor
  2. Work in Gnome Desktop (My Gnome environment not affected by this issue)
  3. Launch remote Java app using Java 6 (Issue not present in Java6)

None of these are ideal workarounds, but considering that my Desktop freezes for 3-4 seconds every time I click on a menu item, they'll do for the time being.

查看更多
老娘就宠你
3楼-- · 2019-06-16 02:35

Well, there still doesn't seem to be much information out there on how to work around this problem and running an application via remote X11/xinerama makes it practically unusable. In particular, menu navigation takes an eternity. The work-around that we employed has 2 parts to it.

  1. At the startup of your application call: JPopupMenu.setDefaultLightWeightPopuEnable(false);

    This will force the popups to use heavy weight popups. Lightweight popups make multiple calls to the X windows across the network to determine what is visible, obscurred, etc. When operating over remote X11 this becomes a very expensive call. Lightweight popups make these calls everytime the popup becomes visible. Heavyweight popups make this call when they are 1st invoked, but every successive popup action reuses the heavyweight component that I'm guessing is managed by the window manager so the menus thereafter are very responsive.

  2. Create a new XineramaJMenu class that extends JMenu. This class must override the method:

    protected Point getPopupMenuOrigin() {...}

copy the code for this method from JMenu, but replace the line:

 Insets screenInsets = toolkit.getScreenInsets(gc);

with

 Insets screenInsets = new Insets(0,0,0,0);

This eliminates the getScreenInsets(...) call, which makes multiple calls to the remote X server to determine the max inset values of the child windows. We eliminate this expensive call across the network and accept a default 0 inset.

Unfortunately, this will require you to replace all instances of JMenu with XineramaJMenu, but it at least results in usable menus when running your application over remote X11.

查看更多
做自己的国王
4楼-- · 2019-06-16 02:39

I finally found much better workaround for this problem. When opening the SSH connection to the remote computer, set ForwardX11Trusted option to "no".

ssh -o ForwardX11Trusted=no -X user@host.domain

For me, opening a ComboBox reduced from ~14s to instantly. Unfortunately, I currently don't have any Java applications with Swing Menu installed on the server, but I think this should work for Menus too.

If you don't want to type that option every time, add the following line to ssh config file (/etc/ssh/ssh_config)

ForwardX11Trusted no
查看更多
迷人小祖宗
5楼-- · 2019-06-16 02:42

I was able to solve this problem on a RHEL 7 system with NVidia graphics board and NVidia driver 340.96 running KDE 4.14.8 by adding this option to the Screen section of the X server config file.

Option         "nvidiaXineramaInfo" "Off"

The NVidia driver manual has this to say about this option:

The NVIDIA X driver normally provides a Xinerama extension that X clients (such as window managers) can use to discover the current layout of display devices within an X screen. Some window mangers get confused by this information, so this option is provided to disable this behavior.

Perhaps KDE is one of the window managers that gets confused?

查看更多
登录 后发表回答