Toggle AWT Canvas and Fullscreen

I have searched and read many threads discussing this problem but without any answers.

I am trying to toggle a Canvas context type and a Display context type in a SimpleApplication.

Initially I put a canvas into a frame but when I went into fullscreen mode using GraphicsDevice the canvas fails to show. This was discussed in another thread but without any solution.

My next attempt was to change the app settings toggling Display/Canvas and restart() but it didnt work. This was due to the fact that once context is set the Application class does not allow it to be set to a different .

So, I thought, I will destroy the current context and set it to null to a new context will be created. The problem with this is that removeing the canvas from the frame before it is stopped caused the JVM to lock requiring task manager to close the JVM.

stopping with wait blocks, i presume this is because it is still visible therefore neither of these methods are suitable. My next idea was to call stop without wait but then in setting the protected variable context to null causes an exception.

I then tried stopping the context and then writing a new context to that var but I guess the old context clean up causes conflicts with the new context. Its a shame the stop with wait blocks forever.

Anyway, enough of my waffle…

Does anyone have a solution for toggling a Canvas context type and a Display context type in a SimpleApplication???

Many Thanks

Its strange that setting a canvas to full screen causes it to stop working. What OS is this by the way?

You can try AWT panels (if you have not tried yet), although they might work slower, see TestAwtPanels example.

It is actually possible to make a canvas full screen through LWJGL (the library which jME uses to implement rendering), but this part has not been implemented. If you would like, you can make a pull request :hankey:

Hi,
Windows 7 Ultimate to answer your question.

I create a canvas and place it in a frame. This works fine. When I make the frame go full screen via GraphicsDevice the screen goes blank. I do notice though when I exit fullscreen the screen flashes with what should have appeared.

I did read another thread with this experience, i cant find it now, and it had no solution, just said that going to fullscreen causes “a thread” to stop with no solution.

I will persevere with trying to make my own versions of Application and SimpleApplication work. Its a shame Application and SimpleApplication are not interfaces.

Maybee this fits your needs for the moment:
I would try fullscreen window, via lwjgl hidden switches you can disable borders, then you just need to get the resolution right to fit the whole screen.

I cant find TestAwtPanels in either the documentation or the source code.

I have been working on my own solution without much success.

I have tried creating a new context once destroy has been called on the old one. I have been copying over the rootNode, guiNode and timer in the constructor but something is stopping it working.

I am sure it has been done a million times for an applet to toggle fullscreen and I cant believe there isnt a simple solution for this.

TestAwtPanels is in the jME3 source code:

1 Like

Thanks for that. I have a good play to see if I could come up with a viable solution.

I conclude it pretty much reflects one of my attemps where I create a canvas context plonk it into a frame and then set to full screen vis GraphicsDevice…

GraphicsDevice gd=GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
gd.setFullScreenWindow(frame);

which disappointingly results in a blank screen. This is a known issue as discussed on another thread which suggested there is a thread issue but provided no solution.

In one of my attempts I created 2 complete separate SimpleApplications and shared the rootNode, guiNode, timer and settings. I see you set the renderer context type in the settings, I wonder if this is what is causing the problem stopping it working. I will try that again without sharing the settings…

Thanks

So, I still do not have a solution to go from an AWT Canvas to a Fullscreen Display.

Everything I have tried doesnt work. I even tried two completely separate SimpleApplication instances one with a Canvas context and the other with a Display Context. Each works fine if it is the startup instance but as soon as I destory the current the initialisation of the next fails.

This is really frustrating me. I am finding that SimpleApplication is really inhibiting my ability. I have used a number of other 3D engines and I had direct control over the Jogl2 awt newt canvas and windows.

I am trying to migrate to JMonkey but I cant seem to do what I want. I dont even have proper access to the jogl2 and lwjgl.

I dont know a game that doesnt offer fullscreen mode.

When I used Sandy3D and PaperVision3D they were flash based and didnt provide graphics card abilities so they were just slugish. Things my have improved since but going from an applet in a webbrowser to fullscreen mode wasnt an issue whatsoever.

