3

I want to color some JButtons, some other questions here showed me, that it would be easier to paint a little image (did it with gimp) and set it as icon for the JButton.

The number and size of the buttons should be variable (they're in a grid), so I want a high res image that I can scale how i need it.

The problem now is, I don't know how to 'cut the edges' of the icon, because the buttons have rounded edges.

Pic is not inside the borders of the button

Here you can see that the image is not inside of the button border.

And here is my method in the class that extends JButton.

public void setYellow() {
    URL u = getClass().getResource("/img/yellow.png");
    ImageIcon i = new javax.swing.ImageIcon(u);
    //Image img = i.getImage();
    //img = img.getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH); 
    //i = new ImageIcon(img);
    setIcon(i);
}

EDIT

package test;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import control.Control;
import view.Field;
import view.View;

public class HelloWorldSwing {

  /**
     * @param args
     */
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                TestView.initialize();
            }
        });
    }    

}

class TestView {
private static TestView view = new TestView();
public static TestView getView() {
    return view;
}

private TestView() {
    JFrame frame = new JFrame("HelloWorldSwing");
    frame.setLayout(new GridLayout(0,3));
    int buttonSize = 40;

    frame.getContentPane().add(new MyButton(buttonSize));
    frame.getContentPane().add(new MyButton(buttonSize));
    frame.getContentPane().add(new MyButton(buttonSize));

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
}

public static void initialize() {
}
}

class MyButton extends JButton {

int size;
public MyButton(int size) {
    this.size = size;
    setPreferredSize(new Dimension(size, size));
    this.addActionListener(new ButtonHandler());
    setBorder(LineBorder.createGrayLineBorder());
    setOpaque(true);
}

public void setYellow() {
    //URL u = getClass().getResource("/img/test.png"); // 64x64 png pic
        URL u1 = null;
    try {
        u1 = new URL("http://assets1.qypecdn.net/uploads/users/0195/7210" 
                       + "/calvin_yellow_original_thumb.jpg");         
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    ImageIcon i = new javax.swing.ImageIcon(u1);
//      Image img = i.getImage();
//      img = img.getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH); 
//      i = new ImageIcon(img);
    setIcon(i);
//      setBorderPainted(false);
//      setContentAreaFilled(false); did not help
}
}

class ButtonHandler implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
    MyButton mb = (MyButton) e.getSource();
    mb.setYellow();
}
}

EDIT 2

Here are the pictures where the lines in setYellow()

setBorderPainted(false);
setContentAreaFilled(false);

are not commented out (unfortunately there is no difference)

Before button is clicked:

enter image description here

After button is clicked:

enter image description here

UPDATE

I added Borders to the MyButton constructor

setBorder(LineBorder.createGrayLineBorder());

and now the icons are inside the button borders. I added pictures.

enter image description here

enter image description here

But as you can see, we don't have these rounded button edges anymore.

jim810
  • 128
  • 2
  • 10

1 Answers1

2
button.setBorderPainted(false);
button.setContentAreaFilled(false);

As seen in this answer.

Update

I do not quite get what you are trying to achieve if not this.

12 Yellow buttons w/ orange rollover icon

I made the rollover icon to be orange so that we could easily see the size of one button, but otherwise I put 4 in a row to ensure the minimum frame width did not insert extra space between the buttons in a row.

import java.awt.*;
import java.awt.Image;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class HelloWorldSwing {

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                TestView.getView();
            }
        });
    }    
}

class TestView {

    private static TestView view = new TestView();

    public static TestView getView() {
        return view;
    }

    private TestView() {
        JFrame frame = new JFrame("HelloWorldSwing");
        frame.setLayout(new GridLayout(3,4));
        int buttonSize = 40;

        for (int i=0; i<12; i++) {
            frame.getContentPane().add(new MyButton(buttonSize));
        }

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void initialize() {
    }
}

class MyButton extends JButton {

    int size;

    public MyButton(int size) {
        this.size = size;
        setPreferredSize(new Dimension(size, size));
        this.addActionListener(new ButtonHandler());
        setOpaque(true);
        setYellow();
    }

    public Image getImage(int sz, Color color) {
        BufferedImage bi = new BufferedImage(sz,sz,BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bi.createGraphics();
        g.setColor(color);
        g.fillRect(0, 0, sz, sz);

        g.dispose();
        return bi; 
    }

    public void setYellow() {
        Image img = getImage(64, Color.YELLOW).getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH); 
        setIcon(new ImageIcon(img));
        Image rollover = getImage(64, Color.ORANGE).getScaledInstance(size, size, java.awt.Image.SCALE_SMOOTH);
        setRolloverIcon(new ImageIcon(rollover));
        setBorderPainted(false);
        setContentAreaFilled(false); 
    }
}

class ButtonHandler implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        MyButton mb = (MyButton) e.getSource();
        mb.setYellow();
    }
}
Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Yeah, I already saw that, but it didn't help. The icon still stands out the button(s). – jim810 Nov 03 '12 at 14:17
  • 1) For better help sooner, post an [SSCCE](http://sscce.org/). 2) *"Yeah, I already saw that"* Yeah, it might have made sense to mention what you've already tried, given we are not psychic. – Andrew Thompson Nov 03 '12 at 14:19
  • My mistake, these were the only methods I tried. To mention, the button is also setOpaque. – jim810 Nov 03 '12 at 14:25
  • 2
    *"To mention.."* Stop 'mentioning' start SSCCEing. – Andrew Thompson Nov 03 '12 at 14:27
  • Thanks for the broad hint, I added the SSCCE. I'm going to hold on to that practice in future questions. – jim810 Nov 03 '12 at 14:59
  • Note that to be an SSCCE, we need to either hot-link to images or generate them in code. The first code I linked was an example of hot-linking, see my update for an example of generating them in code. – Andrew Thompson Nov 03 '12 at 16:12
  • I changed that and I also added a picture. I hope that helps to clarify my problem. The edges of the JButton are rounded (at least on MacOs), but when I set the IconImage, the image stands out of the button borders. I want the icon the fit in smoothly into the button. – jim810 Nov 03 '12 at 16:20
  • Show me an image produced with those two code lines I suggested **not** commented out. – Andrew Thompson Nov 03 '12 at 17:30
  • I added the pictures plus another approach with borders. Thanks for your effort so far. – jim810 Nov 04 '12 at 12:39