How to center actors in a group with Scene2d and LibGDX? - java

I'm using LibGDX and Scene2d and I want to create a pop-up that looks like the one shown in the image below.
So far, I created a table and set the background to a semitransparent color. Then I created an image with a white background. This image expands x, so it is centered. Now I want to have a label centered inside the image. To overlay these two actors, I created a group, but I couldn't find out how to center something in a group. How can I do this?
Here is my code:
Table table = new Table();
table.top();
table.setFillParent(true);
table.setBackground(getColoredBackground(color));
labelStyle = new Label.LabelStyle(font, fontColor);
label = new Label(message, labelStyle);
Image image = new Image(whiteBackground);
image.setSize(table.getWidth() - padding, label.getHeight() + extraHeight);
Group group = new Group();
group.setSize(image.getWidth(), image.getHeight());
group.addActor(image);
group.addActor(label);
table.add(group).expandX().padTop(padTop);

The group has it own coordinates system. It means that when you are setting actor position to (0,0) for example and then adding it to group which is actually at (100, 100) position then the object will be at (100, 100) position relative to the stage.
All you need to do is just to set:
label.setPosition( group.getWidth() / 2f - label.getWidth() / 2f, group.getHeight() / 2f - label.getHeight() / 2f );
after setting Group size. Remember that setting actor's position we are defining its left bottom corner position and that's why you need to also subtract the half of label width/height.
Of course you can modify the y position it doesn't have to be centered vertically also

Related

How do i scale a Label in LibGdx

i am trying to code a HUD for my game but i cannot figure out how to scale a Label properly I am using this code:
Label hpLabel = new Label("HP: ",new Label.LabelStyle(new BitmapFont(),Color.BROWN));
table.add(hpLabel);
viewport = new FitViewport(Gdx.graphics.getWidth()/ FacultyWars.PPM, Gdx.graphics.getHeight()/ FacultyWars.PPM, cam);
stage = new Stage(viewport, batch);
stage.addActor(table);
//other ellements added after this
The HP tag is enormous on the screen. I tried using setScale on the label and on the table to no avail. Any help is appreciated!
Thanks
Here is a picture of the current screen https://gyazo.com/57c190a9d7516bb8b2256bf1a7d17b4c
Simply add the Label to a Group then apply the scale to the group.
Label label = new Label("hello", skin);
Group group = new Group();
group.addActor(label);
group.setScale(2f, 2f);
I only scale Groups with Labels in animations where at the end of the animation the scale is 1. One should not scale fonts, because it looks pixelated. For example, a simple scale up scale down animation:
group.addAction(Actions.sequence(Actions.scaleTo(2f, 2f, 1f), Actions.scaleTo(1f, 1f, 1f)));
Use setFontScale(float fontScale) method of Label

screenshot image from vtkRenderWindow without borders

I tried everything I found to save just my image without borders without success.
My image is 124x126, so when the image is saved it's always with borders and new size 300x300, If I use another program to select only my image it's 208x209.
so I don't know why my image is scaled and why it's always 300x300, If I change the size of vtkRenderWindow to 124x126 the borders are still there and my image is shrunk.
My question is how I can save my image of 124x126 without borders?
mapper.SetInputConnection(polyDataReader.GetOutputPort());
vtkActor actor = new vtkActor();
actor.SetMapper(mapper);
actor.GetBounds(bounds);
System.out.println("actor: " + bounds[1] + " x " + bounds[3]); // 124x126 (everything's ok)
//Create a renderer, render window, and interactor
vtkRenderer renderer = new vtkRenderer();
vtkRenderWindow renderWindow = new vtkRenderWindow();
renderWindow.BordersOff(); // the borders are still there
renderWindow.AddRenderer(renderer);
vtkRenderWindowInteractor renderWindowInteractor = new vtkRenderWindowInteractor();
renderWindowInteractor.SetRenderWindow(renderWindow);
//Add the actor to the scene
renderer.AddActor(actor);
renderer.SetBackground(0, 0, 0);
//Render and interact
renderWindow.Render();
//screenshot code:
vtkWindowToImageFilter w2if = new vtkWindowToImageFilter();
w2if.SetInput(renderWindow);
w2if.Update();
vtkPNGWriter writer = new vtkPNGWriter();
writer.SetFileName("out.png"); //my image with borders 300x300 !!!!??
writer.SetInputData(w2if.GetOutput());
writer.Write();
ps: sorry for my English
It is because your renderwindow has the default size of 300x300.
What you have to realize is that the polydata is rendered in a 3D scene, and what you call "borders" is the background, the amount of which depends on the zoom level, i.e. on your camera's position. To get what you want, you need to do two things:
Resize renderwindow to desired image size:
renderWindow.SetSize(bounds[1], bounds[3]);
Reposition camera so that the actor fills the viewport completely. Try
renderer.GetActiveCamera().SetParallelScale(1); // we want parallel projection
renderer.GetActiveCamera().SetParallelScale(0.5 * (bounds[3] - bounds[2])); // zoom
The bounds in zoom may be 0.5 * (bounds[1] - bounds[0]), not exactly sure which side of the rectangle it should be.
Hope this helps,
Miro

