Embedding a Libgdx window into a Java desktop application

Developing a medium-sized game takes an unholy amount of time. Logically, this makes your toolset a crucial factor because the tools' productivity and your mastery over them will dramatically affect the process. Most areas are already covered by brilliant tools: tiles for level editing, spine for skeletal animation, Physics Editor to create rigid bodies, the Libgdx particle editor, and the list goes on.

However, you might have certain requirements that no existing software features yet. Beware, the never reinvent the wheel advice is really good advice. Think about it; if the tool closest to what you need is open source, it is probably more convenient to check out the repository and add such a feature yourself. The community will probably be quite grateful for this and you will get public recognition!

Alright, if you really need something completely different, the best option can end up being implementing a new tool from scratch. This tool can typically have a bunch of UI controls (buttons, panels, tick boxes, sliders, and so on) and a previewer to see live results of our work. How can we code this?

In this recipe, we will learn how to embed a Libgdx canvas into a Swing application, which is the main Java GUI toolkit. As an example, we will create an application that lists all the samples in this book on the right and runs them on the left, without launching additional windows.

Note that this is not an introductory article about Swing; some previous knowledge on the matter is advisable.

Getting ready

This time, you only need to make sure that the sample projects are in your Eclipse workspace.

How to do it…

For obvious reasons, this exercise focuses exclusively on desktop platforms, so take a look at the code within the samples/desktop folder. More specifically, open up the SwingCanvasSample.java file.

SwingCanvasSample derives from JFrame, a top level Swing container. It also implements SampleLauncher, a custom utility interface to help us launch our samples. The LwjglAWTCanvas member is the entry point to our Libgdx application—it contains an OpenGL surface on an AWT Canvas. As you might suspect, an AWT Canvas is a component that can be added to a JFrame layout. SampleList is a custom JPanel containing a list with all the book samples and a button to launch them:

public class SwingCanvasSample extends JFrame implements SampleLauncher {
  LwjglAWTCanvas canvas;
  SampleList list;

…
}

In the constructor, we instantiate SampleList, passing the SampleLauncher implementation as a parameter, and we add it to the content pane on the left. We set the size of JFrame, make it visible and nonresizable, and then we set the title. Finally, we establish that System.exit(0) is called when the window is closed. The canvas will not be created until the Run Sample button is pressed (inside SampleList):

public SwingCanvasSample() {
  list = new SampleList(this);
  list.setSize(320, 540);

  Container container = getContentPane();
  container.add(list, BorderLayout.WEST);

  setSize(1280, 540);
  setVisible(true);
  setResizable(false);
  setTitle("Libgdx Game Development Cookbook Samples");

  addWindowListener(new WindowAdapter() {
    public void windowClosed (WindowEvent event) {
      System.exit(0);
    }
  });
}

The SampleLauncher interface declares the launchSample() method. It gets called whenever the user picks a sample from the left-hand side panel and clicks on Run Sample. What we need to do is remove the previous Libgdx sample using remove(), if it exists, and instantiate the new sample. GdxSamples is a static class that maps sample names to the ApplicationListener classes. Its newSample() method makes sure that the corresponding ApplicationListener is given a name that we can use to create a new LwjglAWTCanvas and embed into the content pane:

public boolean launchSample(String sampleName) {
  Container container = getContentPane();

  if (canvas != null) {
    container.remove(canvas.getCanvas());
  }

  ApplicationListener sample = GdxSamples.newSample(sampleName);

  canvas = new LwjglAWTCanvas(sample, true);
  canvas.getCanvas().setSize(960, 540);
  container.add(canvas.getCanvas(), BorderLayout.EAST);

  pack();

  return test != null;
}

The main method simply creates a new SwingCanvasSample:

public static void main (String[] args) {
  SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run () {
      new SwingCanvasSample();
    }
  });
}

With this method, you can easily embed as many Libgdx canvases as you wish into your Swing applications. The result for our sample is illustrated in the following figure:

How to do it…

How it works…

To put things into perspective, let's regress to the Understanding the project structure and application life cycle recipe, where we examined the Libgdx projects' architecture. Every supported platform had a backend that implemented the Application interface and a launcher to instantiate them passing through an ApplicationListener object.

In our current situation, LwglAWTCanvas is a different backend and our JFrame acts as the launcher. Do not trust these words; as an exercise, feel free to examine the Libgdx source code, and see for yourself how everything fits together nicely.

There's more…

An alternative to creating a tool with Swing and embedding a Libgdx canvas in it is to build a Libgdx-only application using its Scene2D UI API, which is easily extensible and feature rich. Spine, the popular skeletal animation editor, took this approach.

Like everything in life, both methods have their drawbacks. Using an OpenGL canvas in Swing reduces performance, though this might not be a deal breaker as per your requirements. On the other hand, the Libgdx Scene2D UI makes it a bit more difficult to design layouts.

See also

  • Move on to Chapter 8, User Interfaces with Scene2D, and its opening recipe, Introducing the Scene2D API, to find out more about alternatives to embedding Libgdx canvases into Swing applications for tool development.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.183.10