3

My code for custom button is:

public class GreyButton extends JLabel {

    private int     ButtonWidth,
                    ButtonHeight;
    String          ButtonText;

    public GreyButton(String BText, int BWidth, int BHeight) {
        super(BText);
        this.ButtonHeight   =   BHeight;
        this.ButtonWidth    =   BWidth;
        this.ButtonText     =   BText;
        setGreyButton();
    }

    private void setGreyButton() {
        this.setPreferredSize(new Dimension(this.ButtonWidth, this.ButtonHeight));
        this.setBackground(Color.LIGHT_GRAY);
        this.setOpaque(false);
        this.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
        this.setForeground(Color.WHITE);
        this.setHorizontalAlignment(SwingConstants.CENTER); //This line
    }

    @Override
    public void paint(Graphics g) {
        paintComponent(g);
    }

    @Override
    public void paintComponent(Graphics g) {
        Graphics2D  Shape                   =   (Graphics2D) g;

        AlphaComposite newComposite         =   AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
        Shape.setComposite(newComposite);

        Color[]         FillArray           =   {Color.WHITE, Color.GRAY};
        float[]         Distribution        =   {0.85f, 1.0f};
        GradientPaint   Fill                =   new GradientPaint(10, 8, Color.BLACK, 10, 72, Color.WHITE);         
        Paint           OldPaint            =   Shape.getPaint();

        Shape.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Shape.setPaint(Fill);
        Shape.fillRect(0, 0, ButtonWidth, ButtonHeight);
        Shape.setPaint(OldPaint);
        Shape.setFont(new Font("Monospace", Font.BOLD, 14));
        Shape.drawString(ButtonText, 0, 0); //This line
    }

}

This is to create a JLabel with custom 2D Graphics. The problem is that I am trying to center the text in the JLabel and this be should valid for any size the used in the constructor.

Currently, I need to calculate the values and set the second and third parameters of drawString accordingly.

Question: Is there a general way of centering a text on JLabel whose size may differ with each instance?

StanislavL
  • 56,971
  • 9
  • 68
  • 98
jagan
  • 67
  • 1
  • 5

4 Answers4

4

You can get the width of the String using the FontMetrics.

    Shape.getFontMetrics().stringWidth(ButtonText);
Grim
  • 1,938
  • 10
  • 56
  • 123
  • Related examples [here](http://stackoverflow.com/questions/6238037/how-do-i-align-this-text-correctly/6238908#6238908). – trashgod Sep 20 '11 at 18:16
  • @peter This helps for the width part, How should I go about the height (center vertically)? – jagan Sep 20 '11 at 18:26
  • @jagan: swing unfortunatily has uniqe height-metrics... try **Shape.getFontMetrics().getHeight();** – Grim Sep 21 '11 at 07:45
4

Don't override the paint() method when doing custom painting. You would never override the method to invoke the paintCompnent() method.

If you are just trying to paint a custom background then I would think you would:

  1. Paint your gradient background at the start of the paintComponent() method.

  2. Then invoke super.paintComponent(g). The normal painting code will position the text based on the horizontal alignment property.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • @camickr This really helped but it throws up a bluish border around the text again. How can I eliminate it? This is was one of the problems for which I decided to 'paint' the component myself – jagan Sep 22 '11 at 16:02
  • @jagan, You probably need to use setOpaque(true) on your JLabel. This indicates that your custom painting will be responsible for painting the background. If this doesn't help then you need to post your SSCCE that demonstrates the problem. – camickr Sep 22 '11 at 20:14
  • @camickr It was `.setFocusPainted(false)` I was talking about in the comments. Just could not get the correct word for it. Anyways, your reply to the OP helped, Thanks! – jagan Sep 23 '11 at 13:53
  • JLabel doesn't have a `setFocustPainted()` method. – camickr Sep 23 '11 at 14:50
2

Alternative 1:

Have your button to extend JButton. Invoke setContentAreaFilled(false) on that button. Override the paintComponent() method of the button and draw the background as you'd like to have it, and then invoke super.paintComponent() to draw the text/label.

Alternative 2:

Since JLabel is good at drawing text and position that text horizontally and vertically, I think I would have taken advantage of that and delegated the actual drawing to JLabel. However, clearly, this is an issue since you need a gradient background. As far as I know, both the background painting and text painting is taken care of in the same method (paintComponent()) in JLabel, so you can't really have the JLabel to just draw the text but not the background.

What I would have done is to let GreyButton extend JPanel. I would then create a class which extends PanelUI to draw the JPanel, and set that class as the JPanel's UI.

After that, I'd set GridBagLayout as layout manager on the JPanel and add the JLabel to the JPanel. The layout manager makes sure that the JLabel fills the entire JPanel horizontally and vertically. Thus, the text will become centered in the middle of the JPanel.

In other words, in the JPanel constructor, I'd make sure to add the JLabel using something along the lines of:

    JLabel label = new JLabel("Label");
    GridBagLayout l = new GridBagLayout();
    setLayout(l);

    GridBagConstraints c = new GridBagConstraints();
    c.gridx = 0;
    c.gridy = 0;
    c.fill = GridBagConstraints.BOTH;
    add(label, c0);

You most likely have to experiment a little with the constraints, but the above piece of code should be a good place to start.

sbrattla
  • 5,274
  • 3
  • 39
  • 63
1

It looks like you want to paint your own JComponent with JButton functionality.

1) Don't reinvent the wheel; in many cases it is only necessary to change the Look and Feel in Java. Everything there is possible, for example with Substance, Synthetica and Nimbus.

If you really want to hack JButton in detail,

2) You can go this way with a custom ButtonUI; notice one overrides only certain methods.

3) In some cases, only a change in "Button.background" is required.

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319