Libgdx Can you set the bounds of a ScrollPane? - libgdx

So recently i discovered Scrollpanes and have been trying implement one properly.
After a bit of searching i found this section of code
public void create() {
batch = new SpriteBatch();
skin = new Skin(Gdx.files.internal("data/uiskin.json"));
stage = new Stage();
gamelog = new Label("Start", skin);
gamelog.setAlignment(Align.center);
gamelog.setWrap(true);
Table scrollTable = new Table();
scrollTable.add(gamelog);
scrollTable.row();
scroller = new ScrollPane(scrollTable);
Table table = new Table();
table.setFillParent(true);
table.add(scroller).fill().expand();
Now for the most part this code works well. a scrollpane is actually created and i can dynamically add text to it. my issue however is the size of the scrollpane takes up the whole screen, and initial text is centered in the middle of the scrollpane(so in the middle of the screen) and only starts to scroll once enough text has been added to take up the whole height of the screen.
Rather than expanding on its own what i actually want is for the scrollpane to take up just a small section at the bottom of the screen.
I have tried setting the bounds of the tables and of the scrollpane but the closest i have come is merely moving the scrollpane downwards(meaning the last text added is off screen and not in view. Its s if it completely ignores any width or height set and just expands on its own.
I figure i could get the desired effect by simply using a set of labels at the bottom of the screen and change their text dynamically but then the scroll feature would be lost. so before i do this i was hoping someone could shed some light on wether or not it is possible to resize and set a scrollpanes bounds?

Table uses cells to size its components. When you add a component to a table it returns the table's cell which holds that component. You can then use the cell to set the size of the component.
In your original code try this:
table.add(scroller).size(460, 200);
And if you want to change the scrollpane size after adding it to the table, you can get the cell from the table and then set its size like this:
table.add(scroller);
...
table.getCell(scroller).size(460, 200);
And here is the API for Cell:
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Cell.html

I stumbled across a solution with trial and error.
the following code works for me and allows the scrollpane to be resized and positioned. The main culprit seems to be the use of table.setFillParent(true); and the order in which you try to set the parent tables bounds.
batch = new SpriteBatch();
skin = new Skin(Gdx.files.internal("data/uiskin.json"));
stage = new Stage();
gamelog = new Label("Start", skin);
gamelog.setAlignment(Align.center);
gamelog.setWrap(true);
Table scrollTable = new Table();
scrollTable.add(gamelog);
scrollTable.row();
scroller = new ScrollPane(scrollTable);
Table table = new Table();
table.setBounds(10, 10, 460, 200);
table.add(scroller).fill().expand();
scrollTable.debug();
scroller.debug();
table.debug();
stage.addActor(table);

Related

Libgdx Table Layout Logical table not Positioning Correctly

I wants to store a scrollpane in a table. However, the positioning of the images are not as expected.
I have look through this, but has no clue on solving my problem.
The blue box (logical table) of the scrollpane and scrolldetails table is not at the right position. Please help.
My codes goes as below:
scrollDetails = new Table();
scrollDetails.setBackground(skin.getDrawable("gameSelectionBox1"));
scrollDetails.setDebug(true);
Button b = new Button(skin,"arithmetic");
scrollDetails.add(b);
scrollDetails.pack();
sp = new ScrollPane(scrollDetails);
sp.setOverscroll(false,true);
sp.pack();
sp.setDebug(true);
table = new Table();
table.setFillParent(true);
table.bottom().padBottom(100).add(sp).align(Align.center);
table.setDebug(true);
table.pack();
//tried but has no effect
//t.setPosition(0,100);
//sp.setPosition(0,550);
//tt.setPosition(0,100);
stage.addActor(tt);
setFillParent() does not work correctly inside a ScrollPane. Remove the line and it will work as intended.

Add horizontal scroll Libgdx

I want to design my levels on a horizontal pane what i am doing is:
container = new Table(skin);
container.setBounds(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
levelselect = new Table(skin);
levelselect.setBounds(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
// list = new List(skin,"1");
scrollPane = new ScrollPane(levelselect);
scrollPane.layout();
levelselect.align(Align.left);
for(int i=1;i<20;i++){
levelnumber = new Label(" "+i,levelnumbertext);
levelselect.add(levelnumber);
}
container.align(Align.bottom);
container.add(scrollPane).width(400).height(400);
container.add(levelselect);
any suggestions?? thanks in advance.
Using a ScrollPane and Table for this sounds like a lot of unnecessary overhead, they have a lot going on in the background, dynamically calculating their own layouts etc, you might not need this if you just want a full screen side scroller. You might be best just positioning your Actors on the Stage, however far along they need to be and update the Camera position to suit. Stage has culling options which I think by default are enabled, so it won't be drawing any of your Actors that are off the screen.

How to align table in scrollPane top?

I' am making achievements screen in my libgdx game. I want to align my table in scrollPane to top, now it is centred vertically and horizontally and I don't know why. Using .top() method when I've tried to create new row didn't worked.
stage = new Stage();
Gdx.input.setInputProcessor(stage);
outerTable = new Table();
innerTable = new Table();
innerTable.setFillParent(true);
for(int i=0;i<score_bound; i++){
if(i<score_state){
innerTable.row().width(achie_width).height(achie_height).top();
innerTable.add(new Image(ltm.assets.score_textures[i]));
}else{
innerTable.row().width(achie_width).height(achie_height).top();
innerTable.stack(new Image(ltm.assets.score_textures[i]),new Image(ltm.assets.kurtyna));
}
}
for(int i=0;i<letin_bound; i++){
if(i<letin_state){
innerTable.row().width(achie_width).height(achie_height).top();
innerTable.add(new Image(ltm.assets.letin_textures[i]));
}else{
innerTable.row().width(achie_width).height(achie_height).top();
innerTable.stack(new Image(ltm.assets.letin_textures[i]),new Image(ltm.assets.kurtyna));
}
}
scrollPane = new ScrollPane(innerTable);
outerTable.setPosition(0, 0);
outerTable.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
outerTable.debug();
outerTable.add(scrollPane).fill().expand();
stage.addActor(outerTable);
I run into the same issue today and came across here, so I might as well post an answer here in case somebody is still looking for an answer.
#peterSweter said top() does not work, what #Rara suggested is the same as calling top.
The only way to achieve something that looks like an align to the top - which only is relevant if the innerTable is smaller - is to increase the size by adding empty elements around it, so the table you pass to the ScrollPane has at least the same size as the scrollPane.
I just wrapped yet another Table around my innerTable reference.
(658 is the fixed height I use for my ScrollPane)
Table spacingTable = new Table();
spacingTable.setHeight(Math.max(innerTable.getHeight(), 658));
spacingTable.add(innerTable);
if (innerTable.getHeight() < 658) {
spacingTable.row();
spacingTable.add().expandY();
}
ScrollPane scroll = new ScrollPane(spacingTable, skin);
In order to achieve what you want, you can wrap your table inside another table and use that table for ScrollPane. Note that when adding your table to container table, you'll need to add some growable, empty cell at the bottom and right side in order to "push" it to top-left (although I believe you can also simply use containerTable.add(myTable).top().left() - but haven't tested it really).
This of course is a much better solution than second's solution, which uses hardcoded height. The thing is, you will usually want to add scroll pane as growable (.grow()), so fixed height/width is useless.

Arrange the sprites and text on the screen with Libgdx

I'm in the process of building my splash screen and I'm having some doubts related to align the elements and fit them right. How can make my sprites, text and other elements to occupy the right place and make them align on the screen, if you know what I mean. Should I use Table for that? How can I do that and how can I use the Table for this operation?
I changed my code: now may Player class extends the Actor class.
But I'm getting some troubles because I added the player into the table but the player image appears almost in the middle of the screen. It wasn't happening before I have inserted the method align the table to the center, but I removed this method and the player still keeps with that position on the screen
A part from the SplashScreen in the show() method:
// Create the SpriteBatch
this.game.spriteBatch = new SpriteBatch();
// Create the stage
this.game.stage = new Stage(this.game.viewPort);
// Create the table
this.table = new Table();
this.table.setFillParent(true);
this.game.stage.addActor(this.table);
// Insert the elements into the table
this.table.row();
this.table.add(this.game.player);
Now from the render() method from the SplashScreen:
// Set the projection matrix for the SpriteBatch
this.game.spriteBatch.setProjectionMatrix(this.game.orthoCamera.combined);
// SpriteBatch begins
this.game.spriteBatch.begin();
// Display the ClimbUp logo
this.gameTitle.draw(this.game.spriteBatch);
this.table.draw(this.game.spriteBatch, 1);
this.game.player.draw(this.game.spriteBatch, 1);
// SpriteBatch ends
this.game.spriteBatch.end();
Yes, when it comes to alignment in LibGdx Table is the way to go. Using Table's is very easy.
There first thing you need to have is a Skin instance which takes a TextureAtlas parameter, then you can instantiate the Table.
Table someTable = new Table(); //Takes a Skin object as a parameter.
someTable.add(); // Element as parameter.
someTable.row(); // Add a row if you need it.
someTable.add(); //Element as parameter.
someTable.debug(); // Don't forget to call debug();
When you have the Table object instantiated and ready to go just add it to a Stage object and let it do the drawing and other stuff.
someStage.addActor(someTable);
But before doing any of this you should probably take a look here.

JScrollPane will not reduce in size

I wrote a simple gui with DesignGridLayout as layout manager.
I have a 2 JTextFields, beneath them a JScrollPane containing a JTextArea, and right under it I have a button.
Upon maximizing the JFrame, everything is stretching out nicely to fill the screen.
The problem starts when I try to restore the Frame to it's original size. the JScrollFrame Vertical size remains too large, and the Button is not shown, since it is covered by the too big Jscrollpane.
The problem is the same for manual resizing. The JScrollPane sets a new value for it's vertical size according to how much I stretch it.
I tried overriding the getScrollableTracksViewportHeight() method from Scrollable interface, but it had no affect. In addition, I had this entire setting inside a Jpanel which I removed, but it's still the same.
Any insights would be appreciated.
edit: added samples of code.
This code creates most of the Gui:
DesignGridLayout layout = new DesignGridLayout(frame);
layout.row().grid().empty().add(new JLabel("someText1"), someText1);
layout.row().grid().empty().add(new JLabel("someText2"), someText2);
layout.emptyRow();
layout.row().grid().add(new JSeparator());
layout.row().grid().empty().add(titleLabel).empty();
layout.row().grid().add(textarea("",5,6));
layout.row().grid().empty().add(button).empty();
This code creates The JScrollPane:
private JScrollPane textarea(String content, int rows, int columns)
{
JTextArea textArea = new JTextArea(rows, columns);
JScrollPane scrollPane = new JScrollPane(textArea);
return scrollPane;
}