The tree is game content, the top right was overlapped by the browser and didn’t get redrawn.
I’m running under Linux, using the XFCE window manager (i.e. Xubuntu).
I think I’m doing everything right (with thread issues and such), but of course I may have missed something - so the question is more which area to investigate first than anything else.
Well, almost - resizing the window changes the size by a pixel or two. I suspect that’s because the window gets recentered, or maybe it gets recreated; I’ll investigate a bit further unless somebody comes over with a full solution
Turned out that using restart() would recreate the application window, so the mouse would lose the border being dragged. Understandable.
Trouble is, without restart() the window will resize just fine but the LWJGL context won’t.
Is that a bug?
Even more trouble, I didn’t find a way to make the context resize inside the window. Nor a way to make the window replace the context with a properly-sized one. Not in Display or LinuxDisplay, anyway.
Did I overlook something, or is there really no way to do that?
Yes, recreating the context without stopping the application is exactly what I’m after.
Application.restart() does that. The snag here is that it recreates not just the context but the main window, too, which defeats dragging window borders with the mouse.
With that, I can resize the window just fine with the mouse.
It’s just that enlarging the window does not enlarge the rendering area.
Shrinking the window does not shrink the rendering area, the rendered scene doesn’t get smaller. However, the output is clipped to window size.
You’re right that the render area can’t be resized (or at least it seems so), but what good is an API that allows resizing the window then?
The other question: Would it make sense to try the Swing display? It would be easy to put it into a JFrame (in fact I have seen code by others who do that).
Since nobody bothered to answer my last question: Yes, it works.
Details:
Resizing the JFrame will automatically resize the rendering area. This will scale the displayed scene, too (which is just what I wanted). Enforcing an aspect ratio or a minimum window size needs to be done at the Swing level.
The Swing window did not come with any noticeable different in frame rate. That’s not a big surprise, Swing’s performance problems are more-or-less gone since Java 5.
The basic trick is to override [Simple]Application’s start(), not call super.start(), and use this code somewhere in start():
[java]
JmeCanvasContext context =
(JmeCanvasContext) getContext();
canvas = context.getCanvas();
canvas.setSize(
getAppSettings().getWidth(),
getAppSettings().getHeight());
SwingUtilities.invokeLater(
new SwingApplicationStarter ());
[/java]
canvas can be embedded into any Swing or AWT component, just like a panel or button.
Details to consider:
In the traditional approach, you’d check for changed size inside update(), and put the new size into your Settings (and possibly save them). With Swing, it’s easier to attach a listener to the frame. Anything else related to window size or position is best dealt with in the listener, too (such as a policy on aspect ratio, minimum size, and such).
I don’t know the best way to switch to fullscreen mode with this. I’m pretty sure there’s a more elegant way, but it should always be possible to tear down the Swing setup and restart() the application traditionally and vice versa. The frame should be kept around and left open so it stays available if the user alt-tabs away from the application (a listener on the frame should then switch the application back to Swing mode).
Here’s my code (without imports, and some comments added):
[java]
public class ClientApplicationSwing
extends ClientApplication
{
// ClientApplication is my own variant of SimpleApplication.
Canvas canvas; // Canvas is the standard AWT class.
@Override
public void start() {
loadSettings (); // ClientApplication function to load my Settings object.
setPauseOnLostFocus (false); // I like to keep it running.
// Here we start doing things differently than traditionally.
// If this were a descendant of SimpleApplication, you’d want
// to setDragToRotate(true) here since this is windowed mode
// where you don’t want to grab the mouse.
createCanvas(); // Creates a canvas plus associated rendering machinery.
// We can now work with that canvas just like with any AWT/Swing Canvas.
canvas.setSize(getAppSettings().getWidth(), getAppSettings().getHeight()); // SimpleApplication descendants would use settings instead of getAppSettings().