1

I'm making a custom button that is made up of two other buttons. It has different behavior from a normal button (hence why it's custom) and looks like this

My Button Working http://i1078.photobucket.com/albums/w491/evesforeva/Screenshot2012-07-28at21932AM.png

I would like to change the way icons are set in my button so that they apply to the button on the right (the one with the square). Currently, I am overriding AbstractButton.getIcon and AbstractButton.setIcon so that they apply to the right button, rather than the whole button. So my code looks like this

/* (non-Javadoc)
 * @see javax.swing.AbstractButton#getIcon()
 */
@Override
public Icon getIcon() {
    return popupButton.getIcon();  // popupButton = the right button
}

/* (non-Javadoc)
 * @see javax.swing.AbstractButton#setIcon(javax.swing.Icon)
 */
@Override
public void setIcon(Icon icon) {
    Icon oldValue = getIcon();
    firePropertyChange(ICON_CHANGED_PROPERTY, oldValue, icon);
    popupButton.setIcon(icon);
}

When I try to set my button icons, the button ends up looking like this

My Button Broken http://i1078.photobucket.com/albums/w491/evesforeva/Screenshot2012-08-19at42508PM.png

where the icon is duplicated in the middle of the whole button. I tried removing firePropertyChange, but that didn't work.

Also here is the code I used to produce the two screenshots

public class MyButtonDemo implements Runnable {

public static class DemoPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    public DemoPanel() {
        MyButton myButton = new MyButton("My Button");
        Icon icon = new ImageIcon(new BufferedImage(5, 5, BufferedImage.TYPE_INT_RGB));
        myButton.setIcon(icon);

        add(myButton);
        add(new JButton("Normal Button"));
    }

}

/* (non-Javadoc)
 * @see java.lang.Runnable#run()
 */
public void run() {
    LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels();
    try {
        UIManager.setLookAndFeel(lafs[2].getClassName());
    } catch (Exception e) { }

    JFrame frame = new JFrame();
    frame.setContentPane(new DemoPanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new MyButtonDemo());
}

}

What is making my button display the icon for the whole button instead of just the right button? And how do I work around it?

Eva
  • 4,397
  • 5
  • 43
  • 65
  • 3
    Going to need `MyButton` as well ;) – MadProgrammer Aug 20 '12 at 00:05
  • @MadProgrammer The code for MyButton is really long (about 1000 loc). Would the constructor help? – Eva Aug 20 '12 at 00:40
  • How about a brief idea of how it's build. You say it extends `AbstractButton`, how do you go about getter the separator and popup attached to it? – MadProgrammer Aug 20 '12 at 00:52
  • 'getter' should be 'adding' :P – MadProgrammer Aug 20 '12 at 01:05
  • @MadProgrammer All AbstractButtons extend Container so I just add the inner buttons and separator to the outer button using the add method. I guess part of my problem is that my button is a button but it also has buttons. – Eva Aug 20 '12 at 02:10
  • Why isn't `button.setHorizontalTextPosition(AbstractButton.LEFT); and button.setVerticalTextPosition(AbstractButton.CENTER);` working for you ? Isn't that what you expecting as an output, when you add these two lines to your **CustomButton** ? – nIcE cOw Aug 20 '12 at 05:03

1 Answers1

2

As to the why: you are overriding a method of the containing button such that the containing button thinks it has an icon - consequently, its uidelegate paints it where it deems appropriate :-)

As to how-to prevent that: depends a bit on how much work you want to put into it.

  • The clean one is to implement a custom ui-delegate and implement that for all LAFs you want to support. You might want to have a look at SwingX, its plaf module takes off a bit of the pain as demonstrated in a recent thread.
  • The simpler one is to not re-use the containing button's api: implement the setIcon to do nothing and add new methods for setting the popup icon.
Community
  • 1
  • 1
kleopatra
  • 51,061
  • 28
  • 99
  • 211