LibGDX and ScrollPane with multiple widgets - java

Trying to add multiple items to a scrollpane I quickly found that all "addActor" functions are Unsupported. So, I went with adding a table with all the items I wanted (this code misses a image that I still want to add) to make a scrollable credits screen... but this approach (currently) doesn't allow for overflow, rendering the ScrollPane useless. (My text is only shown up to what the screen's height allows, and isn't scrollable).
What's the way to make a scrollable pane with multiple widgets in LibGDX? (I only care about Android and Win/Lin/Mac platforms at the moment.
pane = new ScrollPane(null, skin);
pane.setFillParent(true);
paneContent = new Table(skin);
paneContent.setFillParent(true);
Label temp = new Label("", skin);
temp.setAlignment(Align.left, Align.center);
temp.setText( Gdx.files.internal("licenses/credits.txt").readString("UTF-8") );
paneContent.addActor(temp);
pane.setWidget(paneContent);
stage.addActor(pane);

If you want to put multiple items into the ScrollPane you simply need to put a table into it and call add() for each widget you want to put into the ScrollPane.
Below is an example of how to make your credits scrollable:
public class ScrollTest implements ApplicationListener {
private Stage stage;
private static final String reallyLongString = "This\nIs\nA\nReally\nLong\nString\nThat\nHas\nLots\nOf\nLines\nAnd\nRepeats.\n"
+ "This\nIs\nA\nReally\nLong\nString\nThat\nHas\nLots\nOf\nLines\nAnd\nRepeats.\n"
+ "This\nIs\nA\nReally\nLong\nString\nThat\nHas\nLots\nOf\nLines\nAnd\nRepeats.\n";
#Override public void create() {
this.stage = new Stage();
Gdx.input.setInputProcessor(this.stage);
final Skin skin = new Skin(Gdx.files.internal("skin/uiskin.json"));
final Label text = new Label(reallyLongString, skin);
text.setAlignment(Align.center);
text.setWrap(true);
final Label text2 = new Label("This is a short string!", skin);
text2.setAlignment(Align.center);
text2.setWrap(true);
final Label text3 = new Label(reallyLongString, skin);
text3.setAlignment(Align.center);
text3.setWrap(true);
final Table scrollTable = new Table();
scrollTable.add(text);
scrollTable.row();
scrollTable.add(text2);
scrollTable.row();
scrollTable.add(text3);
final ScrollPane scroller = new ScrollPane(scrollTable);
final Table table = new Table();
table.setFillParent(true);
table.add(scroller).fill().expand();
this.stage.addActor(table);
}
#Override public void render() {
this.stage.act();
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
this.stage.draw();
}
#Override public void resize(final int width, final int height) {}
#Override public void pause() {}
#Override public void resume() {}
#Override public void dispose() {}
}
Edit: Added code on setting up a table inside of a ScrollPane.

Related

Drawing multiple Tables with one Stage

