-1

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
  • 168,117
  • 40
  • 217
  • 433
D-Lef
  • 1,219
  • 5
  • 14
  • 20

3 Answers3

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
  • 10,969
  • 6
  • 68
  • 77
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 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
1

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,219
  • 5
  • 14
  • 20
0

This is a good opportunity for you to set rounded corners for custom components, for example the following example implements setting rounded corners and margins:

import javax.swing.*;
import java.awt.*;

public class BaseComponent extends JComponent {
    private Insets insets;
    private int radius = 0;

    public BaseComponent() {
    }


    public BaseComponent(Insets insets, int radius) {
        this.insets = insets;
        this.radius = radius;
    }

    @Override
    protected void paintComponent(Graphics gr) {
        Graphics2D g2 = (Graphics2D) gr.create();
        // 背景
        if (getBackground() != null && isOpaque()) {
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
                    Boolean.getBoolean("apple.awt.graphics.UseQuartz") ?
                            RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE);
            g2.setColor(getBackground());
            g2.fillRoundRect(0, 0, getWidth(), getHeight(), radius, radius);
        }
        g2.dispose();
    }

    /**
     * 获取内边距,如果没有调用 {@link #setInsets(Insets)} ,则调用父类的insets,否则就获取设置的内边距
     */
    @Override
    public Insets getInsets() {
        if (insets == null) return super.getInsets();
        return insets;
    }

    public int getRadius() {
        return radius;
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }

    public void setInsets(Insets insets) {
        this.insets = insets;
    }

    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        BaseComponent c = new BaseComponent();
        c.setLayout(new BorderLayout());
        c.add(new JLabel("this is a label"));
        c.setBackground(Color.ORANGE);
        c.setPreferredSize(new Dimension(300,200));
        c.setRadius(20);
        c.setOpaque(true);
        c.setInsets(new Insets(10,10,10,10));

        f.getContentPane().setLayout(new FlowLayout());
        f.getContentPane().add(c);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

VsRoom
  • 1