I develop a javaFX application on linux on a Red Hat 6.8 x64 using java 8u162 and an NVidia GPU (and its latest driver), with 2 full HD Screens.
I got an issue retrieving the number of physical screens:
when the X server is in extended desktop mode (2 physical screens, but
a single logical one from 0 to 3840 pixels), Screen.getScreens() returns 2
Screen (which is normal)
When the X server is in separate desktop mode (2 physical screens and
2 logical screens from 0 to 1920 pixels), Screen.getScreens() returns 1
Screen ==> is this normal or a bug?
I compared the JavaFX API to the AWT API:
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gdev = env.getScreenDevices();
AWT returns 2 screen devices in both configuration mode.
I Also checked on java 9 and java 10 using a ubuntu x64 machine and got the same issue with JavaFX.
I tried debugging this and it seems that the issue is in libglass.so in native code.
What do you think about this ? Am I missing something ?
here is the code that reproduces the issue:
public class ScreenTest extends Application {
private static final int SIZE = 1600;
private final AnchorPane root = new AnchorPane();
#Override
public void start(Stage primaryStage) throws Exception {
root.backgroundProperty().set(new Background(new BackgroundFill(Color.BEIGE, null, null)));
Scene scene = new Scene(root, SIZE, SIZE);
primaryStage.show();
Screen.getScreens().forEach(screen -> System.out.println("JAVAFX :"+ screen));
GraphicsEnvironment env =GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gdev = env.getScreenDevices();
for (GraphicsDevice d : gdev) {
System.out.println("AWT:" + d);
}
}
public static void main(String... strings) {
launch(strings);
}
}
Here is my xorg.conf X11 configuration:
Section "ServerLayout"
Identifier "Layout0"
Screen 0 "Screen0" 0 0
Screen 1 "Screen1" RightOf "Screen0"
InputDevice "Keyboard0" "CoreKeyboard"
InputDevice "Mouse0" "CorePointer"
Option "Xinerama" "0"
EndSection
Section "Files"
EndSection
Section "InputDevice"
# generated from default
Identifier "Mouse0"
Driver "mouse"
Option "Protocol" "auto"
Option "Device" "/dev/psaux"
Option "Emulate3Buttons" "no"
Option "ZAxisMapping" "4 5"
EndSection
Section "InputDevice"
# generated from default
Identifier "Keyboard0"
Driver "kbd"
EndSection
Section "Monitor"
Identifier "Monitor0"
VendorName "Unknown"
ModelName "CMN"
HorizSync 53.0 - 66.0
VertRefresh 48.0 - 60.0
Option "DPMS"
EndSection
Section "Monitor"
Identifier "Monitor1"
VendorName "Unknown"
ModelName "DELL C7017T"
HorizSync 30.0 - 83.0
VertRefresh 56.0 - 76.0
EndSection
Section "Device"
Identifier "Device0"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro K3100M"
BusID "PCI:1:0:0"
Screen 0
EndSection
Section "Device"
Identifier "Device1"
Driver "nvidia"
VendorName "NVIDIA Corporation"
BoardName "Quadro K3100M"
BusID "PCI:1:0:0"
Screen 1
EndSection
Related
When user change Display settings scaling (Windows 10, right click on desktop, select Display settings and scale to 150%), suddenly all values reported by
GraphicsDevice device = MouseInfo.getPointerInfo().getDevice();
Rectangle bounds = device.getDefaultConfiguration().getBounds();
or
Toolkit.getDefaultToolkit().getScreenSize();
or
GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
become invalid. Is there a way how to get the actual values ?
Found solution that seems to respect the Display settings.
javafx.geometry.Rectangle2D r = new javafx.geometry.Rectangle2D(0, 0, 1, 1);
ObservableList<Screen> screens = Screen.getScreensForRectangle(r);
if (screens != null && screens.size() > 0) {
javafx.geometry.Rectangle2D rc = screens.get(0).getBounds();
}
I have a Java application that displays two JFrames on two separate monitors. On Ubuntu and Windows the application displays just fine. I can configure the JFrames to display on the monitors with the specified screen ID. However on openSUSE it keeps displaying on the same monitor regardless of the setting. What is different to openSUSE?
Here is some of the code that I use to determine on which monitor the JFrame must display:
GraphicsDevice[] screens = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
for (int s = 0; s < screens.length; s++) {
GraphicsConfiguration configuration = null;
for (int c = 0; c < screens[s].getConfigurations().length; c++) {
if (AWTUtilities.isTranslucencyCapable(screens[s].getConfigurations()[c])) {
configuration = screens[s].getConfigurations()[c];
break;
}
}
if (configuration == null) {
configuration = screens[s].getDefaultConfiguration();
}
if (screens[s].getIDstring().equals[frame1_id]) {
frame1 = new JFrame("Frame 1", configuration);
frame1.setResizable(false);
frame1.setUndecorated(true);
frame1.setBounds(configuration.getBounds());
frame1.setVisible(true);
}
if (screens[s].getIDstring().equals[frame2_id]) {
frame2 = new JFrame("Frame 2", configuration);
frame2.setResizable(false);
frame2.setUndecorated(true);
frame2.setBounds(configuration.getBounds());
frame2.setVisible(true);
}
}
The OpenSuse implementation of GraphicsEnvironment may depend on the choice of a particular window manager. You'll have to experiment to find the optimal one.
Addendum: #bouncer comments, "I have used the Gnome window manager, which caused the problem. After switching to KDE, the problem was solved." See also 10 things to do after installing openSUSE 12.3.
In Linux, we have virtual screens like desktop 1, 2, 3, 4. Most cases we use desktop 1 (screen 1, with one monitor).
Now, my question is how can i tell my java application to launch on desktop 2 (screen 2, with one monitor)
By default when i run java -cp /var/tmp/SystemX.jar run.X it will launch in desktop 1, screen 1. Which is not my case.
Tried: following but did not helped cause, it runs for dual monitor scenario. Not what i am expecting.
screen = Toolkit.getDefaultToolkit().getScreenSize();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screenDevices = ge.getScreenDevices();
for (int i = 0; i < screenDevices.length; i++) {
System.out.println(screenDevices[i].getIDstring());
int screenWidth = 1024;
int screenHeight = 764;
if (screenDevices[i].getDisplayMode()!=null) {
DisplayMode dm = screenDevices[i].getDisplayMode();
screenWidth = dm.getWidth();
screenHeight = dm.getHeight();
}
System.out.println("[myResolution]: " + screenWidth + " " + screenHeight);
screen.width = screenWidth;
screen.height = screenHeight;
}
Follow up:
#!/bin/sh
(export DISPLAY=:0.0 && java -cp /var/tmp/SystemX.jar run.X) & (wmctrl -r "WINDOW_TITLE" -t DESKTOP_NUMBER)
* But what if my application is border less, when it has no window title ? how do i tell wmctrl ?
The borderless applications should still have window titles. (ie. xfce4-panel shows.) You can check what they are by using:
wmctrl -l
From the command line. If you're having a hard time figuring out which window is yours, try the command before you open it, then once it's open. That way, you can just look for the new window.
When i have a PC with only, DVI output and monitor is VGA input (so i used a small DVi to VGA converter, i have my display of OS)
Linux display query shows this following:
$ export DISPLAY=:0.0 && xrandr
xrandr: Failed to get size of gamma for output default
Screen 0: minimum 640 x 480, current 1280 x 1024, maximum 1280 x 1024
default connected 1280x1024+0+0 0mm x 0mm
1280x1024 0.0*
1024x768 0.0
800x600 0.0
640x480 0.0
legend (0x10c) 74.5MHz
h: width 1280 start 1344 end 1472 total 1664 skew 0 clock 44.8KHz
v: height 720 start 723 end 728 total 748 clock 59.9Hz
-- Where my Java application gets confused while startup, and fail to launch the application, with exception is coming from dm.getWidth();:
screen = Toolkit.getDefaultToolkit().getScreenSize();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screenDevices = ge.getScreenDevices();
for (int i = 0; i < screenDevices.length; i++) {
System.out.println(screenDevices[i].getIDstring());
DisplayMode dm = screenDevices[i].getDisplayMode();
int screenWidth = dm.getWidth(); // this fails....
int screenHeight = dm.getHeight();
System.out.println("[myResolution]: " + screenWidth + " " + screenHeight);
screen.width = screenWidth;
screen.height = screenHeight;
}
-- Output:
[meJavaDebug]: YES i am running
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at main.YumYumYum.createAndShowGUI(YumYumYum.java:167)
at main.YumYumYum.access$000(YumYumYum.java:42)
at main.YumYumYum$1.run(YumYumYum.java:118)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:226)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:647)
at java.awt.EventQueue.access$000(EventQueue.java:96)
at java.awt.EventQueue$1.run(EventQueue.java:608)
at java.awt.EventQueue$1.run(EventQueue.java:606)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:105)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:617)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:275)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:200)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:185)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:177)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:138)
Total Garbage Collections: 0
Total Garbage Collection Time (ms): 0
Any idea?
It appears that screenDevices[i].getDisplayMode() is returning null on your system.
It could be related to this bug in the Java Bugs Database, for which there doesn't seem to be a viable workaround ... apart from testing to see if the display mode is null and not using it if it is.
How can i completely make this grey panel as transparent, so that i can see only the button "Test" but not the grey box (JPanel or JLayeredPane)
Screen shot:
public class win extends JWindow
{
...
public win()
{
super(new JFrame());
layers = new JLayeredPane();
button = new JButton("close");
this.setLayout (new BorderLayout ());
..
button.setBackground(Color.RED);
button.setSize(200,200);
button.setLocation(0,20);
this.add("North", button);
JPanel p = new JPanel();
p.setOpaque(false);
p.setSize(300, 200);
p.setLocation(0, 0);
p.add(new JButton("Test"));
layers.add(p, new Integer(1));
layers.setSize(400,300);
layers.setLocation(400,50);
layers.setOpaque(false);
this.add("North", layers);
canvas.setSize(screenSize.width,screenSize.height);
this.add("North",canvas);
//com.sun.awt.AWTUtilities.setWindowOpacity(this, 0.5f); // gives error in my Java version
}
}
Follow up: installed as recommended, but no luck yet.
ERROR not solved: Exception in thread "main" java.lang.UnsupportedOperationException: The TRANSLUCENT translucency kind is not supported.
Installed:
compiz-gnome.i686 0:0.9.4-2.fc15
Dependency Installed:
compiz-gtk.i686 0:0.9.4-2.fc15 compiz-plugins-main.i686 0:0.9.4-1.fc15
libcompizconfig.i686 0:0.9.4-1.fc15 protobuf.i686 0:2.3.0-7.fc15
Complete!
You have mail in /var/spool/mail/root
[root#example ~]# xdpyinfo | grep -i render
RENDER
You have mail in /var/spool/mail/root
[root#example ~]# xdpyinfo | grep -i comp
Composite
XVideo-MotionCompensation
[root#example ~]#
See this article or this article. Note that not all environments support all the features (translucency, per pixel transparencyt etc.) described in the article.
EDIT: On my system (Ubuntu 10.04.2 LTS, Sun java 1.6.0_26) the following code:
System.out.println("TRANSLUCENT supported: " + AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.TRANSLUCENT));
System.out.println("PERPIXEL_TRANSPARENT supported: " + AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.PERPIXEL_TRANSPARENT));
System.out.println("PERPIXEL_TRANSLUCENT supported: " + AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.PERPIXEL_TRANSLUCENT));
gives:
TRANSLUCENT supported: false
PERPIXEL_TRANSPARENT supported: true
PERPIXEL_TRANSLUCENT supported: true
EDIT2: Inspired by this discussion, I just installed and configured compiz and now the 'constant opacity level' slider of the web start application at the second article linked above suddenly can be moved to values smaller than 100% and the demo frame actually is translucent. Also the code snipped shown above now prints true for all three kinds of translucency/transparency. And AWTUtilities.setWindowOpacity(..) does not throw any more but produces a transparent window.