One question currently I am working on a team size seletion screen, So far I did it with checkboxes for team one is finished. Now next to that I wanted to draw another table with the same stage, I don't want to draw with a new Stage in order to save ressources. So my question is it Possible to draw multible tables with one stage next to each other? This is what I currently tried but it didn't work.
So I tried to give a second Table to the constructor something like:
stage.addActor(table,table2)
which did not work.
My second try was something like
stage.addActor(table);
stage.addActor(table2);
which did not work either.
public class TeamSelectScreen implements Screen {
public SEPGame game;
public SpriteBatch menuBatch;
public AssetManager assetManager;
public Viewport viewport;
public Stage stage;
public MenuScreen menuScreen;
public ButtonGroup<CheckBox> teamSelect;
public CheckBox Tank1;
public CheckBox Tank2;
public CheckBox Tank3;
public CheckBox Tank4;
public CheckBox Tank5;
public TeamSelectScreen(SEPGame game) {
game = new SEPGame();
menuBatch = new SpriteBatch();
assetManager = new AssetManager();
viewport = new FitViewport(SEPGame.WORLD_PIXEL_WIDTH, SEPGame.WORLD_PIXEL_HEIGHT);
menuScreen = new MenuScreen(game);
menuScreen.dispose();
stage = new Stage(viewport, menuBatch);
Gdx.input.setInputProcessor(stage);
assetManager.load(Assetdescriptor.backGround);
assetManager.load(Assetdescriptor.buttonNotePressed);
assetManager.load(Assetdescriptor.buttonPressed);
assetManager.load(Assetdescriptor.skinUI);
assetManager.finishLoading();
}
public void setupScreen() {
TextureAtlas menuUi = assetManager.get(Assetdescriptor.backGround);
Skin uiSkin = assetManager.get(Assetdescriptor.skinUI);
TextureRegion backGroundRegion = menuUi.findRegion(Regionnames.backGround);
Table table = new Table();
Table table2 = new Table();
Label title = new Label("Team Auswahl", uiSkin);
Tank1 = new CheckBox("Tank 1 Player", uiSkin);
Tank2 = new CheckBox("Tank 2 Player", uiSkin);
Tank3 = new CheckBox("Tank 3 Ki", uiSkin);
Tank4 = new CheckBox("Tank 4 Ki", uiSkin);
Tank5 = new CheckBox("Tank 5 Ki", uiSkin);
ChangeListener teamSizeChanger = new ChangeListener() {
#Override
public void changed(ChangeEvent event, Actor actor) {
}
};
Tank1.addListener(teamSizeChanger);
Tank2.addListener(teamSizeChanger);
Tank3.addListener(teamSizeChanger);
Tank4.addListener(teamSizeChanger);
Tank5.addListener(teamSizeChanger);
Table checkTable = new Table();
checkTable.defaults().pad(5);
checkTable.add(Tank1).row();
checkTable.add(Tank2).row();
checkTable.add(Tank3).row();
checkTable.add(Tank4).row();
checkTable.add(Tank5).row();
Table checkTable2 = new Table();
Table checkTable3 = new Table();
Table checkTable4 = new Table();
Table checkTable5 = new Table();
// Team 1
table.add(checkTable);
table.padRight(1200);
table.setFillParent(true);
table.pack();
table.setBackground(new TextureRegionDrawable(backGroundRegion));
// Team 2
table2.add(checkTable2);
table2.padRight(1000);
table.setFillParent(true);
table.pack();
// Add 2 Tables?
stage.addActor(table);
stage.addActor(table2);
}
#Override
public void show() {
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
menuScreen.dispose();
setupScreen();
stage.draw();
}
}
You're calling table.setFillParent(true) twice but never table2.setFillParent(true).
Another option would be adding a Stack with fill parent to the stage and then adding the two tables to the stack:
Stack stack = Stack(table, table2)
stack.setFillParent(true)
stage.addActor(stack)

How to set image as background using JavaFX?

I'm trying to put an image as a background in a JavaFX scene, but my code isn't working.
Im trying to make a Battleship-game program in java eclipse but i'm stuck at a graphics problem.
public class WindowGUI extends Application{
Game game;
Image image;
public WindowGUI(Game game) {
this.game = game;
}
public static void main(String[] args) {
Game game = new Game();
new WindowGUI(game);
}
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Battleship");
image = new Image ("C:\\Users\\amali\\git\\inf101.v19.sem2\\inf101.v19.sem2\\src\\window\\battleshipbackground.jpg");
ImageView background = new ImageView(image);
Button startButton = new Button("START");
BorderPane newStack = new BorderPane();
newStack.getChildren().add(startButton);
newStack.getChildren().add(background);
stage.setScene(new Scene(newStack, 1300, 860));
stage.show();
startButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
// START THE GAME
}
});
}
}
When I first tried to run it, it worked and a new window opened with a button in the center, but the bakcground was blank. When i try setting an image as background in the window, behing the 'start'-button, nothing happens..
A better way to do it is to use the Background class rather than trying to add an ImageView as a child of your BorderPane.
Image image = new Image("C:\\Users\\amali\\git\\inf101.v19.sem2\\inf101.v19.sem2\\src\\window\\battleshipbackground.jpg");
BackgroundSize size = new BackgroundSize(BackgroundSize.AUTO,
BackgroundSize.AUTO,
false,
false,
true,
false);
Background background = new Background(new BackgroundImage(image,
BackgroundRepeat.NO_REPEAT,
BackgroundRepeat.NO_REPEAT,
BackgroundPosition.CENTER,
size));
newStack.setBackground(background);
Use BackgroundImage class.
or try this
JavaFX How to set scene background image

How to get contents to show up inside a ScrolledComposite

