Drawing graphics on top of a JButton

10,123

Solution 1

you can subclass JButton and override paintComponent(). you can handle each button having a different graphic by providing an external 'painter' to the subclass. Or just have a different subclass for each different graphic.

public class MyButton extends JButton {
    private Painter painter;

    public void paintComponent(Graphics g) {
       super.paintComponent(g);
       painter.paint(g);
    }
}

public interface Painter {
    public void paint(Graphics g);
}

you cannot just paint on the button as you are doing as the painting will get lost when the button is next repainted.

Solution 2

You can create a BufferedImage and do custom painting on it and then draw the image in your custom paintComponent(...) method.

Look at the DrawOnImage example from Custom Painting Approaches.

Share:
10,123
trinth
Author by

trinth

Updated on June 04, 2022

Comments

  • trinth
    trinth almost 2 years

    I have a situation wherein I have a bunch of JButtons on a GridLayout. I need each of the JButtons to have:

    1. a background image (but retain the ability to keep the default button look if needed)
    2. custom graphics drawn on top by other classes

    I have no trouble with the background image, since I am using setIcon() but I am having problems drawing things on top of the background. At one point I was able to draw on top of the button, but after the button was clicked, the drawings disappeared. How can make the button keep this drawing state?

    Basically, I need a way for my JButtons to have public methods that would allow another class to draw anything on it such as:

    public void drawSomething() {
      Graphics g = this.getGraphics();
      g.drawOval(3,2,2,2);
      repaint();
    }
    

    or

    public Graphics getGraphics() {
      return this.getGraphics();
    }
    

    then another class could do this:

    button.getGraphics().drawSomething();
    

    The latter is more what I am looking for but the first is equally useful.

    Is there any way to go about this? Also, overriding the parent class method paintComponent() doesn't help since I need each button to have different graphics.

  • trinth
    trinth about 14 years
    Thanks for the answer, I considered this but have decided to go with the interface answer.
  • trinth
    trinth about 14 years
    I had actually been using this approach earlier except I had not used an interface. I scrapped it because I thought there might be an easier way. This is a more elegant approach, Thank You.