Search code examples
javaswingoverridingjlabelpaintcomponent

JLabel: After overriding paintComponent(). How to make setText() render the text String?


I wrote a subclass of JLabel, and I override paintComponent(Graphics) method to make a gradient background color.

This is the subclass of JLabel:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.BorderFactory;
import javax.swing.JLabel;

public class DLabel extends JLabel
{

    Dimension size = new Dimension(70, 80);

    public DLabel()
    {
        this.setPreferredSize(size);
        this.setBorder(BorderFactory.createBevelBorder(TOP, Color.white, Color.black));
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        Color color1 = new Color(226, 218, 145);
        Color color2 = color1.brighter();
        int w = getWidth();
        int h = getHeight();
        GradientPaint gp = new GradientPaint(
                0, 0, color1, 0, h, color2);
        g2d.setPaint(gp);
        g2d.fillRect(0, 0, w, h);
    }

}

When I create an instance of this label it is displayed correctly, but when I use setText(String) the text is not rendered anything.

DLabel label = new DLabel();
label.setText("I am"); //No text displayed.

I tried different compilations of these methods after setting the text:

label.setOpaque(true);
label.revalidate();
label.repaint();

But nothing happed


Solution

  • What if you call the super.paintComponent(g) at the end of the method, so that the label draws the text after it draws the gradiant:

    public void paintComponent(Graphics g) {
      // super.paintComponent(g);  // *** commented
      Graphics2D g2d = (Graphics2D) g;
      Color color1 = new Color(226, 218, 145);
      Color color2 = color1.brighter();
      int w = getWidth();
      int h = getHeight();
      GradientPaint gp = new GradientPaint(0, 0, color1, 0, h, color2);
      g2d.setPaint(gp);
      g2d.fillRect(0, 0, w, h);
      super.paintComponent(g); // *** added
    }
    

    Also, as an unrelated aside, I prefer to change this:

    Dimension size = new Dimension(70, 80);
    
    public DLabel()
    {
        this.setPreferredSize(size);
        this.setBorder(BorderFactory.createBevelBorder(TOP, Color.white, 
             Color.black));
    }
    

    to this:

    public static final Dimension PREF_SIZE = new Dimension(70, 80);
    
    public DLabel()
    {
        this.setBorder(BorderFactory.createBevelBorder(TOP, Color.white, 
             Color.black));
    }
    
    @Override
    public Dimension getPreferredSize() {
      Dimension superDim = super.getPreferredSize();
      int width = Math.max(superDim.getWidth(), PREF_SIZE.getWidth());
      int height = Math.max(superDim.getHeight(), PREF_SIZE.getHeight()); 
      return new Dimension(width, height);
    }