Resizable Applets and Applications with LWJGL

Some posts before, in the comments section, Gornova asked me to write about resizable Applets if I had some time. As I never used resizable LWJGL Applets, I had to do some research. This post is to show what I found.

(note: LWJGL version 2.8.2 was used for all the tests I made).


LWJGL Applets are similar to LWJGL Applications, they work using a class named Display which uses an AWT Canvas component. On desktop, you create a JFrame or similar and add inside a Canvas, on Applet you just create the Canvas and add it to the Applet. Unless you want some custom behavior, I believe that is the common usage.

(note: using fullscreen is a different case but has no meaning for this post)

How to resize an Applet

To resize an Applet on the browser, two possible ways are, use Javascript to change the applet tag sizes or just configure the HTML applet tag to adapt to its container size, so if you resize the browser window then all corresponding HTML components are resized.

The other way around, suppose you have a way inside your game to choose the game resolution, you will have to communicate that to the Browser, probably calling a Javascript function from your Applet to let the Browser react to the change.

How to handle Applet resize

If you are working with LWJGL directly, then it depends a lot of how which kind of layout are you using for the container of the Canvas object. For example, if you chose a layout which grows to the parent container size, then each time you resize the container, the Canvas will be resized. If you chose another layout, then maybe you will call Canvas.setSize() by hand.

However, you need to react to that change in your game, to do that the best way (imho) is use a similar approach LibGDX does. What LibGDX does is, its stores the current Canvas size on each iteration of the main application loop, on the next iteration, if the Canvas size is different to the stored, then it calls a resize() method to tell your game the screen size changed.

Another way is to create a ComponentListener and add that to the Canvas component so each time the componentResized() method is called you resize your game. However as all the AWT stuff runs in another thread you need to store the new size and process the resize in your LWJGL thread to avoid problems.

What to do inside your game

The very basic approach is to just modify the OpenGL viewport of your game, then the game is scaled to the new size and, in some cases, that should be enough.

	glViewport(0, 0, width, height);

However, You may want to take care about aspect ratio since just scaling the game could look ugly. One option is to modify the viewport in values to maintain the aspect ratio you want, for example:

	glViewport(0, 0, width, width / aspectRatio);

You could also provide different common aspect ratios (4:3, 16:10, 16:9, etc). However, I believe the best option is to provide fixed commonly used resolutions like 640x480 or 800x600 instead.

In some cases you could want to adapt your game elements, for example GUI stuff, where you may want to maintain the element sizes and move them accordingly over the screen instead just scaling them.

Then, you have to take care of the user input. As mouse location is dependent on the viewport size, you will have to take that in mind when interacting with part of your application, like the GUI stuff, after a size change. For example, LibGDX Camera uses the current viewport size when using project and unproject methods (which allow you to transform world coordinates to viewport coordinates and vice versa).

Not so sure as I am not an OpenGL expert but if you work different cameras (model + projection matrices) you probably need to update them in order to render everything in the correct way. I have to go deeper in this issue.

Optionally, you may want make other changes when reacting to the resize like loading HD assets if you go to a higher resolution and vice versa.

Some issues

  • You have some glitches if you do resize in real time (tested myself, but cant find references right now). However, in general nobody does this so it is not a big problem.
  • I believe Applet resizing is not working on mac yet.


Handling all the mentioned things when resizing LWJGL Applets and LWJGL Applications depends a lot on the game you are making, in some cases the basic approach work fine and should be easy to implement.

Despite the article was focused mainly on LWJGL Applets, great part of the findings can be applied to LWJGL Applications as well.

This post is only to show some basic experimentation I made on the subject, as I said before, I am not an OpenGL nor LWJGL expert, so some assertions could be wrong. If you have more experience and want to contribute your opinion, feel free to do it.

Thanks and hope you like the post.

VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

LWJGL on Maven central

Hi we are happy to announce that LWJGL is available in Maven central. We worked hard with the @LWJGL people to make this possible.

Why was it important to get LWJGL into central?

Well, one of the biggest pains when using maven is having your dependencies available from central, if they are, you just need to add a little snippet of XML and you are done, if they aren't, then you need to install them manually to your local repo or to a private maven repo.
This is a problem in itself but this also means that projects that depend on something that isn't available in central, can't get into central themselves, making the work needed to use it grow exponentially.

Previous work

In order to get LWJGL into central we had to work first with @Endolf to get JInput into central so a huge thanks to him as well.

Future plans

Now that we got LWJGL into maven central, we can start thinking about trying to convince the authors of other useful libs that use LWJGL like Slick2D, libGDX, nifty-gui, etc to make their libs also available on central (of course we would love to help make this a reality as well).

If you use LWJGL with maven, we would love to hear from you and feel free to ask us anything.

More information:

VN:F [1.9.22_1171]
Rating: 5.0/5 (3 votes cast)

JNLP Applet Loader

