| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610 |
- = Laying Out the GUI in Java
- :author:
- :revnumber:
- :revdate: 2016/03/17 20:48
- :keywords: gui, documentation, nifty, hud
- :relfileprefix: ../../
- :imagesdir: ../..
- ifdef::env-github,env-browser[:outfilesuffix: .adoc]
- . <<jme3/advanced/nifty_gui#,Nifty GUI Concepts>>
- . <<jme3/advanced/nifty_gui_best_practices#,Nifty GUI Best Practices>>
- . <<jme3/advanced/nifty_gui_xml_layout#,Nifty GUI XML Layout>> or *Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ Java Layout*
- . <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> or <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>>
- . <<jme3/advanced/nifty_gui_java_interaction#,Interact with the GUI from Java>>
- *Work in progress* You can “draw the +++<abbr title="Graphical User Interface">GUI</abbr>+++ to the screen by writing Java code – alternatively to using XML. Typically you lay out the static base +++<abbr title="Graphical User Interface">GUI</abbr>+++ in XML, and use Java commands if you need to change the +++<abbr title="Graphical User Interface">GUI</abbr>+++ dynamically at runtime. In theory, you can also lay out the whole +++<abbr title="Graphical User Interface">GUI</abbr>+++ in Java (but we don't cover that here).
- == Sample Code
- Sample project
- * *Original Source Code:* link:http://nifty-gui.svn.sourceforge.net/viewvc/nifty-gui/nifty-default-controls-examples/trunk/src/main/java/de/lessvoid/nifty/examples/[/nifty-default-controls-examples/trunk/src/main/java/de/lessvoid/nifty/examples/]. +
- * *Download demo project:* link:http://files.seapegasus.org/NiftyGuiDemo.zip[http://files.seapegasus.org/NiftyGuiDemo.zip] (jme3-ready) +
- The full demo ZIP is based on `de.lessvoid.nifty.examples.controls.ControlsDemo.java`.
- .. The demo is a SimpleApplication-based game (use e.g. the BasicGame template in the jMonkeyEngine SDK).
- .. Copy images and sound files into your project's `assets/Interface/` directory. (In this example, I copied them from `nifty-default-controls-examples/trunk/src/main/resources/` to `assets/Interface/`).
- .. Make sure to use paths relative to your project's `assets/` directory.
- *** E.g. for .fnt/.png/.jpg files use `filename(“Interface/yang.png);` ( not `filename(“yang.png);`).
- *** E.g. for .wav/.ogg files use `filename(“Interface/sounds/gong.wav);` (not `filename(“sounds/gong.wav);`).
- Just so you get a quick picture what Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++'s Java Syntax looks like, here is the most basic example. It creates a screen with a layer and a panel that contains a button.
- [source,java]
- ----
- package mygame;
-
- import com.jme3.app.SimpleApplication;
- import com.jme3.niftygui.NiftyJmeDisplay;
- import de.lessvoid.nifty.Nifty;
- import de.lessvoid.nifty.builder.ScreenBuilder;
- import de.lessvoid.nifty.builder.LayerBuilder;
- import de.lessvoid.nifty.builder.PanelBuilder;
- import de.lessvoid.nifty.controls.button.builder.ButtonBuilder;
- import de.lessvoid.nifty.screen.DefaultScreenController;
- /**
- * @author iamcreasy
- */
- public class Main extends SimpleApplication {
-
- public static void main(String[] args) {
- Main app = new Main();
- app.start();
- }
-
- @Override
- public void simpleInitApp() {
- NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
- assetManager, inputManager, audioRenderer, guiViewPort);
- Nifty nifty = niftyDisplay.getNifty();
- guiViewPort.addProcessor(niftyDisplay);
- flyCam.setDragToRotate(true);
-
- nifty.loadStyleFile("nifty-default-styles.xml");
- nifty.loadControlFile("nifty-default-controls.xml");
-
- // <screen>
- nifty.addScreen("Screen_ID", new ScreenBuilder("Hello Nifty Screen"){{
- controller(new DefaultScreenController()); // Screen properties
-
- // <layer>
- layer(new LayerBuilder("Layer_ID") {{
- childLayoutVertical(); // layer properties, add more...
-
- // <panel>
- panel(new PanelBuilder("Panel_ID") {{
- childLayoutCenter(); // panel properties, add more...
-
- // GUI elements
- control(new ButtonBuilder("Button_ID", "Hello Nifty"){{
- alignCenter();
- valignCenter();
- height("5%");
- width("15%");
- }});
-
- //.. add more GUI elements here
-
- }});
- // </panel>
- }});
- // </layer>
- }}.build(nifty));
- // </screen>
-
- nifty.gotoScreen("Screen_ID"); // start the screen
- }
- }
- ----
- == Implement Your GUI Layout
- image::jme3/advanced/gui-layout-draft.png[gui-layout-draft.png,with="",height="",align="right"]
- In this tutorial, you recreate the same screen as in the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ XML example.
- Create an Screen.Java file in the `assets/Interfaces/` directory of your project. One Java file can contain several, or even all screens. As a reminder: Nifty displays one screen at a time; a screen contains several layers on top of one another; each layer contains panels that are embedded into another; the panels contain the actual content (text, images, or controls).
- === Make Screens
- The following minimal Java file contains a start screen and a HUD screen. (Neither has been defined yet.)
- [source,java]
- ----
- nifty.addScreen("start", new ScreenBuilder("start"){{
- controller(new DefaultScreenController());
- // <!-- ... -->
- }}.build(nifty));
-
- nifty.addScreen("hud", new ScreenBuilder("hud"){{
- controller(new DefaultScreenController());
- // <!-- ... -->
- }}.build(nifty));
- ----
- Every Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ must have a start screen. The others (in this example, the HUD screen) are optional.
- === Make Layers
- The following Java code shows how we add layers to the start screen and HUD screen:
- [source,java]
- ----
- nifty.addScreen("start", new ScreenBuilder("start"){{
- controller(new DefaultScreenController());
-
- // layer added
- layer(new LayerBuilder("background") {{
- childLayoutCenter();
- backgroundColor("#000f");
-
- // <!-- ... -->
- }});
-
- layer(new LayerBuilder("foreground") {{
- childLayoutVertical();
- backgroundColor("#0000");
-
- // <!-- ... -->
- }});
- // layer added
-
- }}.build(nifty));
- ----
- Repeat the same, but use
- [source]
- ----
- nifty.addScreen("hud", new ScreenBuilder("hud"){{
- ----
- for the HUD screen.
- In a layer, you can now add panels and arrange them. Panels are containers that mark the areas where you want to display text, images, or controls (buttons etc) later.
- === Make Panels
- A panel is the inner-most container (that will contain the actual content: text, images, or controls). You place panels inside layers. The following panels go into in the `start` screen:
- [source,java]
- ----
- nifty.addScreen("start", new ScreenBuilder("start") {{
- controller(new DefaultScreenController());
- layer(new LayerBuilder("background") {{
- childLayoutCenter();
- backgroundColor("#000f");
- // <!-- ... -->
- }});
- layer(new LayerBuilder("foreground") {{
- childLayoutVertical();
- backgroundColor("#0000");
-
- // panel added
- panel(new PanelBuilder("panel_top") {{
- childLayoutCenter();
- alignCenter();
- backgroundColor("#f008");
- height("25%");
- width("75%");
- }});
- panel(new PanelBuilder("panel_mid") {{
- childLayoutCenter();
- alignCenter();
- backgroundColor("#0f08");
- height("50%");
- width("75%");
- }});
- panel(new PanelBuilder("panel_bottom") {{
- childLayoutHorizontal();
- alignCenter();
- backgroundColor("#00f8");
- height("25%");
- width("75%");
- panel(new PanelBuilder("panel_bottom_left") {{
- childLayoutCenter();
- valignCenter();
- backgroundColor("#44f8");
- height("50%");
- width("50%");
- }});
- panel(new PanelBuilder("panel_bottom_right") {{
- childLayoutCenter();
- valignCenter();
- backgroundColor("#88f8");
- height("50%");
- width("50%");
- }});
- }}); // panel added
- }});
- }}.build(nifty));
- ----
- The following panels go into in the `hud` screen:
- [source,Java]
- ----
- nifty.addScreen("hud", new ScreenBuilder("hud") {{
- controller(new DefaultScreenController());
- layer(new LayerBuilder("background") {{
- childLayoutCenter();
- backgroundColor("#000f");
- // <!-- ... -->
- }});
- layer(new LayerBuilder("foreground") {{
- childLayoutHorizontal();
- backgroundColor("#0000");
- // panel added
- panel(new PanelBuilder("panel_left") {{
- childLayoutVertical();
- backgroundColor("#0f08");
- height("100%");
- width("80%");
- // <!-- spacer -->
- }});
- panel(new PanelBuilder("panel_right") {{
- childLayoutVertical();
- backgroundColor("#00f8");
- height("100%");
- width("20%");
- panel(new PanelBuilder("panel_top_right1") {{
- childLayoutCenter();
- backgroundColor("#00f8");
- height("15%");
- width("100%");
- }});
- panel(new PanelBuilder("panel_top_right2") {{
- childLayoutCenter();
- backgroundColor("#44f8");
- height("15%");
- width("100%");
- }});
- panel(new PanelBuilder("panel_bot_right") {{
- childLayoutCenter();
- valignCenter();
- backgroundColor("#88f8");
- height("70%");
- width("100%");
- }});
- }}); // panel added
- }});
- }}.build(nifty));
- ----
- Try the sample. Remember to activate a screen using `nifty.gotoScreen(“start);` or `hud` respectively.
- The result should look as follows:
- image::jme3/advanced/nifty-gui-panels.png[nifty-gui-panels.png,with="",height="",align="center"]
- == Adding Content to Panels
- See also link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Layout_Introduction[Layout Introduction] on the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ site.
- === Add Images
- The start-background.png image is a fullscreen background picture. In the `start` screen, add the following image element:
- [source,java]
- ----
- nifty.addScreen("start", new ScreenBuilder("start") {{
- controller(new DefaultScreenController());
- layer(new LayerBuilder("background") {{
- childLayoutCenter();
- backgroundColor("#000f");
-
- // add image
- image(new ImageBuilder() {{
- filename("Interface/tutorial/start-background.png");
- }});
- }});
- ----
- The hud-frame.png image is a transparent frame that we use as HUD decoration. In the `hud` screen, add the following image element:
- [source,java]
- ----
- nifty.addScreen("hud", new ScreenBuilder("hud") {{
- controller(new DefaultScreenController());
- layer(new LayerBuilder("background") {{
- childLayoutCenter();
- backgroundColor("#000f");
-
- // add image
- image(new ImageBuilder() {{
- filename("Interface/tutorial/hud-frame.png");
- }});
- }});
- ----
- The face1.png image is an image that you want to use as a status icon.
- In the `hud` screen's `foreground` layer, add the following image element:
- [source,java]
- ----
- panel(new PanelBuilder("panel_top_right2") {{
- childLayoutCenter();
- backgroundColor("#44f8");
- height("15%");
- width("100%");
-
- // add image
- image(new ImageBuilder() {{
- filename("Interface/tutorial/face1.png");
- valignCenter();
- alignCenter();
- height("50%");
- width("30%");
- }});
-
- }});
- ----
- This image is scaled to use 50% of the height and 30% of the width of its container.
- === Add Static Text
- The game title is a typical example of static text. In the `start` screen, add the following text element:
- [source,java]
- ----
- // panel added
- panel(new PanelBuilder("panel_top") {{
- childLayoutCenter();
- alignCenter();
- backgroundColor("#f008");
- height("25%");
- width("75%");
-
- // add text
- text(new TextBuilder() {{
- text("My Cool Game");
- font("Interface/Fonts/Default.fnt");
- height("100%");
- width("100%");
- }});
-
- }});
- ----
- For longer pieces of static text, such as an introduction, you can use wrap=“true. Add the following text element to the `Start screen`:
- [source,java]
- ----
- panel(new PanelBuilder("panel_mid") {{
- childLayoutCenter();
- alignCenter();
- backgroundColor("#0f08");
- height("50%");
- width("75%");
- // add text
- text(new TextBuilder() {{
- text("Here goes some text describing the game and the rules and stuff. "+
- "Incidentally, the text is quite long and needs to wrap at the end of lines. ");
- font("Interface/Fonts/Default.fnt");
- wrap(true);
- height("100%");
- width("100%");
- }});
- }});
- ----
- The font used is jME3's default font “Interface/Fonts/Default.fnt which is included in the jMonkeyEngine.JAR. You can add your own fonts to your own `assets/Interface` directory.
- === Add Controls
- Before you can use any control, you must load a Control Definition first. Add the following two lines _before_ your screen definitions:
- [source,java]
- ----
- nifty.loadStyleFile("nifty-default-styles.xml");
- nifty.loadControlFile("nifty-default-controls.xml");
- ----
- ==== Label Control
- Use label controls for text that you want to edit dynamically from Java. One example for this is the score display.
- In the `hud` screen's `foreground` layer, add the following text element:
- [source,java]
- ----
- panel(new PanelBuilder("panel_top_right1") {{
- childLayoutCenter();
- backgroundColor("#00f8");
- height("15%");
- width("100%");
-
- control(new LabelBuilder(){{
- color("#000");
- text("123");
- width("100%");
- height("100%");
- }});
- ----
- Note that the width and height do not scale the bitmap font, but make indirectly certain it is centered. If you want a different size for the font, you need to provide an extra bitmap font (they come with fixes sizes and don't scale well).
- ==== Button Control
- Our +++<abbr title="Graphical User Interface">GUI</abbr>+++ plan asks for two buttons on the start screen. You add the Start and Quit buttons to the bottom panel of the `start` screen using the `<control>` element:
- [source,java]
- ----
- panel(new PanelBuilder("panel_bottom_left") {{
- childLayoutCenter();
- valignCenter();
- backgroundColor("#44f8");
- height("50%");
- width("50%");
-
- // add control
- control(new ButtonBuilder("StartButton", "Start") {{
- alignCenter();
- valignCenter();
- height("50%");
- width("50%");
- }});
-
- }});
- panel(new PanelBuilder("panel_bottom_right") {{
- childLayoutCenter();
- valignCenter();
- backgroundColor("#88f8");
- height("50%");
- width("50%");
- // add control
- control(new ButtonBuilder("QuitButton", "Quit") {{
- alignCenter();
- valignCenter();
- height("50%");
- width("50%");
- }});
- }});
- ----
- Note that these controls don't do anything yet – we'll get to that soon.
- ==== Other Controls
- Nifty additionally offers many customizable controls such as check boxes, text fields, menus, chats, tabs, … See also link:http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Elements[Elements] on the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ site.
- == Intermediate Result
- When you preview this code in the jMonkeyEngine SDK, our tutorial demo should looks as follows: A start screen with two buttons, and a game screen with a simple HUD frame and a blue cube (which stands for any jME3 game content).
- *Tip:* Remove all lines that set background colors, you only needed them to see the arrangement.
- image::jme3/advanced/nifty-gui-simple-demo.png[nifty-gui-simple-demo.png,with="",height="",align="center"]
- == Nifty Java Settings
- Before initializing the nifty screens, you set up properties and register media.
- [cols="2", options="header"]
- |===
- a| Nifty Method
- a| Description
- a| registerSound(“mysound, “Interface/abc.wav);
- a|
- a| registerMusic(“mymusic, “Interface/xyz.ogg);
- a|
- a| registerMouseCursor(“mypointer, “Interface/abc.png, 5, 4);
- a|
- a| registerEffect(?);
- a| ?
- a| setDebugOptionPanelColors(true);
- a| Highlight all panels, makes it easier to arrange them.
- |===
- Example:
- [source,java]
- ----
- nifty.registerMouseCursor("hand", "Interface/mouse-cursor-hand.png", 5, 4);
- ----
- == Next Steps
- Integrate the +++<abbr title="Graphical User Interface">GUI</abbr>+++ into the game. Typically, you will overlay the +++<abbr title="Graphical User Interface">GUI</abbr>+++.
- * <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> (recommended)
- * <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>> (optional)
|