nifty_gui_java_layout.adoc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. = Laying Out the GUI in Java
  2. :author:
  3. :revnumber:
  4. :revdate: 2016/03/17 20:48
  5. :keywords: gui, documentation, nifty, hud
  6. :relfileprefix: ../../
  7. :imagesdir: ../..
  8. ifdef::env-github,env-browser[:outfilesuffix: .adoc]
  9. . <<jme3/advanced/nifty_gui#,Nifty GUI Concepts>>
  10. . <<jme3/advanced/nifty_gui_best_practices#,Nifty GUI Best Practices>>
  11. . <<jme3/advanced/nifty_gui_xml_layout#,Nifty GUI XML Layout>> or *Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ Java Layout*
  12. . <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> or <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>>
  13. . <<jme3/advanced/nifty_gui_java_interaction#,Interact with the GUI from Java>>
  14. *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).
  15. == Sample Code
  16. Sample project
  17. * *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/]. +
  18. * *Download demo project:* link:http://files.seapegasus.org/NiftyGuiDemo.zip[http://files.seapegasus.org/NiftyGuiDemo.zip] (jme3-ready) +
  19. The full demo ZIP is based on `de.lessvoid.nifty.examples.controls.ControlsDemo.java`.
  20. .. The demo is a SimpleApplication-based game (use e.g. the BasicGame template in the jMonkeyEngine SDK).
  21. .. 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/`).
  22. .. Make sure to use paths relative to your project's `assets/` directory.
  23. *** E.g. for .fnt/.png/.jpg files use `filename(“Interface/yang.png);` ( not `filename(“yang.png);`).
  24. *** E.g. for .wav/.ogg files use `filename(“Interface/sounds/gong.wav);` (not `filename(“sounds/gong.wav);`).
  25. 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.
  26. [source,java]
  27. ----
  28. package mygame;
  29. import com.jme3.app.SimpleApplication;
  30. import com.jme3.niftygui.NiftyJmeDisplay;
  31. import de.lessvoid.nifty.Nifty;
  32. import de.lessvoid.nifty.builder.ScreenBuilder;
  33. import de.lessvoid.nifty.builder.LayerBuilder;
  34. import de.lessvoid.nifty.builder.PanelBuilder;
  35. import de.lessvoid.nifty.controls.button.builder.ButtonBuilder;
  36. import de.lessvoid.nifty.screen.DefaultScreenController;
  37. /**
  38. * @author iamcreasy
  39. */
  40. public class Main extends SimpleApplication {
  41. public static void main(String[] args) {
  42. Main app = new Main();
  43. app.start();
  44. }
  45. @Override
  46. public void simpleInitApp() {
  47. NiftyJmeDisplay niftyDisplay = NiftyJmeDisplay.newNiftyJmeDisplay(
  48. assetManager, inputManager, audioRenderer, guiViewPort);
  49. Nifty nifty = niftyDisplay.getNifty();
  50. guiViewPort.addProcessor(niftyDisplay);
  51. flyCam.setDragToRotate(true);
  52. nifty.loadStyleFile("nifty-default-styles.xml");
  53. nifty.loadControlFile("nifty-default-controls.xml");
  54. // <screen>
  55. nifty.addScreen("Screen_ID", new ScreenBuilder("Hello Nifty Screen"){{
  56. controller(new DefaultScreenController()); // Screen properties
  57. // <layer>
  58. layer(new LayerBuilder("Layer_ID") {{
  59. childLayoutVertical(); // layer properties, add more...
  60. // <panel>
  61. panel(new PanelBuilder("Panel_ID") {{
  62. childLayoutCenter(); // panel properties, add more...
  63. // GUI elements
  64. control(new ButtonBuilder("Button_ID", "Hello Nifty"){{
  65. alignCenter();
  66. valignCenter();
  67. height("5%");
  68. width("15%");
  69. }});
  70. //.. add more GUI elements here
  71. }});
  72. // </panel>
  73. }});
  74. // </layer>
  75. }}.build(nifty));
  76. // </screen>
  77. nifty.gotoScreen("Screen_ID"); // start the screen
  78. }
  79. }
  80. ----
  81. == Implement Your GUI Layout
  82. image::jme3/advanced/gui-layout-draft.png[gui-layout-draft.png,with="",height="",align="right"]
  83. In this tutorial, you recreate the same screen as in the Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ XML example.
  84. 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).
  85. === Make Screens
  86. The following minimal Java file contains a start screen and a HUD screen. (Neither has been defined yet.)
  87. [source,java]
  88. ----
  89. nifty.addScreen("start", new ScreenBuilder("start"){{
  90. controller(new DefaultScreenController());
  91. // <!-- ... -->
  92. }}.build(nifty));
  93. nifty.addScreen("hud", new ScreenBuilder("hud"){{
  94. controller(new DefaultScreenController());
  95. // <!-- ... -->
  96. }}.build(nifty));
  97. ----
  98. Every Nifty +++<abbr title="Graphical User Interface">GUI</abbr>+++ must have a start screen. The others (in this example, the HUD screen) are optional.
  99. === Make Layers
  100. The following Java code shows how we add layers to the start screen and HUD screen:
  101. [source,java]
  102. ----
  103. nifty.addScreen("start", new ScreenBuilder("start"){{
  104. controller(new DefaultScreenController());
  105. // layer added
  106. layer(new LayerBuilder("background") {{
  107. childLayoutCenter();
  108. backgroundColor("#000f");
  109. // <!-- ... -->
  110. }});
  111. layer(new LayerBuilder("foreground") {{
  112. childLayoutVertical();
  113. backgroundColor("#0000");
  114. // <!-- ... -->
  115. }});
  116. // layer added
  117. }}.build(nifty));
  118. ----
  119. Repeat the same, but use
  120. [source]
  121. ----
  122. nifty.addScreen("hud", new ScreenBuilder("hud"){{
  123. ----
  124. for the HUD screen.
  125. 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.
  126. === Make Panels
  127. 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:
  128. [source,java]
  129. ----
  130. nifty.addScreen("start", new ScreenBuilder("start") {{
  131. controller(new DefaultScreenController());
  132. layer(new LayerBuilder("background") {{
  133. childLayoutCenter();
  134. backgroundColor("#000f");
  135. // <!-- ... -->
  136. }});
  137. layer(new LayerBuilder("foreground") {{
  138. childLayoutVertical();
  139. backgroundColor("#0000");
  140. // panel added
  141. panel(new PanelBuilder("panel_top") {{
  142. childLayoutCenter();
  143. alignCenter();
  144. backgroundColor("#f008");
  145. height("25%");
  146. width("75%");
  147. }});
  148. panel(new PanelBuilder("panel_mid") {{
  149. childLayoutCenter();
  150. alignCenter();
  151. backgroundColor("#0f08");
  152. height("50%");
  153. width("75%");
  154. }});
  155. panel(new PanelBuilder("panel_bottom") {{
  156. childLayoutHorizontal();
  157. alignCenter();
  158. backgroundColor("#00f8");
  159. height("25%");
  160. width("75%");
  161. panel(new PanelBuilder("panel_bottom_left") {{
  162. childLayoutCenter();
  163. valignCenter();
  164. backgroundColor("#44f8");
  165. height("50%");
  166. width("50%");
  167. }});
  168. panel(new PanelBuilder("panel_bottom_right") {{
  169. childLayoutCenter();
  170. valignCenter();
  171. backgroundColor("#88f8");
  172. height("50%");
  173. width("50%");
  174. }});
  175. }}); // panel added
  176. }});
  177. }}.build(nifty));
  178. ----
  179. The following panels go into in the `hud` screen:
  180. [source,Java]
  181. ----
  182. nifty.addScreen("hud", new ScreenBuilder("hud") {{
  183. controller(new DefaultScreenController());
  184. layer(new LayerBuilder("background") {{
  185. childLayoutCenter();
  186. backgroundColor("#000f");
  187. // <!-- ... -->
  188. }});
  189. layer(new LayerBuilder("foreground") {{
  190. childLayoutHorizontal();
  191. backgroundColor("#0000");
  192. // panel added
  193. panel(new PanelBuilder("panel_left") {{
  194. childLayoutVertical();
  195. backgroundColor("#0f08");
  196. height("100%");
  197. width("80%");
  198. // <!-- spacer -->
  199. }});
  200. panel(new PanelBuilder("panel_right") {{
  201. childLayoutVertical();
  202. backgroundColor("#00f8");
  203. height("100%");
  204. width("20%");
  205. panel(new PanelBuilder("panel_top_right1") {{
  206. childLayoutCenter();
  207. backgroundColor("#00f8");
  208. height("15%");
  209. width("100%");
  210. }});
  211. panel(new PanelBuilder("panel_top_right2") {{
  212. childLayoutCenter();
  213. backgroundColor("#44f8");
  214. height("15%");
  215. width("100%");
  216. }});
  217. panel(new PanelBuilder("panel_bot_right") {{
  218. childLayoutCenter();
  219. valignCenter();
  220. backgroundColor("#88f8");
  221. height("70%");
  222. width("100%");
  223. }});
  224. }}); // panel added
  225. }});
  226. }}.build(nifty));
  227. ----
  228. Try the sample. Remember to activate a screen using `nifty.gotoScreen(“start);` or `hud` respectively.
  229. The result should look as follows:
  230. image::jme3/advanced/nifty-gui-panels.png[nifty-gui-panels.png,with="",height="",align="center"]
  231. == Adding Content to Panels
  232. 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.
  233. === Add Images
  234. The start-background.png image is a fullscreen background picture. In the `start` screen, add the following image element:
  235. [source,java]
  236. ----
  237. nifty.addScreen("start", new ScreenBuilder("start") {{
  238. controller(new DefaultScreenController());
  239. layer(new LayerBuilder("background") {{
  240. childLayoutCenter();
  241. backgroundColor("#000f");
  242. // add image
  243. image(new ImageBuilder() {{
  244. filename("Interface/tutorial/start-background.png");
  245. }});
  246. }});
  247. ----
  248. The hud-frame.png image is a transparent frame that we use as HUD decoration. In the `hud` screen, add the following image element:
  249. [source,java]
  250. ----
  251. nifty.addScreen("hud", new ScreenBuilder("hud") {{
  252. controller(new DefaultScreenController());
  253. layer(new LayerBuilder("background") {{
  254. childLayoutCenter();
  255. backgroundColor("#000f");
  256. // add image
  257. image(new ImageBuilder() {{
  258. filename("Interface/tutorial/hud-frame.png");
  259. }});
  260. }});
  261. ----
  262. The face1.png image is an image that you want to use as a status icon.
  263. In the `hud` screen's `foreground` layer, add the following image element:
  264. [source,java]
  265. ----
  266. panel(new PanelBuilder("panel_top_right2") {{
  267. childLayoutCenter();
  268. backgroundColor("#44f8");
  269. height("15%");
  270. width("100%");
  271. // add image
  272. image(new ImageBuilder() {{
  273. filename("Interface/tutorial/face1.png");
  274. valignCenter();
  275. alignCenter();
  276. height("50%");
  277. width("30%");
  278. }});
  279. }});
  280. ----
  281. This image is scaled to use 50% of the height and 30% of the width of its container.
  282. === Add Static Text
  283. The game title is a typical example of static text. In the `start` screen, add the following text element:
  284. [source,java]
  285. ----
  286. // panel added
  287. panel(new PanelBuilder("panel_top") {{
  288. childLayoutCenter();
  289. alignCenter();
  290. backgroundColor("#f008");
  291. height("25%");
  292. width("75%");
  293. // add text
  294. text(new TextBuilder() {{
  295. text("My Cool Game");
  296. font("Interface/Fonts/Default.fnt");
  297. height("100%");
  298. width("100%");
  299. }});
  300. }});
  301. ----
  302. For longer pieces of static text, such as an introduction, you can use wrap=“true. Add the following text element to the `Start screen`:
  303. [source,java]
  304. ----
  305. panel(new PanelBuilder("panel_mid") {{
  306. childLayoutCenter();
  307. alignCenter();
  308. backgroundColor("#0f08");
  309. height("50%");
  310. width("75%");
  311. // add text
  312. text(new TextBuilder() {{
  313. text("Here goes some text describing the game and the rules and stuff. "+
  314. "Incidentally, the text is quite long and needs to wrap at the end of lines. ");
  315. font("Interface/Fonts/Default.fnt");
  316. wrap(true);
  317. height("100%");
  318. width("100%");
  319. }});
  320. }});
  321. ----
  322. 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.
  323. === Add Controls
  324. Before you can use any control, you must load a Control Definition first. Add the following two lines _before_ your screen definitions:
  325. [source,java]
  326. ----
  327. nifty.loadStyleFile("nifty-default-styles.xml");
  328. nifty.loadControlFile("nifty-default-controls.xml");
  329. ----
  330. ==== Label Control
  331. Use label controls for text that you want to edit dynamically from Java. One example for this is the score display.
  332. In the `hud` screen's `foreground` layer, add the following text element:
  333. [source,java]
  334. ----
  335. panel(new PanelBuilder("panel_top_right1") {{
  336. childLayoutCenter();
  337. backgroundColor("#00f8");
  338. height("15%");
  339. width("100%");
  340. control(new LabelBuilder(){{
  341. color("#000");
  342. text("123");
  343. width("100%");
  344. height("100%");
  345. }});
  346. ----
  347. 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).
  348. ==== Button Control
  349. 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 `&lt;control&gt;` element:
  350. [source,java]
  351. ----
  352. panel(new PanelBuilder("panel_bottom_left") {{
  353. childLayoutCenter();
  354. valignCenter();
  355. backgroundColor("#44f8");
  356. height("50%");
  357. width("50%");
  358. // add control
  359. control(new ButtonBuilder("StartButton", "Start") {{
  360. alignCenter();
  361. valignCenter();
  362. height("50%");
  363. width("50%");
  364. }});
  365. }});
  366. panel(new PanelBuilder("panel_bottom_right") {{
  367. childLayoutCenter();
  368. valignCenter();
  369. backgroundColor("#88f8");
  370. height("50%");
  371. width("50%");
  372. // add control
  373. control(new ButtonBuilder("QuitButton", "Quit") {{
  374. alignCenter();
  375. valignCenter();
  376. height("50%");
  377. width("50%");
  378. }});
  379. }});
  380. ----
  381. Note that these controls don't do anything yet – we'll get to that soon.
  382. ==== Other Controls
  383. 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.
  384. == Intermediate Result
  385. 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).
  386. *Tip:* Remove all lines that set background colors, you only needed them to see the arrangement.
  387. image::jme3/advanced/nifty-gui-simple-demo.png[nifty-gui-simple-demo.png,with="",height="",align="center"]
  388. == Nifty Java Settings
  389. Before initializing the nifty screens, you set up properties and register media.
  390. [cols="2", options="header"]
  391. |===
  392. a| Nifty Method
  393. a| Description
  394. a| registerSound(“mysound, “Interface/abc.wav);
  395. a|
  396. a| registerMusic(“mymusic, “Interface/xyz.ogg);
  397. a|
  398. a| registerMouseCursor(“mypointer, “Interface/abc.png, 5, 4);
  399. a|
  400. a| registerEffect(?);
  401. a| ?
  402. a| setDebugOptionPanelColors(true);
  403. a| Highlight all panels, makes it easier to arrange them.
  404. |===
  405. Example:
  406. [source,java]
  407. ----
  408. nifty.registerMouseCursor("hand", "Interface/mouse-cursor-hand.png", 5, 4);
  409. ----
  410. == Next Steps
  411. Integrate the +++<abbr title="Graphical User Interface">GUI</abbr>+++ into the game. Typically, you will overlay the +++<abbr title="Graphical User Interface">GUI</abbr>+++.
  412. * <<jme3/advanced/nifty_gui_overlay#,Nifty GUI Overlay>> (recommended)
  413. * <<jme3/advanced/nifty_gui_projection#,Nifty GUI Projection>> (optional)