Auto-resizing JButton Icon

20,046

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

enter image description here enter image description here

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

  1. Override paintComponent
  2. 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!

Share:
20,046
Cristol.GdM
Author by

Cristol.GdM

Updated on November 23, 2020

Comments

  • Cristol.GdM
    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.
    ee. over 12 years
    For a simpler approach, change to int margin = 0; Dimension dim = this.getParent().getSize(); without the need to override getMinimumSize() and getPreferredSize() since the parent component has its margins already set
  • Cristol.GdM
    Cristol.GdM over 12 years
    Great! 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); by Icon 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
    kleopatra over 12 years
    still 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
    Tomáš Zato about 9 years
    Indeed, this answer doesn't do what was expected.
  • mKorbel
    mKorbel about 9 years
    @Tomáš Zato maybe another your mistake here
  • Tomáš Zato
    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
    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
    Tomáš Zato about 9 years
    I don't understand half of what you said. Sorry, we can't have a discussion in english.