Search code examples
javaswingjlabelpaintcomponentsetbackground

For a Custom JLabel (shape changed) setbackground method paints the rectangle and not the new shape


I have created a custom label by overriding the paintComponent() method as shown below. But when I call the setBackground() method on this component. It paints the entire rectangle. I want it to paint only the custom shape.Please help.

Custom Label code :

public class CustomLabel extends JLabel {
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Rectangle rect = g.getClipBounds();

        Polygon shape3 = new Polygon();
        shape3.addPoint(rect.x, rect.y + rect.height - 1);
        shape3.addPoint(rect.x + rect.width - 10, rect.y + rect.height - 1);
        shape3.addPoint(rect.x + rect.width - 1,  rect.y + rect.height / 2);
        shape3.addPoint(rect.x + rect.width - 10, rect.y);
        shape3.addPoint(rect.x, rect.y);

        g.setColor(Color.LIGHT_GRAY);
        g.drawPolygon(shape3);

    }

}

EDIT :

Modified the code as below.

I want the default background to be white So when the label gets created the first time the background is white. Now there are several labels displayed on the screen. On click event I change the background color e.g. I call setbackground(Color.red) so the color of the clicked label gets updated.

Now when I scroll the screen the repaint() method gets called and this repaints all the Custom Labels and changes the background of all the Labels to red.

EDIT 2: Code for adding Labels:

for (int i = 0; i < noOfLabels; i++)
    {
        String labelkey = "Label" +i;
        CustomLabel label = new CustomLabel();
        label.addMouseListener(this);
        myLayeredPane.add(label, new Integer(3));
    }

Code for Custom Label:

public class CustomLabel extends JLabel
{
private Color background = Color.WHITE;

public void paintComponent(Graphics g)
{
    super.paintComponent(g);

    Rectangle rect = g.getClipBounds();

    Polygon shape3 = new Polygon();
    shape3.addPoint(rect.x, rect.y + rect.height - 1);
    shape3.addPoint(rect.x + rect.width - 10, rect.y + rect.height - 1);
    shape3.addPoint(rect.x + rect.width - 1, rect.y + rect.height / 2);
    shape3.addPoint(rect.x + rect.width - 10, rect.y);
    shape3.addPoint(rect.x, rect.y);

    g.setColor(background);
    g.fillPolygon(shape3);

    g.setColor(Color.LIGHT_GRAY);
    g.drawPolygon(shape3);
}

@Override
public void setBackground(Color arg0)
{
    background = arg0;
    System.out.println("Setting bg color to : "+background);
}

}

Solution

  • You can try next trick with overriding setBackground() and fill your shape with custom color:

    public class CustomLabel extends JLabel {
    
        private Color background = Color.RED;
    
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            Rectangle rect = g.getClipBounds();
    
            Polygon shape3 = new Polygon();
            shape3.addPoint(rect.x, rect.y + rect.height - 1);
            shape3.addPoint(rect.x + rect.width - 10, rect.y + rect.height - 1);
            shape3.addPoint(rect.x + rect.width - 1, rect.y + rect.height / 2);
            shape3.addPoint(rect.x + rect.width - 10, rect.y);
            shape3.addPoint(rect.x, rect.y);
    
            g.setColor(Color.LIGHT_GRAY);
            g.drawPolygon(shape3);
            g.setColor(background);
            g.fillPolygon(shape3);
        }
    
        @Override
        public void setBackground(Color arg0) {
            background = arg0;
        }
    }
    

    EDIT: Here is my example with 4 labels and all works properly:

    public class CustomLabel extends JLabel {
    
        static Random rand = new Random();
    
        public static void main(String args[]) {
            JLayeredPane p = new JLayeredPane();
            p.setBorder(BorderFactory.createLineBorder(Color.BLACK));
            p.setPreferredSize(new Dimension(200, 100));
            MouseAdapter adapter = new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent arg0) {
                    super.mouseClicked(arg0);
                    float r = rand.nextFloat();
                    float g = rand.nextFloat();
                    float b = rand.nextFloat();
                    Color randomColor = new Color(r, g, b);
                    arg0.getComponent().setBackground(randomColor);
                    arg0.getComponent().repaint();
                }
            };
            for (int i = 0; i < 4; i++)
            {
                String labelkey = "Label" +i;
                CustomLabel label = new CustomLabel();
                label.setText(labelkey);
                label.setBounds(10+i*30,10,30,30);
                label.addMouseListener(adapter);
                p.add(label);
            }
    
            JFrame f = new JFrame();
            f.add(p);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.pack();
            f.setVisible(true);
        }
    
        public CustomLabel(){
        }
    
        private Color background = Color.white;
    
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            Rectangle rect = g.getClipBounds();
    
            Polygon shape3 = new Polygon();
            shape3.addPoint(rect.x, rect.y + rect.height - 1);
            shape3.addPoint(rect.x + rect.width - 10, rect.y + rect.height - 1);
            shape3.addPoint(rect.x + rect.width - 1, rect.y + rect.height / 2);
            shape3.addPoint(rect.x + rect.width - 10, rect.y);
            shape3.addPoint(rect.x, rect.y);
    
            g.setColor(Color.LIGHT_GRAY);
            g.drawPolygon(shape3);
            g.setColor(background);
            g.fillPolygon(shape3);
        }
    
        @Override
        public void setBackground(Color arg0) {
            background = arg0;
        }
    
    }