-2

I want to add a JComponent in my basic JFrame. My problem is that I cannot set background color or border for my component.

JFrame

JPanel drawPanel = new JPanel(new GridBagLayout());
drawPanel.add(new DrawingBoard());
JScrollPane scrollPane = new JScrollPane(drawPanel);
this.add(scrollPane, BorderLayout.CENTER);
this.setVisible(true);

JComponent

private class DrawingBoard extends JComponent {
        ...
        public DrawingBoard() {
        this.setPreferredSize(new Dimension(500, 500));
        this.setBackground(Color.WHITE);     //doesn't work
        this.setBorder(BorderFactory.createEmptyBorder(0,10,10,10)); //doesn't work
        this.setOpaque(true);
        ...
Andrew Thompson
  • 166,747
  • 40
  • 210
  • 420
D-Lef
  • 1,041
  • 5
  • 13
  • 18

2 Answers2

2

Basically, because JComponent has no UI delegate, it never paints its background (its paintComponent method essentially does nothing).

You could supply a UI delegate that performs the required actions, or simply use JPanel, for example:

enter image description here

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;

public class TestComponent {

    public static void main(String[] args) {
        new TestComponent();
    }

    public TestComponent() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setBackground(Color.WHITE);
            setBorder(new CompoundBorder(
                            BorderFactory.createEmptyBorder(0,10,10,10),
                            BorderFactory.createLineBorder(Color.RED)
            ));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}
Jan Bodnar
  • 9,881
  • 5
  • 60
  • 71
MadProgrammer
  • 336,120
  • 22
  • 219
  • 344
  • I sometimes suggest `JPanel` _because_ it has a UI delegate; older versions of `com.apple.laf.AquaPanelUI` are seen [here](http://stackoverflow.com/a/11338636/230513) and [here](http://stackoverflow.com/a/11724866/230513). – trashgod Jun 08 '14 at 23:52
0

I found a simple solution to my problem. I just added the Jcomponent to a Jpanel and then I added the Jpanel to the Jframe.

    JPanel outer = new JPanel(new GridBagLayout()); 
    JPanel drawPanel = new JPanel(new GridBagLayout());
    drawPanel.add(new DrawingBoard(500,500));
    drawPanel.setBackground(Color.WHITE);
    outer.setBorder(BorderFactory.createEmptyBorder(0,10,10,10));
    JScrollPane scrollPane = new JScrollPane(drawPanel);
    outer.add(scrollPane);
    this.add(outer, BorderLayout.CENTER);
D-Lef
  • 1,041
  • 5
  • 13
  • 18