Question

If I want to create my own custom JButton and i want to set the preferred size how do I go about doing this. I thought that it might be easy but when I get to it I have a dimension that I will be sending into my preferred size.

But then how do I set the correct x, y, width, and height values for my specific JButton component. It seems redundant to just call setPreferredSize again from in side of the same method?

This is the thing that I find odd about overriding a JComponent. I see how they are supposed to work with the paintComponent(...).

I want my new button to have a preferred size (is this the default size) that is 20 x 20.

I want to set this on any button were the size is not set by the constructor.

Also what methods should be overridden when creating a custom button?

class myButton extends JButton {
    public myButton(String s) {
        super(s);   
    }
    public void setPrefferedSize(Dimension d) {
        this.setBounds(x, y, width, height)
        setPreferredSize(d);
    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        setBackground(Color.RED);
    }
}
Was it helpful?

Solution

First of all: Adding an @Override annotation to your setPrefferedSize method would have made clear that it should be called setPreferredSize.

Apart from that, the getPreferredSize and setPreferredSize methods have some special semantics in a JComponent. Quoting from the JComponent#getPreferredSize documentation:

If the preferredSize has been set to a non-null value just returns it. If the UI delegate's getPreferredSize method returns a non null value then return that; otherwise defer to the component's layout manager.

When setting the preferred size with setPreferredSize, everything is fine. (I'd not recommend to create a subclass of a component only to call some set... methods in the constructor, but I assume that you'll have some additional methods that will justify extending the class).

However, when overriding getPreferredSize of JComponent, one should try to preserve the semantics of this method. That means that you should rather override it like that

@Override
public Dimension getPreferredSize()
{
    // If the preferred size was set manually, return this
    // size in order to be in line with the specification
    // that is described in the JavaDoc
    if (super.isPreferredSizeSet())
    {
        return super.getPreferredSize();
    }

    // Otherwise, return "your" preferred size. The
    // DEFAULT_WIDTH and DEFAULT_HEIGHT would be 20,20
    // in your case
    return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}

(actually, one would have to first ask the UI for a preferred size, but this is probably not desired here)

OTHER TIPS

Try overriding getMaximumSize and getMinimumSize. Which value is used and how they are used depends on the layout (and its implementation). Setting all three (min, max, preferred) should get you a definite size if the layout doesn't misbehave.

call super.setPreferredSize(d); inside overridden setPrefferedSize() method otherwise it will result in StackOverflowError calling same method again and again.


Try with overridden getPreferredSize() method for your custom JButton class.

@Override
public Dimension getPreferredSize() {
    return new Dimension(50, 20);
}

It's really very simple.

public class MyButton extends JButton {

    public MyButton(String s) {
        super(s);
        this.setPreferredSize(new Dimension(20, 14));
        this.setBackground(Color.black);
        this.setFont( new Font("Verdana", Font.BOLD, 10));
        this.setForeground(Color.WHITE);
    }
}

It's not redundant to use the methods to set something predefined, it's how your supposed to do it. What would be redundant would be doing this on 24+ buttons in your program, cluttering your guy constructor up with code it doesn't need to have.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top