Set icon size of JTabbedPane tab icon - java

Is there a way to easily set the size of an icon for a JTabbedPanetab.
The icon is the same size as the original image and therefore makes for a very ridiculous looking tab with it taking up half the screen.
How would I easily rescale this icon to be a similar size to my text "Settings" and just have it appear normally?
URL cogIconUrl = getClass().getResource("/images/cog.png");
ImageIcon cogImg = new ImageIcon(cogIconUrl);
JTabbedPane jtp = new JTabbedPane();
getContentPane().add(jtp);
JPanel jp1 = new JPanel();
jtp.addTab("Settings", cogImg,jp1);
Furthermore, how would you go about setting the font of the tab text? I assume the two are potentially related.

Resize the Image:
BufferedImage image = ImageIO.read(...);
Image scaled = image.getScaledInstance(...);
Icon icon = new ImageIcon( scaled );
Note: the getScaledInstance(...) method may not be the best approach as it is slow, but for a single image you won't notice any problems.
You can read Perils of Image.getScaledImage for more information.

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 can I get my JLabel Icon Images to be high resolution?

I want to make an application with a small jLabel(50x50) in its corner.
The Problem I now have is that the Image the Label displays is looking really bad.
I also added the same Image as an Icon to a shortcut in windows on my desktop just as a comparison.
Windows on the left side and Java JLabel on the right.
How can I archive a similar scaling result in Jave with no loss in quality?
It does not need to use JLabel.
Code:
ImageIcon imgIcon = new ImageIcon(path);
Image img = imgIcon.getImage();
Image imgScaled = img.getScaledInstance((int) (getWidth()), (int) (getHeight()),
Image.SCALE_SMOOTH);
ImageIcon image = new ImageIcon(imgScaled);
label.setIcon(image);
EDIT:
If you look at these Google Chrome Icons, they are extremely tiny but still sharp and high resolution, how can I archive this in Java?
Your can to use in BufferedImage, this is much higher resolution the JLabel.
You can to create BufferedImage from .png file with ImageIO class.
I see two options, or maybe a combination of this:
You're using a weird resolution image for your ImageIcon
Ratio of width to height is not equal, thus skewed scaling
EDIT In case 2, make sure the JComponent you're using to fetch dimensions from (the one you're calling getWidth and getHeight on) has equal dimensions for both width and height.
I cut your left image, at 62px width/height. First row shows that image scaled, second row shows what happens when I scale the source image down to 32px in graphics program first:
Dimensions, as you can see below, go from 62px up by increments of 10px. Code was run on Java 1.8, Windows 10:
void addSeries(Image srcImg, JPanel targetPanel) {
for (int i = 0; i < 50; i += 10) {
int dimension = 62 + i;
Image imgScaled = srcImg.getScaledInstance(dimension, dimension, Image.SCALE_SMOOTH);
ImageIcon scaledIcon = new ImageIcon(imgScaled);
JLabel label = new JLabel();
label.setIcon(scaledIcon);
targetPanel.add(label);
}
}

Fit setIcon to JButton Array

I know this has been asked a ton of times, but I've searched everywhere and still haven't found an answer. I'm relatively new to Java. I have
JButton b[][];
Later, I assign b[3][3].setIcon(path). However, the image at path is always a small section of the actual image the size of the JButton. What I want is to re-size the image to fit the size of the JButton. Is there any way to do this? By the way, here's some code that's (I think) is important:
int n = 8;
int m = 8;
...
b = new JButton[n][m];
setLayout(new GridLayout(n,m));
for (int y = 0;y<m;y++){
for (int x = 0;x<n;x++){
b[x][y] = new JButton(" ");
b[x][y].addActionListener(this);
add(b[x][y]);
b[x][y].setEnabled(true);
}
}
What I want is to re-size the image to fit the size of the JButton.
You can use the Stretch Icon class.
It will allow you to automatically resize the Icon:
to fill the space of the button, or
keep the Icon proportion and fill the space of the button
The resizing is done dynamically so you don't need scaled images.
What you obviously need is a Icon Resizer method, something in the way of what I have provided below:
public static Icon resizeIcon(ImageIcon icon, int resizedWidth, int resizedHeight) {
Image img = icon.getImage();
Image img = img.getScaledInstance(resizedWidth, resizedHeight, java.awt.Image.SCALE_SMOOTH);
return new ImageIcon(img);
}
You can call this method after the image has already been applied to the JButton and after it has been added to whatever panel:
b[3][3].setIcon(path)
b[3][3].setIcon(resizeIcon((ImageIcon) b[3][3].getIcon(),
b[3][3].getWidth() - 15, b[3][3].getHeight() - 15));
or you could do it this way:
ImageIcon img = new ImageIcon("MyImage.png");
Icon icn = resizeIcon(img, b[3][3].getWidth() - 15, b[3][3].getHeight() - 15);
b[3][3].setIcon(icn);

