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
Related
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
In the following code:
Text imageText = textX.getTextWithDefaultBoldLookAndFeel("Image:");
BufferedImage image = (pojo.getImage() != null) ? pojo.getImage() : imageX.getImageFromFileAsBufferedImage(GlobalVar.defaultImage);;
double maxHeight = 300;
double maxWidth = 150;
Pane imageViewPane = new Pane();
imageViewPane.setMaxWidth(maxWidth);
imageViewPane.setMaxHeight(maxHeight);
//Setting the image view
Image image = SwingFXUtils.toFXImage(image, null);
//Setting the image view
ImageView imageView = new ImageView(image);
//Setting the fit height and width of the image view
imageView.setFitWidth(maxWidth);
//imageView.minWidth(maxWidth); // this won't solve the problem
imageView.setFitHeight(maxImageHeight);
//imageView.minHeight(maxHeight); // this won't solve the problem
// this solves the problem but also enlarges image which I do not want
imageView.setPreserveRatio(false);
imageGridPane.add(imageText, 0, 3);
imageGridPane.add(imageView, 1, 3);
gridPane.addRow(1, imageGridPane);
I'm adding Image to ImageView which is then added to a GridPane. The images I'm adding are of different sizes - some are too small to fill the entire ImageView area (300 x 150). When this occurs it causes the parent GridPane box to be smaller than the other boxes. I do not desire this. I realize that when an image is too small I am able to resize the image by setting imageView.setPreserveRatio(false); however, while it creates uniform boxes, it also causes the image to become blurry.
I would like for the image to be displayed however big (up the max limit) or small it is (i.e, not to be enlarged if too small) but I still want a uniform size for all ImageViews so that the parent GridPane (box) are all the same size. Perhaps so sort of transparent border can be added when the image is too small so that the image is not enlarged but ImageView still takes up same space as other large images - forcing uniform box size. I was unable to accomplish this by setting minWidth and minHeight properties of parent GridPane.
How can this be achieved?
Thanks!
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()
}
I have a canvas and a simple bitmap for background image, fills the whole screen. I created a rect painted black and set it's alpha to 250 in order to make a "dark" effect on the background image. My aim to make a simple circle object that reveals the place it's hovering above. I tried thinking in many ways how to excecute it and failed.
I think the best way is to create a simple circle that manages to decrease the darkness alpha on the position it hovers above, but I have no idea how to do it.
The relevant part of my code:
private ColorFilter filter = new LightingColorFilter(Color.BLACK, 1);
private Paint darkPaint = new Paint(Color.BLACK), paint = new Paint(), paint2 = new Paint();//The style of the text and dark.
public DarkRoomView(Context context) {
super(context);
myChild = this;
darkPaint.setColorFilter(filter);
darkPaint.setAlpha(250);
paint2.setAlpha(10);
paint.setAlpha(50);
}
private void loadGFX() {//Loads all of this view GFX file.
backgroundImage = BitmapFactory.decodeResource(getResources(), R.drawable.darkroomscreen);
lightImage = BitmapFactory.decodeResource(getResources(), R.drawable.light);
}
private void drawGFX(Canvas canvas) {
canvas.drawBitmap(backgroundImage, 0, 0, paint2);//The backgeound image.
canvas.drawRect(0, 0, WIDTH, HEIGHT, darkPaint);//The darkness.
canvas.drawBitmap(lightImage, 50, 50, paint);//A spotlight.
}
Any ideas how I should get it done?
Thanks!
For the spotlight, you could draw a circle of the original image over the darkness. You'd simply need to find the correct rectangle of the original image (based on where your finger is), and then draw a circle of that particular rectangle over the darkness. Trying to look "through" the darkness won't really get you anywhere; you need to place something over it.
By the time you draw the "spotlight", you've already darkened the image with the rectangle. It would be difficult to recover information lost during that draw.
A more flexible approach would be to draw a dark rectangle with a spotlight in a separate image (that is, compose the "darkness" and spotlight alpha and color mask image first), and then draw that mask image on top of the background as a separate step. This would also let you easily do things like e.g. give the spotlight fuzzy borders.
I can change the color of the font like this
LabelStyle style1 = new LabelStyle(..some font...,
Color.valueOf("FF4500")
);
label.setStyle(style1);
but how do I change the background?
right now the background is the same as the background of whole screen which is set in
render method lke this
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearColor(
1.000f, 0.980f, 0.941f
,1);
Label label = new Label(labelText, skin);
Pixmap labelColor = new Pixmap(labelWidth, labelHeight, Pixmap.Format.RGB888);
labelColor.setColor(<your-color-goes-here>);
labelColor.fill();
label.getStyle().background = new Image(new Texture(labelColor)).getDrawable();
Basically, use the getDrawable() function of the Image class to assign the color of your Label's LabelStyles' background Drawable.
This is the simplest workaround I've been able to come up with and, frankly, it's just silly that there is no setBackground() in the Label class.
Actually, maybe the easiest fix is to hack the Label class and add a setBackground() method to it.
[Edit] Be sure to dispose of Pixmaps when you are done with them; i.e. labelColor.dispose();
[Update] #Mitrakov Artem made a good point: The above solution will affect all instances of this LabelStyle. If that's not what you want you can create a new LabelStyle, use the above method on it, then save it to the Label. Quoting Artem: "So I would recommend to create a new style (LabelStyle style = new LabelStyle(label.getStyle());), change its background and then apply it to the label (label.setStyle(style);)"
Actually you do not change the background of the Lable like that. You did just change the clearcolour. Guess you know that.
To change the background you need to change the background at the style of the label. To do so i'd recommend to use a simple NinePatch as background, (can be a square! if its white you can change the colour of the ninepatch and the background colour changes!)
NinePatch temp = new NinePatch(new Texture(....), 10, 10, 10, 10); //edges
For more information about ninepatch take a look here libgdx wiki ninepatch
You need to add that ninepatch to an Skin objekt. For example like this
Skin skin = new Skin();
skin.add("background",temp)
After that you can get a drawable from the skin that you can set as background of the LabelStyle.
style1.background = skin.getDrawable("background");
see libgdx API LabelStyle
You can also use a simple bitmap but that does get scaled to the label size which causes in most of the cases deformation. A Ninepatch can be scaled without having deformation.
If you need a quick and easy solution, you can use the snippet below. It doesn't work well with multiline text because it doesn't take the text width per line into account.
Anyway, the background is automatically adjusted to the width and height of the label widget (i.e. if your text changes).
private Label label = new Label("text", createLabelStyleWithBackground());
private LabelStyle createLabelStyleWithBackground() {
LabelStyle labelStyle = new LabelStyle();
labelStyle.font = new BitmapFont();
labelStyle.fontColor = Color.WHITE;
labelStyle.background = createBackground();
return labelStyle;
}
private Drawable createBackground() {
Pixmap labelColor = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
Color color = new Color(Color.GRAY);
color.a = 0.75f;
labelColor.setColor(color);
labelColor.fill();
Texture texture = new Texture(labelColor);
return new BaseDrawable() {
#Override
public void draw(Batch batch, float x, float y, float width, float height) {
GlyphLayout layout = label.getGlyphLayout();
x = label.getX();
y = label.getY() - (layout.height + 15) / 2; // +15 is some space
batch.draw(texture, x, y, layout.width, layout.height + 15);
}
};
}
here is an example with a multiline label