Question

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);
}

}
Was it helpful?

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;
    }

}

OTHER TIPS

Check out Playing With Shapes for some other ideas for drawing shapes instead of extending JLabel and doing custom painting.

The shapes will be reusable and can be used with any components that can display an Icon.

It might be your super.paintComponent(g); Try removing that, your parent will still draw the shape.

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