Auto-resizing JButton Icon
Solution 1
in Swing you can add any JComponent
to the another JComponent
, for Image
is JLabel
the best JComponent
, then why not put the JLabel#setIcon()
to the JButton
import java.awt.*;
import javax.swing.*;
public class ResizeIconInButton extends JFrame {
private static final long serialVersionUID = 1L;
public ResizeIconInButton() {
JButton myButton = new JButton();
myButton.setLayout(new BorderLayout());
myButton.add(new CustomComponents0());
add(myButton, BorderLayout.CENTER);
setPreferredSize(getPreferredSize());
setTitle("Resize Icon In Button");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
ResizeIconInButton main = new ResizeIconInButton();
}
};
javax.swing.SwingUtilities.invokeLater(r);
}
}
class CustomComponents0 extends JLabel {
private static final long serialVersionUID = 1L;
@Override
public Dimension getMinimumSize() {
return new Dimension(200, 100);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
@Override
public void paintComponent(Graphics g) {
int margin = 10;
Dimension dim = getSize();
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
}
}
EDIT:
import java.awt.*;
import javax.swing.*;
public class ResizeIconInButton extends JFrame {
private static final long serialVersionUID = 1L;
private static final String IMAGE_PATH = "http://duke.kenai.com/misc/Bullfight.jpg";
private JButton myButton = new JButton();
private JLabel myLabel = new JLabel();
public ResizeIconInButton() {
Icon myIcon = new ImageIcon(IMAGE_PATH);
myLabel.setIcon(myIcon);
myButton.setLayout(new BorderLayout());
myButton.add(myLabel);
add(myButton, BorderLayout.CENTER);
setPreferredSize(new Dimension(200, 100));
setTitle("Resize Icon In Button");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
ResizeIconInButton main = new ResizeIconInButton();
}
});
}
}
Solution 2
- Override
paintComponent
-
Draw the image directly to it's
Graphics
object
And when drawing the image, provide the dimensional arguments getWidth()
and getHeight()
. By doing this, the resizing will be automated. Also, when resizing, you'll want to do some anti-aliasing so the image doesn't get too pixelated.
Solution 3
You could add a Component-Listener to that Button which upon resizing resizes your Image in it
yourButton.addComponentListener(new ComponentListener() {
@Override
public void componentShown(ComponentEvent e) {
// ignore
}
@Override
public void componentResized(ComponentEvent e) {
resizeIcon(icon, yourButton.getWidth(), yourButton.getHeight());
}
@Override
public void componentMoved(ComponentEvent e) {
// ignore
}
@Override
public void componentHidden(ComponentEvent e) {
// ignore
}
});
Hope it helps!
Cristol.GdM
Updated on November 23, 2020Comments
-
Cristol.GdM over 3 years
so I have this JButtons to which I add Icons. The Icons are too large initially, so I resize them beforehand, and it works fine. Except that when I resize the window, the JButtons change size, but not the Icons, which is problematic.
Is there a way to have an Icon just fill the JButton it is attached to? Bit of code to make it clearer:
public JewelClass(){ setBackground (new Color (30,30,30)); addActionListener(this); setLayout(new GridLayout()); ImageIcon icon = new ImageIcon(src/carre.jpg); setIcon (resizeIcon(icon,60,60)); }
resizeIcon being a personal function, that takes an Icon, a width parameter and a height parameter, and return a resized Icon (obviously). I tried changing the Layout, but it doesn't change anything. I tried getting the width/height of the JButton, but since they don't exist yet when the Icon is added, it doesn't work.
Would you guys have any idea how to get through this? It doesn't have to be an icon, as long as my JButton is filled with the image I give it, it's awesome :)
Thanks!
-
ee. over 12 yearsFor a simpler approach, change to
int margin = 0; Dimension dim = this.getParent().getSize();
without the need to overridegetMinimumSize()
andgetPreferredSize()
since the parent component has its margins already set -
Cristol.GdM over 12 yearsGreat! So it works to paint a shape, but the only thing is, once I replace
g.setColor(Color.red);g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
byIcon icon = new ImageIcon("src/triangle.jpg"); icon.paintIcon(this, g, 60, 60);
, it stops displaying anything at all. Do you have any idea why this is? -
kleopatra over 12 yearsstill doesn't resize the image (which is the OP's problem as I understood it) Basically, adding a component to a component is a ... extremely roundabout way of achieving a goal, especially if it doesn't achieve it <g> Or what am I missing?
-
Tomáš Zato about 9 yearsIndeed, this answer doesn't do what was expected.
-
mKorbel about 9 years@Tomáš Zato maybe another your mistake here
-
Tomáš Zato about 9 years@mKorbel Said a man that never made a mistake-less English sentence... Anyway, I was just pointing out that I have the same objection as kleopatra.
-
mKorbel about 9 years@Tomáš Zato 1. "Anyway, I was just pointing out that I have the same objection as kleopatra." == thats not the same e.g. real Swing guru v.s. you, 2. "Said a man that never made a mistake-less English sentence..." == I don't needed that, hmmm now I'm remember correct if am I wrong, expects you, 3. what did you tried, becase my suggestion is the fastest from all, there are another, EDIT as you know very well - 3diff. ways for resizing an Image (together with) in JButton, optimalizations for Icon/ImageIcon in the JLabel is very simple, fast and, my favorite
-
Tomáš Zato about 9 yearsI don't understand half of what you said. Sorry, we can't have a discussion in english.