When I used Java3D and Ardor3D I used the Jogl2 AWTNewtCanvas within the Applet and when I wanted to go to fullscreen I created Jogl2 GLWindow and I used the same everything else and it worked a treat. Going from a webbrowser applet to fullscreen and back wasnt a issue whatsoever.

I do feel that SimpleApplication is chopping my hands off from the freedom to do what I like with the components of the JMonkey engine. However, I dont really mind as long as I can acheive what I wish to acheive. And what I wish to acheive is to have my web browser based applet display with an AWT Canvas and then open a fullscreen display with exactly the same scenegraph and so on.

Thanks everyone for your responses. I am left completely dumbfounded that this simple concept of going from an AWT Canvas to fullscreen and back again is so elusive…

Please, anyone, what is the solution!!!

Thanks

How do I make a pull request?
Thanks

Hi,

Sorry, there is something I don’t understand. Can you provide more info about :

  1. You display 3D as part of a frame in a AWT or swing or JavaFX apps ? (can you provide a screenshots in non-fullscreen and fullscreen)
  2. You want to display the frame as fullscreen or the 3D part ?

For a “regular” jme application, toggle fullscreen is not done via GraphicsDevice but with something like :

            AppSettings settingsEdit = new AppSettings(false);
            settingsEdit.copyFrom(app.getContext().getSettings());
            settingsEdit.setFullscreen(fullscreen.isSelected());
            //....
            app.setSettings(settingsEdit);
            //settingsEdit.save(settingsEdit.getTitle());
            app.restart();

If you use swing, you can try jme3_ext_swing, I made it for @AXELTOPOLINO who had trouble with jme3 'solution provide for swing.
The jar is available on bintray, and a demo in the source src/test/java/samples

Applets and the GL canvas are both obsolete functionality at this point and are known to be highly unstable, this is why the jME3 SDK switched to AWT panels by default (as I mentioned above).

However since you mentioned “direct control”, here’s how to do it, although it is highly likely to blow up or not work. Use at your own risk.

To go fullscreen:

Display.setDisplayModeAndFullscreen(Display.getDesktopDisplayMode());
reshape(Display.getWidth(), Display.getHeight());

Back to windowed mode:

Display.setDisplayMode(new DisplayMode(canvas.getWidth(), canvas.getHeight()));
reshape(Display.getWidth(), Display.getHeight());

You will need to import LWJGL specific classes for this to work:

import org.lwjgl.*;
import org.lwjgl.opengl.*;

Hi, Thanks for your responses.

David, I tried your code which resulted in no action. Here is my test code…

package test;

import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext;
import com.jme3.system.JmeSystem;
import com.jme3.app.SimpleApplication;
import com.jme3.app.StatsAppState;
import com.jme3.app.FlyCamAppState;

import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

import com.jme3.input.InputManager;
import com.jme3.input.RawInputListener;
import com.jme3.input.event.JoyAxisEvent;
import com.jme3.input.event.JoyButtonEvent;
import com.jme3.input.event.KeyInputEvent;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent;

