Changing icon size for JButton in Java?
Whenever I set an icon for my JButton, it always doesn't have the correct size. How do I resize the icon to fit the button exactly?
final JButton btnSanic = new JButton();
Image img = icon.getImage();
Image newimg = img.getScaledInstance(width, height, java.awt.Image.SCALE_SMOOTH);
icon = new ImageIcon(newimg);
btnSanic.setIcon(icon);
There are several questions. For starters, all Swing components DO NOT automate images. Sure, it might be a good idea, but given the amount of time and processing required to use it effectively, I understand why they don't, so you have to do all the work ...
You should also remember that the size of a component is not determined until after it is laid out, and while you can provide any sizing hints you may like, the layout manager is within its rights to ignore one or more of these hints. ...
Rather than “hopefully” you know the size of the button, you should use the API ComponentListener
to get notified when the component has actually changed ...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestButton {
public static void main(String[] args) {
new TestButton();
}
private BufferedImage master;
public TestButton() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
try {
master = ImageIO.read(new File("C:\\svg\\Revert 256x256.png"));
JButton btn = new JButton() {
@Override
public Dimension getPreferredSize() {
return new Dimension(90, 50);
}
};
btn.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
JButton btn = (JButton) e.getComponent();
Dimension size = btn.getSize();
Insets insets = btn.getInsets();
size.width -= insets.left + insets.right;
size.height -= insets.top + insets.bottom;
if (size.width > size.height) {
size.width = -1;
} else {
size.height = -1;
}
Image scaled = master.getScaledInstance(size.width, size.height, java.awt.Image.SCALE_SMOOTH);
btn.setIcon(new ImageIcon(scaled));
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(btn);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException exp) {
exp.printStackTrace();
}
}
});
}
}
Note. This example is far from optimization, but just provides a broad concept of a possible solution ...
Now a word of warning. Image#getScaledInstance
is not the fastest and largest scaling algorithm ...
Take a look at ...
- Dangers of Image.getScaledInstance ()
- Image quality after resizing is very poor - Java
for more details ...
You can use Stretch Icon . Just add an icon to your component and it will scale automatically.
This code resizes the image to be the same size as the JButton that will contain it:
JButton button = new JButton();
button.setBounds(x, y, width, height);
try{
Image image = ImageIO.read(new File("icons/myImage.png")).getScaledInstance(width, height, Image.SCALE_DEFAULT);
button.setIcon(new ImageIcon(image));
}
catch (Exception e) {
}