Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Swing: paint under components of a JPanel?

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.

like image 760
Martin Tuskevicius Avatar asked Dec 07 '22 13:12

Martin Tuskevicius


2 Answers

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.

like image 101
Peter Quiring Avatar answered Dec 16 '22 06:12

Peter Quiring


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();
            }
        });
    }
}
like image 28
trashgod Avatar answered Dec 16 '22 05:12

trashgod