import java.awt.Canvas;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import com.jme3.system.JmeCanvasContext;
import com.jme3.system.NullContext;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Test extends SimpleApplication implements RawInputListener
{
private AppSettings appSettings;
private boolean fullscreen=false;
private TestFrame tf;
public static void main(String[] args)
{
DB.install();
DB.print(“START”);
Test t=new Test();

t.show();

DB.print(“END”);
}
private Test()
{
super(new StatsAppState());
tf=new TestFrame();
appSettings=new AppSettings(true);
appSettings.setFullscreen(fullscreen);
setSettings(appSettings);
setShowSettings(false);
}
public void finish()
{
stop();
}
public void show()
{
createCanvas();
tf.setCanvas(((JmeCanvasContext)getContext()).getCanvas());
startCanvas();
}
public void simpleInitApp()
{
Box b=new Box(1,1,1);
Geometry geom=new Geometry(“Box”,b);
Material mat=new Material(assetManager,“Common/MatDefs/Misc/Unshaded.j3md”);
mat.setColor(“Color”,ColorRGBA.Blue);
geom.setMaterial(mat);
rootNode.attachChild(geom);
InputManager inputManager=getInputManager();
inputManager.clearMappings();
inputManager.clearRawInputListeners();
inputManager.addRawInputListener(this);
inputManager.setCursorVisible(true);
stateManager.detach(stateManager.getState(FlyCamAppState.class));
}
public void screenSwap()
{
fullscreen=!fullscreen;
DB.print(“screenSwap fs=”+fullscreen);
AppSettings settingsEdit=new AppSettings(false);
settingsEdit.copyFrom(getContext().getSettings());
settingsEdit.setFullscreen(fullscreen);
setSettings(settingsEdit);
restart();

// GraphicsDevice gd=GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
// if(fullscreen)
// {
// gd.setFullScreenWindow(tf);
// }else{
// gd.setFullScreenWindow(null);
// }
// restart();
}
//################################################################################
// RawInputListener
//################################################################################
public void beginInput()
{}
public void endInput()
{}
public void onJoyAxisEvent(JoyAxisEvent _e)
{
DB.print("RawInputListener.onJoyAxisEvent "+_e);
}
public void onJoyButtonEvent(JoyButtonEvent _e)
{
DB.print("RawInputListener.onJoyButtonEvent "+_e);
}
public void onKeyEvent(KeyInputEvent _e)
{
DB.print("RawInputListener.onKeyEvent "+_e);
}
public void onMouseButtonEvent(MouseButtonEvent _e)
{
DB.print("RawInputListener.onMouseButtonEvent "+_e);
if(_e.getButtonIndex()==0&&_e.isReleased())screenSwap();
}
public void onMouseMotionEvent(MouseMotionEvent _e)
{
DB.print("RawInputListener.onMouseMotionEvent "+_e);
}
public void onTouchEvent(TouchEvent _e)
{
DB.print("RawInputListener.onTouchEvent "+_e);
}
//################################################################################
// TestFrame
//################################################################################
private static class TestFrame extends Frame
{
private static final long serialVersionUID=1;
private Canvas canvas=null;
private TestFrame()
{
super(“TestFrame”);
setBounds(10,10,600,500);
setVisible(true);
addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent _e){setVisible(false);}});
}
private void setCanvas(Canvas _canvas)
{
if(canvas!=null)remove(canvas);
canvas=_canvas;
if(canvas!=null)add(canvas);
DB.print(“new Canvas=”+_canvas);
}
}
//################################################################################
// end
//################################################################################
}

To answer your questions, I have included a screen shot of my project running in a web served page. The structure is simply an AWT Canvas childed to the Applet.

There is no other AWT or Swing functions or objects whatsoever. My GUI runs completely within the JOGL Newt Canvas. Unfortunately I havent written the handler to pull the image from the graphics card in full screen mode so you will just have to believe me it works and very reliably too.

The reason why your suggestion didnt work, so I believe, is that the “context” is of lwjgl canvas, ie should sit within a frame, or applet in my case, which does not have the ability to go to full screen. In my existing project I create a Jogl2 GLWindow and just redirect the renderer and input events achordingly and works very well.

Momoko, I downloaded the lwjgl3-mater.zip from www.lwjgl.org but couldnt find any class called “Display” and I couldnt find any class called “Display” within the jme3 libs either so I am not sure how to implement your suggestion.

Many thanks for your suggestions. I am begining to come to the conclusion that to acheive my, what I would have considered a simple and obvious, requriement it looks like I am going to have to bastadise JMonkey with a very large sledgehammer.

Unless someone has a solution lol
Maybe I need to seriously consider other 3D engines.
Regards
Penny

Thanks for the details. I agree that you can’t change the gl context from canvas to display.
I made a small sample using jme3_ext_swing into JApplet and toggle fullscreen by switch parent of the JApplet (applet container <-> JFrame). It works in the appletviewer , I didn’t test with regular applet, because using native lib require special packaging,… (I did it as day job for a game studio 3 years ago).

If you want to give a try :

FYI jme3_ext_swing render 3D offscreen and copy the image into a ImagePanel (a JPanel).
Hope you find a solution.

If you use raw JOGL, why using jME ?

I will look into your suggestion. I wonder what impact it will have on peformance.

