I want to display a JME application on a beamer that is connected to the computer. On the monitor will be a Swing GUI that controls the JME application.
However, the settings dialog doesn’t allow you to select the screen to render the application on and will always put it on the primary monitor. As a workaround I’ve tried to let the application render to a Swing canvas and add that to an undecorated JFrame. With [java]GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[1].setFullScreenWindow(appFrame);[/java] the frame can be placed on the secondary display, but then the JME canvas is hidden (it does show up very briefly when I exit the application) :-s Even though it is visible when the frame is not in fullscreen mode.
Does anyone have any idea how to make the JME application show up on another screen than the primary one? Or, if that is not possible, how to get the canvas to display correctly in fullscreen mode?
Why not query Java for the display’s parameters and set the location of the LWJGL window? (i.e: by a pixel location)
That sounds like it could work, but it raises the following questions:
Will the application be in fullscreen and will I still be able to change the DisplayMode of the second screen?
And how do I get a reference to the LWJGL window? Google only really gives me results for JME2, not for JME3 which I’m using.
Furthermore, I saw in the source code of SettingsDialog that [java]GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()[/java] is used to get the available DisplayModes. Would it not be possible to tell JME to use a different screen?
Ok, I have to admit I never really did anything with LWJGL… But of course I can move the screen with Display.setLocation(x, y). Because I don’t have access to a multi-screen pc at home I’ll have to wait until tomorrow to try and see if that works as desired.
@jogchem said:
Ok, I have to admit I never really did anything with LWJGL... But of course I can move the screen with Display.setLocation(x, y). Because I don't have access to a multi-screen pc at home I'll have to wait until tomorrow to try and see if that works as desired.
It should be pretty straight forward... If you use Java's built-in measurements (getScreenSize()) or whatever the call is, the values are in total pixels. (so 2560x1024 if you have two 1280x1024 monitors)
Yeah. Screen ratio should be either 16:9, 16:10 or 4:3. Using this you should be able to see if there’s more that one monitor.
It’s even easier reading this :
http://docs.oracle.com/javase/6/docs/api/java/awt/GraphicsEnvironment.html
and this:
http://docs.oracle.com/javase/6/docs/api/java/awt/GraphicsDevice.html
could i chage the Screen ratio???
I can move the LWJGL window (in windowed) mode to the other screen, no problem there. But this won’t let me show it fullscreen (Display.setDisplayModeAndFullscreen(new DisplayMode(1024, 768)) does nothing). Nor will it allow me to change the DisplayMode of the second screen.
I would like to be able to set the screen resolution from my application, instead of letting the end user do that in the Windows config.
(BTW: I don’t need to check for the existence of a second screen, because the application will always be run on a pc/laptop with a beamer attached)
If there is no better solution you could use Java’s built in fullscreen mode and use a JMECanvas instead of LWJGL-Window.
(I have to admit that I never did fullscreen with Java with more than one screen attached but I hope it’s possible^^)
@jogchem said:
I can move the LWJGL window (in windowed) mode to the other screen, no problem there. But this won't let me show it fullscreen (Display.setDisplayModeAndFullscreen(new DisplayMode(1024, 768)) does nothing). Nor will it allow me to change the DisplayMode of the second screen.
I would like to be able to set the screen resolution from my application, instead of letting the end user do that in the Windows config.
(BTW: I don't need to check for the existence of a second screen, because the application will always be run on a pc/laptop with a beamer attached)
Make the Window fuill size, and make a fake fullscreen this way, be setting its location exactly so, that you only see the content.
Alternative low performance solution would be to use a Swing Frame wihout decorations and render to that.
As mentioned in the OP I tried to make a fake fullscreen window using Canvas, but it seems that the Swing window only renders the Canvas when it is not in fullscreen mode. I have no problems using this method, because performance is not really an issue. If only it would show more than a gray (on this computer) or black (on my home computer) screen I would be more than happy.
This is the test I’m using, a simple app with a box that can be rotated with a button in a Swing window:
[java]package nl.malienkolders.test.remotecontrol;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;
public class TestRemoteControl extends SimpleApplication {
private Geometry geom;
@Override
public void simpleInitApp() {
// keep updating
setPauseOnLostFocus(false);
// remove default controls
inputManager.clearMappings();
flyCam.setDragToRotate(true);
Box b = new Box(Vector3f.ZERO, 1, 1, 1); // create cube shape at the
// origin
geom = new Geometry(“Box”, b);
Material mat = new Material(assetManager,
“Common/MatDefs/Misc/Unshaded.j3md”); // create a simple
// material
mat.setColor(“Color”, ColorRGBA.Blue); // set color of material to blue
geom.setMaterial(mat); // set the cube’s material
rootNode.attachChild(geom); // make the cube appear in the scene
}
public static void main(String[] args) {
GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = environment.getScreenDevices()[1];
// list all available display modes
/for (DisplayMode mode : device.getDisplayModes())
System.out.println(String.format("%dx%d %d %d", mode.getWidth(), mode.getHeight(), mode.getRefreshRate(), mode.getBitDepth()));/
// instantiate JME app
final TestRemoteControl app = new TestRemoteControl();
AppSettings settings = new AppSettings(true);
settings.setWidth(1024);
settings.setHeight(768);
settings.setTitle(“View”);
app.createCanvas();
final JmeCanvasContext context = (JmeCanvasContext) app.getContext();
// instantiate the viewer frame to provide fake fullscreen
final Frame viewer = new Frame(“Viewer”);
viewer.add(context.getCanvas());
viewer.setUndecorated(true);
viewer.setVisible(true);
viewer.setSize(1024, 768);
// make the viewer fullscreen (removing these lines makes the JME canvas visible again)
device.setFullScreenWindow(viewer);
device.setDisplayMode(new java.awt.DisplayMode(1024, 768, 32, 60));
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// create a very simple controller window
JFrame controller = new JFrame(“Controller”);
controller.getContentPane().add(new JButton(new AbstractAction(“Rotate”) {
@Override
public void actionPerformed(ActionEvent arg0) {
app.geom.rotate(0f, FastMath.PI / 12f, 0f);
}
}));
controller.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
controller.setVisible(true);
controller.pack();
}
});
}
}[/java]
When I don’t make the viewer frame fullscreen it behaves as expected. When I do make it fullscreen on the second monitor I just get a gray screen (the frame’s background colour).
I have no problems using this method, because performance is not really an issue. If only it would show more than a gray (on this computer) or black (on my home computer) screen I would be more than happy.
But where is your question then?^^ If you can use a canvas then it should work by getting the 2nd screen's size. Then put a canvas with that size into a JFrame. After that move it into the second screen (and if it's decorated you call getInsets() after setVisible(true) und move it a litte more outside the screen)
Or did I miss your problem again?^^
The problem is that I want to set the second screen to 1024x768, but that is only possible after setting a fullscreen window with GraphicsDevice.setFullScreenWindow() (which makes my JME canvas disappear).
You can also try using an AWT panel, it will reduce performance but since its a regular lightweight Swing component it should work fine with those AWT methods. See TestAwtPanels.
The issue is that the canvas is provided by LWJGL, which might not support those special fullscreen modes. Similarly the window/display is also provided by LWJGL, and it is mentioned on their website that multiple monitors are not supported.