LibGDX ImageButton image not to scale? - java

The red square is the button's boundary, while the image remains centered at 32x32px. I've tried using button.getImage() to set position and size to the button's values, but it doesn't seem to have any effect.

Just use a regular Button. It also contains a Drawable for its background, but that one is always stretched to fill the button. See the JavaDoc for ImageButton:
... If the image is the size of the button, a Button without any children can be used, where the Button.ButtonStyle.up, Button.ButtonStyle.down, and Button.ButtonStyle.checked nine patches define the image.
Note that these don't actually need to be nine patches; any Drawable will do.

Probably super late but have you tried:
yourButton.getImage().setFillParent(true);

Extending on the answer of #xitnesscomplex:
You can use yourButton.getImage().setFillParent(true); to set the size.
To set an offset is somewhat counter-intuitive
ImageButton.ImageButtonStyle style = new ImageButton.ImageButtonStyle();
style.imageUp = new TextureRegionDrawable(new Texture(Gdx.files.internal(btn.png")));
ImageButton yourButton = new ImageButton(style);
style.unpressedOffsetX = -new_brush.getWidth()/4.0f;
style.unpressedOffsetY = -new_brush.getHeight()/4.0f;
style.pressedOffsetX = -new_brush.getWidth()/4.0f;
style.pressedOffsetY = -new_brush.getHeight()/4.0f;
style.checkedOffsetX = -new_brush.getWidth()/4.0f;
style.checkedOffsetY = -new_brush.getHeight()/4.0f;
yourButton.getImage().setFillParent(true);

Related

How to change size of JCheckBox Swing? [duplicate]

i want to make my JCheckboxes in a JTable bigger (for Touchscreen), but it doesn't change the size.
I tried it with
setPrefferedSize
setSize
What should I do?..
I assume you mean you want a bigger check box. If so then you need to create images to represent the unselected and selected icons of the check box. Then you can create a renderer and editor using these icons. Finally you would need to increase the height of each row in the table. The code might look something like:
Icon normal = new ImageIcon(...);
Icon selected = new ImageIcon(...);
JTable table = new JTable(...);
table.setRowHeight(...);
TableCellRenderer renderer = table.getDefaultRenderer(Boolean.class);
JCheckBox checkBoxRenderer = (JCheckBox)renderer;
checkBoxRenderer.setIcon( normal );
checkBoxRenderer.setSelectedIcon( selected );
DefaultCellEditor editor = (DefaultCellEditor)table.getDefaultEditor(Boolean.class);
JCheckBox checkBoxEditor = (JCheckBox)editor.getComponent();
checkBoxEditor.setIcon( normal );
checkBoxEditor.setSelectedIcon( selected );
IMPORTANT NOTE: This was only tested with the default 'Metal' look and feel. I do not guarantee that this will work for any other look and feel. Also I am not entirely sure how it works because it is admittedly a bit of a hack.
I was able to solve this in a slightly different way.
I wanted to use the existing images and just apply a scale to it. I am already scaling the font of my application using the UI defaults and so I have a rather large font. I wondered if I could leverage that and scale the check boxes accordingly.
After scouring the internet and trying a bunch of things I came up with this method:
public static void scaleCheckBoxIcon(JCheckBox checkbox){
boolean previousState = checkbox.isSelected();
checkbox.setSelected(false);
FontMetrics boxFontMetrics = checkbox.getFontMetrics(checkbox.getFont());
Icon boxIcon = UIManager.getIcon("CheckBox.icon");
BufferedImage boxImage = new BufferedImage(
boxIcon.getIconWidth(), boxIcon.getIconHeight(), BufferedImage.TYPE_INT_ARGB
);
Graphics graphics = boxImage.createGraphics();
try{
boxIcon.paintIcon(checkbox, graphics, 0, 0);
}finally{
graphics.dispose();
}
ImageIcon newBoxImage = new ImageIcon(boxImage);
Image finalBoxImage = newBoxImage.getImage().getScaledInstance(
boxFontMetrics.getHeight(), boxFontMetrics.getHeight(), Image.SCALE_SMOOTH
);
checkbox.setIcon(new ImageIcon(finalBoxImage));
checkbox.setSelected(true);
Icon checkedBoxIcon = UIManager.getIcon("CheckBox.icon");
BufferedImage checkedBoxImage = new BufferedImage(
checkedBoxIcon.getIconWidth(), checkedBoxIcon.getIconHeight(), BufferedImage.TYPE_INT_ARGB
);
Graphics checkedGraphics = checkedBoxImage.createGraphics();
try{
checkedBoxIcon.paintIcon(checkbox, checkedGraphics, 0, 0);
}finally{
checkedGraphics.dispose();
}
ImageIcon newCheckedBoxImage = new ImageIcon(checkedBoxImage);
Image finalCheckedBoxImage = newCheckedBoxImage.getImage().getScaledInstance(
boxFontMetrics.getHeight(), boxFontMetrics.getHeight(), Image.SCALE_SMOOTH
);
checkbox.setSelectedIcon(new ImageIcon(finalCheckedBoxImage));
checkbox.setSelected(false);
checkbox.setSelected(previousState);
}
What it does is get the size of the font from the checkbox's font metrics. Then using that it derives a new icon based on the icon found in the 'Look and Feel'.
One odd thing that I am not able to explain is how the icon for the checkbox in its 'un-selected' or default state, changes to the 'selected' icon, when I am accessing the same property to get each one.
I start by saving the state of the control so I can restore it at the end. This is done because in order for the icons to be set properly, the state needs to be unchecked when you first request the icon from the UIManager and then it will need to be checked when you request the icon the second time to get the 'selected' icon.
I am not entirely sure how the UIManager works or why the checkbox icon changes when we call the same property just by setting the 'selected' value of a single checkbox, but that is what is required in order to get both the necessary icons.
If you did not want to base the size on the font you could easily just pass in the height and width as parameters and use them instead of the font's height when setting the buffered image size.
I might mention that this same methodology works with radiobuttons

How to set BackgroundTintList of a button to default?

I'm changing the BackgroundTintList property of my button with the following line.
myButton.setBackgroundTintList(getColorStateList(R.color.green));
As a result my Button changes it's color from grey to green, and this is what I'd like to achieve.
My problem is that later on I'd like to set back the original grey color of the button, but I have no idea how to do it. I have tried to get the BackgroundTintList property of the button at the very beginning of my code (before I change it) but the following line returns NULL
ColorStateList buttonBackgroundTint = myButton.getBackgroundTintList();
Once I have set the BackgroundTintList to green, setting it to NULL changes my button to white and not to its default grey.
What would be the way to set my button to grey again?
You can try this line:
myButton.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#d8d8d8")));
if you want to change the button color back to its default/original color.
I haven't found any way to do this easily. The only way I could accomplish your goal was to hold on to the original background Drawable, create a clone of it, manually tint the clone, and then swap back and forth between these new drawables.
private Drawable original;
private Drawable tinted;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
this.original = button.getBackground();
this.tinted = button.getBackground().getConstantState().newDrawable().mutate();
ColorStateList custom = getResources().getColorStateList(R.color.my_button, getTheme());
tinted.setTintList(custom);
...
}
Then later on I can either write button.setBackground(original) or button.setBackground(tinted) to swap between the two.
I just created a new Button and get backgroundTintList
actionSearch.backgroundTintList = MaterialButton(requireContext()).backgroundTintList
if you want add custom color
view.backgroundTintList = ColorStateList.valueOf(getColor(context, R.color.color)

Libgdx | Scene2d | ImageButton setColor not working

I have an ImageButton. The texture for it is basically a white square, with black text in the center. I want to be able to dynamically change the color of this button. The problem is that ImageButton.setColor does not do anything. I can call tint on the ImageButtonStyle which does work, but I want to be able to change the color later down the road if for instance the player clicks on the button. Thanks! Here is some code :
ImageButton.ImageButtonStyle style_button_music = new ImageButton.ImageButtonStyle();
style_button_music.imageChecked = new SpriteDrawable(new Sprite((Texture) Game.assetManager.get("button_music.png")));
style_button_music.imageUp = new SpriteDrawable(new Sprite((Texture) Game.assetManager.get("button_music.png")));
style_button_music.imageDisabled = new SpriteDrawable(new Sprite((Texture) Game.assetManager.get("button_music.png")));
button_music = new ImageButton(style_button_music);
button_music.setColor(new Color(22f/255f, 100f/255f, 255f/255f, 1f));
table.setFillParent(true);
table.setDebug(true);
table.top();
table.pad(100);
table.add(button_music).width(200).height(200);
stage.addActor(table);
Use
button_music.getImage().setColor(Color color)
The setColor() on ImageButton is just inherited method from Actor but it doesn't do anything.
Actor color doesn't cascade down to children (except for the alpha component). Since the Image of an ImageButton is a child of the Button, the Image does not inherit the color of the Button.
However, the way in which you're currently using it, I think you could use a plain Button, and set the background image instead. That does get tinted.
style_button_music.checked = new TextureRegionDrawable(new TextureRegion(Game.assetManager.get("button_music.png")));
style_button_music.up = style_button_music.checked;
style_button_music.disabled = style_button_music.checked;
You should probably be using TextureRegionDrawable instead of SpriteDrawable. It's a much lighter-weight object, and it's rare to need the extra overhead of Sprites for buttons.
If you do need to use an actual ImageButton, and you're recoloring it dynamically, you could subclass ImageButton and use it's act method to transfer it's color to its child. That way you can use ColorActions with it.
#Override
public void act (float delta) {
super.act(delta);
Color color = getColor();
getImage().setColor(color.r, color.g, color.b, 1f); //leave opaque, alpha transferred in draw()
}

Set size for checkbox image in libgdx UI

I can't figure out how to manage checkbox images size. Of course, it is possible to create different size of image in my Texture atlas and take appropriate one, but I don't want to do that.
Here is my code:
AtlasRegion checkboxOn = AssetsHelper.textures.findRegion("checked");
AtlasRegion checkboxOff = AssetsHelper.textures.findRegion("unchecked");
CheckBoxStyle checkBoxStyle = new CheckBoxStyle();
checkBoxStyle.font = AssetsHelper.font66yellow;
checkBoxStyle.checkboxOff = checkboxOff;
checkBoxStyle.checkboxOn = checkboxOn;
CheckBox cbSound = new CheckBox(" Sound", checkBoxStyle);
cbSound object doesn't have such methods to rezise image of checkbox, but there is method getImage(), but seems it doesn't work too.
This is not working:
cbSound.getImage().width = 120;
cbSound.getImage().height = 120;
FYI: for example, when I wanted to draw image I did like that:
batch.draw(textureRegion, 0, 0, widthIwant, heightIwant);
But in CheckBox class there is overrided only this (without setting width and height):
public void draw (SpriteBatch batch, float parentAlpha) {
image.setRegion(isChecked ? style.checkboxOn : style.checkboxOff);
super.draw(batch, parentAlpha);
}
Question: how can I change width and height of checkbox image?
Thanks in advance.
The libgdx widgets are using drawables for drawing images. A drawable gets automatically scaled to fit the cell it is in. So in order to change the image size, change the cell size:
cbSound.getCells().get(0).size(widht, height);
For better results, you should use a nine patch for the drawable.
You need to set the image scaling type. Also method getImageCell is more correct than method getCells().get(0). Default is none.
CheckBox soundCB = new CheckBox("Sound", uiskin);
soundCB.getImage().setScaling(Scaling.fill);
soundCB.getImageCell().size(GameConfig.WIDTH/6);
soundCB.left().pad(PAD);
soundCB.getLabelCell().pad(PAD);
//...
content.add(soundCB).width(GameConfig.WIDTH/1.5f).row(); //add to table

libGDX: Textfield with BitmapFont(true) renders the text outside the borders

I'm experimenting with TextField and having problems with it when flipping the font. My orthographic camera is set to yDown = true. With that settings, the text is flipped so I came up with a solution to set BitmapFont's flip constructor parameter to true. But then when I try the code below. The text "Hello World" is rendering outside it's ninepatch borders. Here's a screenshot of it:
TextFieldStyle tfs = new TextFieldStyle();
NinePatch np = new NinePatch(new Texture(Gdx.files.internal(ResourceConstants.IMAGE_NINEPATCH)), 8, 8, 8, 8);
tfs.font = new BitmapFont(true);
tfs.fontColor = Color.BLACK;
tfs.background = np;
TextField tf = new TextField("Hello World", tfs);
tf.x = 50;
tf.y = 90;
tf.width = 100;
tf.height = 32;
addActor(tf);
tf.pack();
The problem is in the method where draw is being called on tfs (which is where the coordinates are set). The cartesian y coordinates for font are opposite other GDX objects, I think because typesetting needs to work a certain way.
So if you call
myFont.draw(spriteBatch, "Hello World", 0, 0);
Then you would expect the message to be drawn right in the bottom left hand side. But this is wrong! The fonts themselves are drawn from the top left, so your message will be drawn on the bottom left corner of the screen, below the bottom edge. We wont even be able to see the message.
But if we change the coordinates:
myfont.draw(spriteBatch, "box2d x: " + String.format("%2.2f", x), 10, 20);
We will see the message because we've given it enough room in the negative y direction to be displayed.
Given that the misbehaving font is misbehaving in the Y direction, and rendering below where you expect it to, I suspect that the above misconception is indeed the problem.
If you're not controlling any of the drawing coordinates of the bitmapfont itself, and this is solely handled by the TextField class, and the font is always out of bounds, no matter the size of your text field, then I would suspect a bug in GDX. You might try asking the forums about that.
I had the same effect. If you add TextField, and after, for example, add CheckBox and for this widget set setScale, then you will see this effect
TextField textfield = new TextField("Text field",skin);
stage.addActor(textfield);
CheckBoxStyle checkBoxStyle = skin.get(CheckBoxStyle.class);
checkBoxStyle.font.getData().setScale(2f);
CheckBox checkbox = new CheckBox("CheckBox", checkBoxStyle);
stage.addActor(checkbox);

Categories