Now that we talked about the LWJGL Applet Loader, we want to talk a bit about the JNLP Applet Loader. In a quick description, the JNLP Applet Loader is an adapter of the LWJGL Applet Loader to make it work with JNLP files.


All of our games were previously released through Web Start and New Generation Plug-In Applets using JNLP files and we wanted to use LWJGL Applet Loader in an easy and seamlessly way.


Our solution was to create an Applet to parse the JNLP file and with that information, create the parameters needed in order to run the LWJGL Applet Loader.

Right now, it works with two parameters:

  • al_jnlp : an URL used for telling it where to find the JNLP file to use in order to launch the game. First, it downloads and parses the JNLP file and with the information provided, and with that, it creates all LWJGL Applet Loader parameters (al_jars, al_main, etc).
  • appendedJarExtension : a String suffix appended to all jar and natives dependencies in order to let the LWJGL Applet Loader to download optimized with pack200 and gzip files while it doesn't process the content encoding for pack200 and gzip stuff.

You can find the project on github with the name of jnlpappletloader. It is a maven project, and right now, as it depends on a custom distribution of the LWJGL, it will not compile for you at least you configure your local maven repo with the required dependencies. Once the LWJGL is on maven central repo, the idea is to depend on it directly.

The best part is that now we can run any of our already deployed games by making a simple applet like this:

<applet code="com.gemserk.jnlpappletloader.util.jnlp.applet.JnlpAppletLoader" archive="jnlpappletloader-full-0.0.4-jar-with-dependencies.jar" codebase="" width="640" height="480">
  <param name="al_jnlp" value="">
  <param name="appendedJarExtension" value=".pack.gz">

Here is a working example of one of our games using the JNLP Applet Loader (it will look exactly as any other game using LWJGL Applet Loder).

One disadvantage of using the JNLP Applet Loader is the extra time consumed to make the JNLP file request and to parse it vs just using the regular LWJGL Applet Loader. However, using the JNLP Applet Loader lets you to use one centralised JNLP file for all your game's launch configurations through different deployment options. Also, if you deploy your game in several portals like Games4j, GameJolt, your own page, etc, and you make a change of your game's launch configuration, your change is automatically replicated because all of them use the same configuration file.

Note that the project is highly coupled to LWJGL Applet Loader, it will not work for any Applet (it should be named something like JNLP Adapter for LWJGL Applet Loader).

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

LWJGL Applet Loader

In a previous post we talked about Java Games deployment options, in this post we want to talk about one custom solution provided by the LWJGL: the LWJGL Applet Loader.

The LWJGL Applet Loader is an Applet which performs a lot of common deployment tasks:

  • It shows a nice and customizable loading screen when deployment is being processed, with detailed messages for each task: downloading file.jar, extracting file.jar.gz, etc.
  • It downloads all required dependencies. If they are compressed using gzip, LZMA or Pack200, it extracts them.
  • It has a cache for all your dependencies so if one dependency is not modified on the server, then it is not downloaded again.
  • It configures the Java library path to load all your native dependencies.
  • Finally, it runs your game's applet.

A feature in mind when developing the LWJGL Applet Loader is that it should start as fast as possible, for that, the jar of the Applet Loader should be really small. The idea is to speed up all the Java loading screen so it can show quickly your custom loading screen.

It provides a lot of parameters in order to let you customize deployment stuff, like which natives dependencies you need for a specific platform, the logo and progress bar, etc. Full documentation of the parameters is on the API docs and you also have a great tutorial at LWJGL Wiki.

This is how it looks when loading an Applet using the LWJGL Applet Loader with the default loading screen:

note: Even without customization, it looks much nicer than Java default loading screen.


  • It lets you customize loading screen, and create Applet using natives support in an easy way.
  • It starts fast. This avoids some browser freeze bug when starting a Java Applet, like Firefox on Linux platforms.
  • It handles different compression options like gzip and LZMA, it also handles Pack200 jars.
  • It works on Mac OS, that is a big difference versus running New Generation Plug-In Java Applets, because they are disabled on Mac OS.
  • It is open source and the guys maintaining it are always open to receive patches and improvement ideas.


  • Pack200 and compression stuff is not done automatically, you have to specify exactly which file you want to download (example: you have to specify that you want to download somedependency.jar.pack.gz instead of having the Applet Loader to detect automatically which version to download by receiving the content encoding from the server).
  • Assumes you need native dependencies, so you need to fill some Applet parameters even if you don't need them. (we want to add an RFE for that)
  • It doesn't use the same cache other Java Applets or Java Web Start use. That means you have to download twice one Applet distributed using LWJGL Applet loader and Java Web Start, and it will cost you double space.

To see LWJGL Applet Loader working you can try one of our games here (warning: link could be broken in the future) or you can try a working and stable version of a game using LWJGL Applet Loader here, its name is Minecraft, don't know if you know about it.

In one of the next posts we want to talk in detail about another deployment option we mentioned before, now that we have some experience using it: getdown.


VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)