How to always print String at the center of the screen?

I am using libgdx for my game and I have a viewport of 360x630, the problem is that I am using FreetypeFont for my fonts and the size is set to 24, I don't know how many pixels is 24. So what I did is
width = Gdx.graphics.getWidth();
height = Gdx.graphics.getHeight();
font.draw(batch, wc.string, width / 2 - string.length / 2, height / 2 - string.length / 2);
but the string length is always changed because the string is always changed too.
bellow A work around I always use to center any text with changing size, I don't know if it's a good practice to add useless sciene2D table for the purpose, anyway here is the solution :
Create a table :
private Table table;
In your show/create methode ( depend on your libgdx version ... ) add the following :
table = new Table(skin); // if you have a skin or you leave it empty
table.setFillParent(true);
YourText = new Label("YourText", skin, "YourFont");
table.add(YourText).colspan(3).expandX().spaceBottom(50).row(); // you change 50 depend on your screen resolution till you get to the center
This will put your text in a cell/row and center it H/V depend on the screen of course.
In the create/show method dont forget to add the table to the stage :
stage.addActor(table);
Now in your render method your add the following:
stage.act(delta);
stage.draw();
Finally you have to dispose the stage because the GC don't do it for you ( a libgdx way to do GC stuff ), in your dispose method you add this :
stage.dispose();

Positioning of 3d boxes in JavaFx

I'm a beginner in JavaFx 3d modelling. I'm trying to create a 3d-model of boxes in a room. I have the dimensions of the boxes and the coords from the front-left-bottom corner of every box. I've tried to set the coords with setTranslateX(), but the result isn't correct. Here is the pice of my code where I try to set the coords:
for (int i = 0; i < Main.load.size(); i++) {
Load l=Main.load.get(i);
Box sphere = new Box(l.getLength()*10, l.getWidth()*10, l.getHeight()*10);
sphere.setTranslateX(l.getX()*10);
sphere.setTranslateY(l.getY()*10);
sphere.setTranslateZ(l.getZ()*10);
PhongMaterial m = new PhongMaterial();
m.setDiffuseColor(new Color(Math.random(),Math.random(),Math.random(),1));
m.setSpecularColor(Color.BLACK);
sphere.setMaterial(m);
root.getChildren().add(sphere);
}
I hope someone can help me.
Here is an example:
Sizes:
blue (30,50,50)
pink (10,10,20)
Position:
blue (0,0,0)
pink (30,0,0)
And this is what I get
When you do a translation of a JavaFX 3D object like a Box you need to account half the width of the object along any axis. The default placement for a Box is to be centered at the origin meaning the center of the Box object is at 0,0,0. Your width is 30 * 10 but your translateX converts to 0*10=0. So the right most edge of your blue box will be X=150 (300 / 2.0 = 150). Your Pink Box has a translateX of 10*30=300. The center of the pink box will be translated to 300 which means the left most edge will be at 300 - (width/2.0) = 300 - (50) = 250.

Create a margins editor component like the one in Microsoft word

I have a Java Swing application that i want to create a nice component in it like a component in Microsoft word. In Microsoft word you can change the margins of your document like in here :
The trick here is that if you change the Top margins to (Let's say) 1.5" then the Preview image will change to show this, so the lines will move down a bit in the image to show that change in the margins so the user can feel how much his document will be affected by this change. So for example if i change the left margin to (4.0") the image will look like this :
What i did is create 2 images a blank page image + another image that contains lines only(Lines image), like these 2 images :
I inserted each image in a JLabel above each other, and now when i change the JSpinner top margin value, i keep the "blank page" image fixed, but i change the border of the "lines image" to move it down a bit. The trick worked fine for the top margin, but the behavior goes totally wrong if i change the bottom/right/left margins.
Here is my code that i apply when changing any JSpinner value :
private void marginSpinnerStateChanged() {
//1. Get the approximate values of all margins :
int topMargin = (int)( Float.valueOf( topSpinner.getValue().toString() ) * 8 );
int bottomMargin = (int)( Float.valueOf( bottomSpinner.getValue().toString() ) * 8 );
int leftMargin = (int)( Float.valueOf( leftSpinner.getValue().toString() ) * 8 );
int rightMargin = (int)( Float.valueOf( rightSpinner.getValue().toString() ) * 8 );
//2. Apply all specified margins to the lines label :
linesLabel.setBorder( new EmptyBorder( topMargin, leftMargin, bottomMargin, rightMargin ) );
}
Can you help me continue this to work right ?
You could just draw the image on top of the paper and scale the image as you go. So you would override the paintComponent() method of a JComponent to do something like:
g.drawImage(image, x, y, width, height, null);
x - would be the left margin
y - would be the top margin
width - would be (maxWidth - leftMargin - rightMargin)
height - would be (maxHeight - topMargin - bottomMargin)
If you don't like scaling the image you can always use a BufferedImage and then use the getSubImage(...) method to get an image the desired size to be painted.
If you notice, they don't shift the textual image. Instead, they only show half of it. This is simple image manipulation. For a good example, see this.

Categories

Resources