Understanding further with the libGDX library, I got to the com.badlogic.gdx.scenes.scene2d.ui package. This package is designed to create a user interface. And here I was disappointed: there are no tutorial articles. Therefore, I decided to independently deal with the package using the source code and the Javadoc documentation. That is, it will be a tutorial on scene2d.ui, but not a translation. I will not describe here in detail the constructors, methods, give detailed signatures. I will try to look from a bird's eye view, because knowing the principles, you can always learn more from the documentation. But even with this approach, there is too much material, so I will break it into two (maybe more) articles.
Recall the previous article and what we talked about the class Stage. The Stage class can contain actors (Actor) and manage them. Also, there is a class Group, which is both an actor and a container for an actor. So, all the visual components from the scene2d.ua package are inherited from either Actor or Group. Accordingly, the heirs of the Group may contain other components. We will consider these components later, and now we will look at Actor’s heirs. The direct inheritor is the Widget class, and the following six components will be inherited from it: Label, TextField, Image, List, SelectBox, Slider.
It should be noted that all visual components implement the Layout interface. This interface is needed to properly locate components in container components. It provides methods for redrawing a component, determining the preferred, minimum, maximum size.
Another important concept is style. Inside, almost every graphic component has a static class called <Name of Component> Style. For example, LabelStyle. This class stores the necessary resources for the correct operation of this class - for example, the font, font color, etc. The fact is that OpenGL cannot directly draw fonts, so some additional mechanisms are needed. The obvious option is to create a picture with images of letters and a text file that describes where the letter is located. Then from this description you can make a class that can "build" lines of text from individual letters-pictures. Here is an example of the LabelStyle class from the Label class:
')
static public class LabelStyle { public BitmapFont font; public Color fontColor; public LabelStyle () { } public LabelStyle (BitmapFont font, Color fontColor) { this.font = font; this.fontColor = fontColor; } }
Some fields are marked with a comment as optional. This means that they can not be described in the style description in the settings file.
To store styles, the Skin class is used. The Skin class reads styles from a file from settings and saves them within itself. Then, when creating a new graphical component, we pass Skin on it to the designer. If there is a suitable style, it is used. If not, an exception is thrown. Here is an example of a simple settings class where a style is defined for only one component - Label:
{ resources: { com.badlogic.gdx.graphics.Color: { black: { r: 0, g: 0, b: 0, a: 1 } }, com.badlogic.gdx.graphics.g2d.BitmapFont: { default-font: { file: default.fnt } } }, styles: { com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: { default: { font: default-font, fontColor: black } } } }
Some comments. This file is written in JSON format. The first section is resources. black is the color defined in the RGBA model. default-font is the name of the font. I took the font from the com.badlogic.utils package, where they were called arial-15.fnt and arial-15.png. The second section is styles directly. Here we have identified one font, which indicated the font and font color. Note that the field names in the file correspond to the names of the public fields in the style classes. You can define for each component several styles with different names. You can get the desired style using the Skin class getStyle (Class type, String name) method. By default, you pass the Skin component into the constructor and from there the component takes the style named default.
For the settings file, it is necessary that in the same directory lay the same-name picture file, but with the png extension. If, for example, you named the settings file SimpleSkin, then the graphic file will be called SimpleSkin.png. It is necessary if you use resources like TextureRegion. Without this file, the program will throw an exception and will not start.
It should be noted that there are no Russian letters in this font file. I have not yet understood in detail this issue, so the Russian text in the examples will not be.
We now turn in more detail to the individual components, their styles and uses.
Label
It is a simple text label with the ability to transfer text by words. It has several designers, the most important, in my opinion, the following two:
public Label (Skin skin)
- creates a label without text.
public Label (String text, Skin skin)
- creates a label with the text.
There are methods for setting and returning a style — setStyle (), getStyle (), a method for setting text setText (), and a method for setting text wrapping according to setWrapt (). By default, word wrap is disabled. To use it, pre-set the preferred size of the label (preferred size).
Otherwise, the properties of the component are not of particular interest, control of its location, rotation, etc. implemented in the same way as the Actor class.
Component style class As you can see, he only needs the font and color of the font.
... static public class LabelStyle { public BitmapFont font; public Color fontColor; public LabelStyle () { } public LabelStyle (BitmapFont font, Color fontColor) { this.font = font; this.fontColor = fontColor; } } ...
Resources corresponding to this class from the settings file:
resources: { com.badlogic.gdx.graphics.Color: { black: { r: 0, g: 0, b: 0, a: 1 } }, com.badlogic.gdx.graphics.g2d.BitmapFont: { default-font: { file: default.fnt } } }, styles: { com.badlogic.gdx.scenes.scene2d.ui.Label$LabelStyle: { default: { font: default-font, fontColor: black } } }
Example of use:
... Skin skin = new Skin(Gdx.files.internal("data/skins/SimpleSkin")); Label label = new Label("I am label", skin); label.x = 10; label.y = 10; stage.add(label); ...
Textfield
The next class is TextField. It is a text entry box. This class is already curious, since you can assign it a listener. The libGDX library was written using the “subscribers-readers” pattern, but limited — you can install only one listener. The listener is installed using the setTextFieldListener () method, which accepts a parameter of type TextFieldListener. This is the interface, here is its code:
... static public interface TextFieldListener { public void keyTyped (TextField textField, char key); } ...
As you can see, one event is being processed - the symbol is entered.
The class has several constructors. We describe two main, in my opinion:
TextField(String text, Skin skin)
- creates a text field with text
TextField(Skin skin)
- creates an empty text field
Some class methods:
setText()
- sets the text
setPasswordMode()
- instead of the text, the characters that you select using the setPasswordCharacter () method will be displayed
setMessageText()
- sets a hint text that will be displayed if you have not entered anything in the text field.
TextField supports copying and pasting text on a PC with standard keys. On Android, copying and pasting is not supported due to Android limitations.
Component style class As you can see, the only required parameter is the font:
... static public class TextFieldStyle { public NinePatch background, cursor; public BitmapFont font; public Color fontColor; public TextureRegion selection; public BitmapFont messageFont; public Color messageFontColor; ...
Resources from the settings file:
... com.badlogic.gdx.scenes.scene2d.ui.TextField$TextFieldStyle: { default: { font: default-font, fontColor: black } } ...
And an example of use:
... TextField textField = new TextField("I am text field", skin); textField.y = 30; stage.addActor(textField); ...
Image
The Image class is one of the few who does not require style for their work. Therefore, its description will be quite brief. You can create an object of this class with several constructors, one of the most simple is Image (TextureRegion region). The class supports ClickListener listeners. Here is the source of this interface:
... public interface ClickListener { public void click (Actor actor, float x, float y); } ...
That is, we can handle click events on our image.
A useful method is setRegion (), which allows you to change the image. You can give the designer both a texture and its region. However, scaling, rotation will work only in the case of a region of the texture.
Example of use:
... Image image = new Image(new Texture(Gdx.files.internal("data/skins/default.png"))); image.y = 100; stage.addActor(image); ...
Here, texture is used as a parameter for the constructor. In real applications it is better to use TextureRegion.
List
The List class is a list of text fields with the ability to select a specific field. Analogue List Swing, or ListBox from Delphi.
Traditionally, it has several constructors, one of the most simple is List (Object [] items, Skin skin). It creates an object from the list from the items array. You can get the selected item using the getSelection () method, and its index is getSelectedIndex (). You can set a new list with the setItems () method, you can make a selected item either by name or by index: setSelection (), setSelectionIndex (). List supports the SelectionListener listener. Class source:
... public interface SelectionListener { public void selected (Actor actor, int index, String value); } ...
The selected () method is called when an item is selected.
Here is the style class:
... static public class ListStyle { public BitmapFont font; public Color fontColorSelected = new Color(1, 1, 1, 1); public Color fontColorUnselected = new Color(1, 1, 1, 1); public NinePatch selectedPatch; ...
As we can see, the colors are already initialized, but the font and selectedPatch will have to be described. A small digression about NinePatch. This is a regular image (.png), in which the edges of 1 pixel size contain some service information. This image is used for the selected item. For more details, you can read here
habrahabr.ru/post/113623 Here are excerpts from the settings file that are responsible for our List:
... com.badlogic.gdx.graphics.g2d.NinePatch: { default-nine : [ {width: 100, height: 100, x: 0, y: 0} ] } ... com.badlogic.gdx.scenes.scene2d.ui.List$ListStyle: { default: { font: default-font, selectedPatch: default-nine } } ...
Here is an example of use:
... List list = new List(new String[] {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"}, skin); list.x = 300; stage.addActor(list); ...
Selectbox
The SelectBox class is a drop-down list of several items. In the inactive state, this is the line that shows the selected item. When we activate it, we are shown a list of items that can be selected by pressing. It has several constructors, the simplest one - SelectBox (Object [] items, Skin skin) - creates a drop-down list of items. The first item is considered selected. The rest of the class is very similar to the List. It supports the same listeners as List - SelectionListener, has the same methods for manipulating list items. Here is the style class:
... static public class SelectBoxStyle { public NinePatch background; public NinePatch listBackground; public NinePatch listSelection; public BitmapFont font; public Color fontColor = new Color(1, 1, 1, 1); public float itemSpacing = 10; ...
As we see, three NinePatchs and a font need mandatory initialization.
Here are the excerpts from the settings file:
... com.badlogic.gdx.scenes.scene2d.ui.SelectBox$SelectBoxStyle: { default: { font: default-font, background: default-nine, listBackground: default-nine, listSelection: default-nine } } ...
Example of use:
... SelectBox selectBox = new SelectBox(new String[] {"Item 1", "Item 2", "Item 3"}, skin); selectBox.x = 400; stage.addActor(selectBox); ...
Slider
The last class is a successor to Widget. The Slider class is a slider with maximum and minimum values. The user can change the value of the slider by dragging. The class has several constructors with the task of maximum, minimum values, number of steps. The simplest is Slider (Skin skin). It will create a slider with a maximum value of 100 and a minimum of 0 with a number of gradations of 100. The class can handle value change events using the ValueChangedListener class:
... static public interface ValueChangedListener { public void changed (Slider slider, float value); } ...
When you change the value of the slider, the called () method is called.
The style class requires two parameters:
... static public class SliderStyle { NinePatch slider;
Here are the code snippets from the settings file:
... com.badlogic.gdx.graphics.g2d.TextureRegion: { default-region: {width: 10, height: 12, x: 0, y: 0} } ... com.badlogic.gdx.scenes.scene2d.ui.Slider$SliderStyle: { default: { slider: default-nine, knob: default-region } } ...
Here is an example of use:
... Slider slider = new Slider(skin); stage.addActor(slider); ...
The first part of the review of the scene2d.ui package is complete. Let me remind you that we have considered only those classes that are inherited from Widget. More than half of the container classes remain - windows, lists, scrolling lists, panels, etc. These include the Button button. As soon as there is time, I will write a sequel, where I will consider the other classes.
Appendix: a
project with a demonstration of opportunities.Appendix:
class diagram, compiled by me in the program ArgoUML.