DarkDust
DarkDust

Reputation: 92384

Automatically resizing JButton, with aspect ratio

I'd like to have a JButton which just shows an icon (or image, really). I do like to have the normal button borders so that a user does recognize it's a button that he can click. This button should have a fixed height but resize its width according to the aspect ratio of the its icon.

Is there a custom JButton class available that can do this? If not, how would I go about implementing this?

Edit: BTW, I could just rescale the icon from the outside, but I'd prefer the button to do it.

Edit 2: So to me, the biggest issue is: when and how do I determine and set the required button size? Scaling the image for drawing is not a problem.

Upvotes: 2

Views: 1665

Answers (2)

Andrew Thompson
Andrew Thompson

Reputation: 168835

Is there a custom JButton class available that can do this?

Not that I know of.

If not, how would I go about implementing this?

I'd approach it by extending ImageIcon to scale the image.

E.G.

Scaled images

import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

class ScaledImageIcon extends ImageIcon {
    ScaledImageIcon(Image image, int height) {
        super(image.getScaledInstance(-1, height, Image.SCALE_SMOOTH));
    }
}

public class ScalableIcons {

    public static void main(String[] args) throws Exception {
        final Image img1 = ImageIO.read(
                new URL("https://i.sstatic.net/gJmeJ.png"));
        final Image img2 = ImageIO.read(
                new URL("https://i.sstatic.net/ET1EH.png"));
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JPanel gui = new JPanel(new BorderLayout(5,5));
                
                final JLabel display = new JLabel();
                display.setPreferredSize(new Dimension(410,200));
                
                ActionListener al = new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        String s = e.getActionCommand();
                        switch (s) {
                            case "1":
                                display.setIcon(new ImageIcon(img1));
                                break;
                            case "2":
                                display.setIcon(new ImageIcon(img2));
                                break;
                        }
                    }
                };

                JPanel imageButtons = new JPanel(
                        new FlowLayout(FlowLayout.CENTER,5,5));

                JButton b1 = new JButton( "1", new ScaledImageIcon(img1,40));
                b1.addActionListener(al);
                imageButtons.add(b1);
                
                JButton b2 = new JButton( "2", new ScaledImageIcon(img2,40));
                b2.addActionListener(al);
                imageButtons.add(b2);
                
                gui.add(imageButtons, BorderLayout.NORTH);
                gui.add(display, BorderLayout.CENTER);
                
                JOptionPane.showMessageDialog(null, gui);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}

Upvotes: 4

camickr
camickr

Reputation: 324147

Not sure I totally understand the UI or the requirement but maybe Darryl's Stretch Icon will help you out. It automatically resizes the icon based on the components size and has the option to keep the aspect ratio.

Upvotes: 0

Related Questions