I am creating a legend view and inside the shell is supposed to have a rectangle followed by a label describing the color. I was able to get the view to work using just a normal composite but the legend continues beyond the screen and no way of see it without making the window larger. I am trying to use a scrolledComposite view for my shell but when I execute the program, nothing appears.
public void createPartControl(Composite parent)
{
display = parent.getDisplay();
parent.setLayout(new FillLayout());
sc = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
LegendView.composite = new Composite(sc, SWT.NONE);
RowLayout layout = new RowLayout();
layout.wrap = true;
layout.spacing = 5;
composite.setLayout(layout);
}
public static void addRectangle(String legendMessage)
{
final String propId = legendMessage;
final String[] s = propId.split(",");
if (display != null)
{
display.syncExec(new Runnable()
{
#Override
public void run()
{
// Creating the color using the RBG values
final Color color =
new Color(display, Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]));
// Creating a canvas for which the rectangle can be drawn on
Canvas canvas = new Canvas(composite, SWT.NONE);
// Maybe set the bounds of the canvas
canvas.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
e.gc.drawRectangle(1, 1, 50, 60);
e.gc.setBackground(color);
e.gc.fillRectangle(2, 2, 49, 59);
}
});
// Disposing the color after it has been used
canvas.addDisposeListener(new DisposeListener()
{
public void widgetDisposed(DisposeEvent e)
{
color.dispose();
}
});
// Creating a label and setting the font
Label label = new Label(composite, SWT.NULL);
Font boldFont = new Font( label.getDisplay(), new FontData( "Arial", 12, SWT.BOLD ) );
label.setFont( boldFont );
label.setText(s[3]);
composite.redraw();
composite.layout(true);
sc.setContent(composite);
}
});
}
}
I am calling add rectangle in a different class. I am fairly new at using SWT and after looking at examples and reading the docs for scrolled Composite, this is what I interpreted it as. Any help would be very appreciated.
You haven't told the ScrolledComposite how to manage the size. You must either call setSize or setMinSize. For this you probably want:
sc.setExpandHorizontal(true);
sc.setExpandVertical(true);
sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));

Libgdx: place 2 actors one on another

I use libgdx's scene2d built-in UI library to make an UI in my game. I'm interesting how can I draw 2 images(or actors) in a table one on another? I'm looking to the similar like LayerDrawable in Android. Is there any exists stuff to make it?
There is a Stack widget in libGDX UI library for these purposes.
UPDATE: if you want to place one widget on top of another widget and these widgets have different size then you should wrap the smaller widget. Something like:
//First add actual content
stack.add(content);
//Second add wrapped overlay object
Table overlay = new Table();
overlay.add(overlayWidget).expand().fillX().bottom().left();
stack.add(overlay);
stack variable is a Stack instance
It's an actual excerpt from my project. You should tune it for your case.
You can use somethings like this :
//create stage
stage = new Stage(new StretchViewport(game.width, game.height));
//create table
Table table = new Table();
table.setSize(game.width,game.height); //fullscreen
//add Image 1
table.add(new Image(game.skin.getDrawable("image1")));
//add Image 2 (create new col)
table.add(new Image(game.skin.getDrawable("image2"))).width(xx).height(xx);
//add new row
table.row();
//add Image 3 - padding to draw over image1/2 && colspan
table.add(new Image(game.skin.getDrawable("image3"))).width(xx).height(xx).padTop(-50f).colspan(2);
//add table to stage
stage.addActor(table);
/*
* Add action
*
*/
#Override
public void render(float delta) {
...
//don't forget to draw ur stage
stage.act(delta); // or stage.act(Gdx.graphics.getDeltaTime())
stage.draw();
}
Also you can add action to stage/table or image etc ... :
stage.addAction(Actions.sequence(
Actions.fadeOut(0.0001f),
Actions.fadeIn(0.5f),
Actions.delay(0.1f),
Actions.run(new Runnable() {
#Override
public void run() {
//mmmm new screen
dispose();
game.setScreen(new BoobsScreen(game));
}
})));
Of course you can draw more than image : button, textbutton, label etc or add scrollPane for Table but before take a look at Skin on libgdx
For exemple a programmatically ninepatch textbutton :
private NinePatch processNinePatchFile(String fname) {
final Texture t = new Texture(Gdx.files.internal(fname));
final int width = t.getWidth() - 2;
final int height = t.getHeight() - 2;
return new NinePatch(new TextureRegion(t, 1, 1, width, height), 3, 3, 3, 3);
}
//create skin
skin = new Skin();
...
//create font
...
//create ninepatch button from android/assets/style/button
NinePatch ninepatch = processNinePatchFile("style/button.9.png");
skin.add("button.9", ninepatch);
//create textbuttonstyle
TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle();
textButtonStyle.font = skin.getFont("font_black_38");
textButtonStyle.fontColor = Color.DARK_GRAY;
textButtonStyle.up = skin.getDrawable("button.9");
skin.add("buttonTextStyle", textButtonStyle);
//now you can create textbutton
TextButton btn = new TextButton("Hello", game.skin.get("buttonTextStyle", TextButton.TextButtonStyle.class));
//add a clicklistener
btn.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
//mmmmmm add action for exemple
stage.addAction(Actions.sequence(Actions.fadeOut(0.5f), Actions.run(new Runnable() {
#Override
public void run() {
//dispose and load screen
dispose();
game.setScreen(new MoreBoobsScreen(game));
}
})));
}
});
table.add(btn);
To create bitmapfont take a look at Gdx freetype, it's really easy to use.