I wouldnt say I exactly use Jogl2 directly. 3D engines bring a lot of tinsel which I enjoy very much. However, when the need arises and I have to delve into the depths of the underlying architecture I tend to gingerly do lol

My current perspective is that I dont think I will be happy manually writing an off screen buffer to the frame due to the performance costs. I am quite astonished that JMonkey cannot easily go from an applet canvas to a full screen display. I also have the perspective that Application and SimpleApplication take away a lot of use defined function and abilities of the underlying architecture.

I think I am going to do some “tests” of the tinsel that comes with JMonkey before I commit myself to rewriting the interface to the underlying architecture just to make sure it answers my needs that previous 3D engines failed to do.

The reason for my migration from previous 3D engines is because they were/are no longer supported and no more continuing development. Which is disappointing and painful. Looking at the showcases of JMonkey I am quite satisfied that my needs will be met whilst also ejoying continuing support and development.

I am just trying make the best descisions with the choices that I have before me.

I am still looking for an easy solution to my requirement. At this moment I am going to develop a couple of test apps to ensure the tinsel meets my requirements. If I conclude that JMonkey does infact meet my requirements, if I havent found a solution to toggling a fullscreen mode whilst using an Applet Canvas my next step will be to bust open the internal workings of Jmonkey and develope my own solution.

What else can I do with the options I have?
Regards

Since applets are all but dead in Java these days… I guess making it work ‘better’ is less a priority.

With all of the applet vulnerabilities, it’s been all I can do to keep people I know from wholesale uninstalling it. I always make sure to include the word “applet” whenever I talk about “java applet vulnerabilities”. This is also a large part of the reason we are moving to support application bundles with the JVM optionally included… to still be able to run on systems where people carved out their java with a rusty dull spoon.

I can’t even seem to get applets to fly against this group-think in environments where we control the platforms. Even webstart is being disabled these days.

Edit: because note that going from windowed to full screen works just fine in desktop apps… non-applet apps.

I am all for entertaining new ideas.

If Applets are all but dead, what is the prefered method to roll out a java app?

I went for an Applet because firstly people would visit my website. When they select to run my application they would be presented with my security certificate so they would be in the full knowledge that I would have 100% access to their system and hopefully they would “trust” me not to do anything they dont want.

I question what you mean by “Applet Vulnerability” because no applet without a security certificate can alter the users system. Do you mean the vulnerability of stupid people accepting certificates that they shouldnt? or developers abusing their trust and performing tasks that they shouldnt once their security certificate has been accepted?

I like applets because they run within my website and therefore have some level of continuity unlike webstart which seems to me to be like a hard transittion from one state to another.

Whenever anyone installs a program or game they are trusting the developer not to do anything untoward. Are you suggesting that the people who have uninstalled java because of its so called “vulnerabilities” should not install any software whatsoever because of the vulnerability that the software could do something the user doesnt want?

If java applets are able to alter the system of a user without a security certificate then surly that is an issue for Oracle?

Anyway, considering applets and webstart have exactly the same abilities and “vulnerabilities” what options are you refering to that overcome these “vulnerabilities” you refer to?

I thought this one was generally known. Java had several vulnerabilities over the last few years that were very public. They effectively allowed various ways of jumping outside of the secure sandbox and the general advice was to uninstall or disable Java. It seemed like Oracle was pushing patches out almost weekly there for a while. Panic was high and people were frequently damning Java across the board.

If you google search for “java applet vulnerabilities” you get a ton of hits from about 2 years ago. For example: https://www.us-cert.gov/ncas/alerts/TA13-032A

Applets and Java itself had a sort of weak existence prior to that but the taint of the many vulnerabilities, seemingly one after another, (to me) put the final nails in the coffin of Java applets. Kind of too bad… but I’d personally prefer to salvage desktop Java than to try to beat the dead-but-lingering horse that Applets have been for half a decade.

As to deployments, one approach: simply check the box in the SDK that generates an executable for your application and provide that zip for download. Then it works the same as many other Java games (like Minecraft, etc.) and very similarly to nearly every other type of non-flash game.

Alternativly a very small desktop application that downloads the rest. One example of such is GetDown. GitHub - threerings/getdown: Download, Install, Update

2 Likes