4

I have a JPanel that has a button in it. The location of the button is irrelevant. The paint(Graphics g) code is:

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        /* drawing code */
    }

If I wanted to fill the entire space of the panel with black rectangle, while also having the button in the panel, the filled in rectangle would simply cover everything up. So rather than having a button and then black all around the button, the entire panel is black.

Is there any way to modify the panel, or the painting procedure, so that the components are drawn on top of the custom painting?

I have tried to put super.paint(g) at the end of painting, like:

    @Override
    public void paint(Graphics g) {
        /* drawing code */
        super.paint(g);
    }

... thinking that it would do the custom painting first, and then simply put the components over it. However, if done like that, the custom painting disappears altogether and only the button shows up. That is, only a button and a white (default) background rather than the black rectangle.

Any ideas?

Thanks!

Edit: I want to clarify that the black rectangle is an example. I am aware that I could simply set the background color, but I am trying to ultimately be able to do any custom painting that I would like.

Martin Tuskevicius
  • 2,590
  • 4
  • 29
  • 46
  • So again, what are you trying to achieve? A button that can't be seen since it's covered in black? If so, to what purpose? – Hovercraft Full Of Eels Jun 18 '12 at 00:09
  • I'm trying to make a menu that has custom painting but also uses the basic Swing components. I realize I could do setBackground(..) but it does not allow me to custom painting. And, as far as I know, menus are not very fun if they are solid colors and cannot be interacted with. – Martin Tuskevicius Jun 18 '12 at 00:11

2 Answers2

9

I think you want to override paintComponent() not paint().

paint() usually doesn't do any painting but delegates to paintComponent(), paintBorder() and paintChildren().

see javax.swing.JComponent.paint() for more info

Example:

  @Override
  public void paintComponent(Graphics g) {
    /* your draw code here */
  }

You could call super.paintComponent(g); to draw the component as usual but can be omitted.

Peter Quiring
  • 1,648
  • 1
  • 16
  • 21
  • 1
    +1 For reference, "Swing programs should override `paintComponent()` instead of overriding `paint()`."—[*Painting in AWT and Swing: The Paint Methods*](http://java.sun.com/products/jfc/tsc/articles/painting/index.html#callbacks). – trashgod Jun 18 '12 at 04:47
  • Yep! This did exactly what I needed. Thanks a lot! – Martin Tuskevicius Jun 24 '12 at 06:38
  • 1
    Could you send an example how you did it? I have the same problem and I can't get it working. – Erich Apr 05 '16 at 16:19
6

You can set the panel's background to black and adjust the UI delegate's colors. You can setBorderPainted(false) and highlight the button as desired. Here's an sscce with which to update your question as the need arises. This AnimationTest shows how paintComponent() can update the panel "behind" components.

Addendum: Putting super.paintComponent(g) first will ensure that components appear to overlie the (possibly changing) background. Because a component's background color is under the control of its UI delegate, you can do any of the following:

  • use the UIManager to change the corresponding properties, as shown below.
  • use a custom JButton that overrides paintComponent(), as shown here.
  • use a custom UI delegate, as shown here.

SSCCE:

import component.Laf;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

/** @see https://stackoverflow.com/a/11075785/230513 */
public class ButtonPanel extends JPanel {

    public ButtonPanel() {
        this.setBackground(Color.black);
        final JButton b = new JButton(new AbstractAction("Button"){

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Clicked");
            }
        });
        // b.setBorderPainted(false);
        this.add(b);
    }

    private void display() {
        UIManager.put("Button.foreground", Color.white);
        UIManager.put("Button.background", Color.black);
        JFrame f = new JFrame("ButtonPanel");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ButtonPanel().display();
            }
        });
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045