How to dynamically show/hide GXT panels?

I'm creating ContentPanel and hide it:
final ContentPanel infoPanel = new ContentPanel();
final TabPanel infoTabPanel = new TabPanel();
...
//Adding TabItems with some forms
infoPanel.add(infoTabPanel);
infoPanel.hide();
add(infoPanel);
Then in some Event Listener I try to show this hidden panel:
infoPanel.show();
infoPanel.layout();
But this panel is shown without any data. Only if I click on tabs data appears.
So how to hide/show this panel correctly?
EDITED:
I'm using GXT 2.2.4.
I'm creating ContentPanel with TabPanel which contains FormPanel and hide ContentPanel.
Then in Event Listener I try to show this hidden panel, but it is shown without form. Only if I click on tabs form appears.
Here is code:
protected void onRender(Element parent, int pos) {
super.onRender(parent, pos);
final ContentPanel infoPanel = new ContentPanel();
infoPanel.setAutoHeight(true);
final TabPanel infoTabPanel = new TabPanel();
infoTabPanel.setAutoHeight(true);
final FormPanel testForm = new FormPanel();
FieldSet fieldSet = new FieldSet();
fieldSet.setHeading("Information");
FormLayout fLayout = new FormLayout();
fieldSet.setLayout(fLayout);
LabelField field1 = new LabelField();
LabelField field2 = new LabelField();
field1.setFieldLabel("Field1:");
field1.setName("field1");
fieldSet.add(field1);
field2.setFieldLabel("Field2:");
field2.setName("field2");
fieldSet.add(field2);
testForm.add(fieldSet);
TabItem formTab = new TabItem("Form Tab");
formTab.add(testForm);
infoTabPanel.add(formTab);
TabItem longText = new TabItem("Long Text");
longText.addStyleName("pad-text");
longText.addText("Long Text" + "<br>" + "Long TextLong Text");
infoTabPanel.add(longText);
infoPanel.add(infoTabPanel);
infoPanel.hide();
Button buttonShow = new Button("show");
buttonShow.addSelectionListener(new SelectionListener<ButtonEvent>() {
#Override
public void componentSelected(ButtonEvent ce) {
infoPanel.show();
}
});
Button buttonHide = new Button("hide");
buttonHide.addSelectionListener(new SelectionListener<ButtonEvent>() {
#Override
public void componentSelected(ButtonEvent ce) {
infoPanel.hide();
}
});
add(infoPanel);
add(buttonShow);
add(buttonHide);
}
Which GXT version do you have? I can't reproduce your problem on GXT 3.x. I wrote a little example code which does exactly what you're asking for.
public void onModuleLoad() {
final ContentPanel infoPanel = new ContentPanel();
final TabPanel infoTabPanel = new TabPanel();
infoTabPanel.add(new TextButton("moo"), "moo");
infoTabPanel.add(new TextButton("boo"), "boo");
infoPanel.add(infoTabPanel);
infoPanel.hide();
VerticalLayoutContainer vlc = new VerticalLayoutContainer();
vlc.setPixelSize(300, 250);
TextButton buttonShow = new TextButton("show");
buttonShow.addSelectHandler(new SelectHandler() {
#Override
public void onSelect(SelectEvent event) {
infoPanel.show();
}
});
TextButton buttonHide = new TextButton("hide");
buttonHide.addSelectHandler(new SelectHandler() {
#Override
public void onSelect(SelectEvent event) {
infoPanel.hide();
}
});
vlc.add(infoPanel, new VerticalLayoutData(1, 1));
vlc.add(buttonShow);
vlc.add(buttonHide);
RootPanel.get().add(vlc);
}
OK I see.
OK I see, since clicking on the tab makes it appear, why don't you programmatically select the tab in your listener?
infoTabPanel.setSelection(formTab);
http://dev.sencha.com/deploy/gxt-2.2.5/docs/api/com/extjs/gxt/ui/client/widget/TabPanel.html#setSelection(com.extjs.gxt.ui.client.widget.TabItem)
---------below didn't work------------
so try infoPanel.repaint();

Categories

Resources