Displaying a JLabel on top of another JLabel

I have the following code:
try {
File file_background = new File(
"C:\\Users\\xxxx\\Desktop\\background.png");
ImageIcon icon_background = new ImageIcon(
ImageIO.read(file_background));
JLabel background = new JLabel(icon_background);
window.setContentPane(background);
File file_car = new File(
"C:\\Users\\xxxxxx\\Desktop\\car.png");
ImageIcon icon_car = new ImageIcon(ImageIO.read(file_car));
JLabel car = new JLabel(icon_car);
car.setVisible(true);
background.add(car);
// TODO Get car showing on top of the background label
} catch (IOException e) {
e.printStackTrace();
}
Where I'm attempting to have the car label show on TOP of the background label. But I'm only getting the background JLabel showing. I'm new to SWING so any suggestions to what steps I'm missing would be great.
..I want to move it a later stage. But right now I want it to show first :)
There are two ways,
1st.
Put JLabel car to JPanel, drawing an Image by using paintComponent, instead of JLabel background (advantage JPanel is container with proper notifications for LayoutManager).
Put JLabel car to JLabel background, but JLabel haven't implemented any LayoutManager, have to set desired.
Advantage all images in JLabel are static, with zero CPU and GPU inpact ad consumption in compare with paintComponent.
Disadvantage JLabel isn't container and with proper notifications for LayoutManager, required a few code lones moreover in compare with JLabel placed in JPanel, for movement (AbsoluteLayout) is quite good solution.
2nd.
Draw both Images by using BufferedImage and Graphics.
Add them both to a JPanel that uses OverlayLayout. It is not ok to add a JLabel to another JLabel.
This code has not gone through a compiler so take it for what it is :)
JPanel panel = new JPanel(new OverlayLayout());
panel.add(background);
panel.add(car);
Works.. Added the following to make it display:
car.setBounds(200, 200, 200, 200);
Apparently it's because by default a null layout manager is used. So setting the bounds of the label will enable it to display since the default size is 0.

How to get the coordinate of Gridlayout

I set my JPanel to GridLayout (6,6), with dimension (600,600)
Each cell of the grid will display one pictures with different widths and heights.
The picture first add to a JLabel, and the JLabel then added to the cells.
How can retrieved the coordinate of the pictures in the cells and not the coordinate of cells? So far the out give these coordinate which equal height and width even on screen the pictures showed in different sizes.
e.g.
java.awt.Rectangle[x=100,y=100,width=100,height=100]
java.awt.Rectangle[x=200,y=100,width=100,height=100]
java.awt.Rectangle[x=300,y=100,width=100,height=100]
The reason why I used GridLayout instead of gridBagLayout is that, I want each pictures to have boundary. If I use GridBagLayout, the grid will expand according to the picture size.
I want grid size to be in fix size.
JPanel pDraw = new JPanel(new GridLayout(6,6));
pDraw.setPreferredSize(new Dimension(600,600));
for (int i =0; i<(6*6); i++)
{
//get random number for height and width of the image
int x = rand.nextInt(40)+(50);
int y = rand.nextInt(40)+(50);
ImageIcon icon = createImageIcon("bird.jpg");
//rescale the image according to the size selected
Image img = icon.getImage().getScaledInstance(x,y,img.SCALE_SMOOTH);
icon.setImage(img );
JLabel label = new JLabel(icon);
pDraw.add(label);
}
for(Component component:components)
{
//retrieve the coordinate
System.out.println(component.getBounds());
}
EDITED: I have tried this but not working :-(
for(Component component: pDraw.getComponents()){
System.out.println(((JLabel)component).getIcon());
}
How can I get output like these?
java.awt.Rectangle[x=300,y=100,width=50,height=40]
java.awt.Rectangle[x=400,y=400,width=60,height=50]
Do your images appear at the desired size ?
i think so.
Anyway, from what your code seems to do, I guess it gets the labels size, and not the icons size. JLabel, like any JComponent, are in fact Container instance. As such, their size depends upon constraints. As a consequence, in a GridLayout, a JLabel will have the size of a cell, whereas the contained Icon will have the size of the image.
As a consquence, to get image size, you have to call ((JLabel) component).getIcon() to be able to retrieve effective image dimension.

Categories