如何在标题边框内设置背景?

问题描述 投票:0回答:2

我有一个 JLabel,我做

setBackground(Color.WHITE)
setBorder(new CustomTitledBorder(Color.BLACK, "Some Text")
。 JLabel 的白色背景位于边框范围之外。我尝试环顾四周并找到了这个解决方案:

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;

public class TempFrame extends JFrame {

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TempFrame frame = new TempFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public TempFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(null);
        setContentPane(contentPane);

        var label = new MyLabel();
        label.setBounds(10, 10, 334, 65);
        getContentPane().add(label);

        JButton btnNewButton = new JButton("Click To Add Text");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                label.setText("String");
            }
        });
        btnNewButton.setBounds(127, 86, 89, 23);
        contentPane.add(btnNewButton);
    }

    private class MyLabel extends JLabel {

        public MyLabel() {
            
            setOpaque(true);
            setBorder(new CustomTitledBorder(Color.BLACK, "Title Here"));
            setBackground(Color.WHITE);
            
        }

/* Here is where I am having the problem */
//      @Override
//      protected void paintComponent(Graphics g) {
//          var insets = this.getBorder().getBorderInsets(this);
//          g.setColor(Color.WHITE);
//          g.fillRect(insets.left, insets.top, getWidth() - insets.left - insets.right,
//                  getHeight() - insets.top - insets.bottom);
//      }

    }

    private class CustomTitledBorder extends TitledBorder {

        public CustomTitledBorder(Color color, String title) {
            super(new LineBorder(color), title);
            
        }

    }
}


这是没有修改

paintComponent()
方法的情况

这就是我想要

paintComponent()
方法做的事情

如果我尝试使用

setText("String");
添加文本,这就是结果。我可以看到我的其他一些组件在那个角落也以某种方式相互重叠

我该如何做才能不出现这种情况?

java swing border
2个回答
2
投票

根据提供的图像,您似乎希望将父面板的背景颜色用作边框的背景,并为标签的其余部分提供不同的背景颜色。

所以这意味着您需要:

  1. 保持标签透明,以便首先绘制父级的背景
  2. 绘制标签的背景减去边框使用的区域
  3. 绘制标签的文字

所以你的自定义标签类应该是:

private class MyLabel extends JLabel
{
    public MyLabel()
    {
        //setOpaque(true);
        setBorder(new CustomTitledBorder(Color.BLACK, "Title Here"));
        setBackground(Color.WHITE);
    }

  @Override
  protected void paintComponent(Graphics g)
  {
        var insets = this.getBorder().getBorderInsets(this);
        g.setColor(Color.WHITE);
        g.fillRect(insets.left, insets.top, getWidth() - insets.left - insets.right, getHeight() - insets.top - insets.bottom);

        super.paintComponent(g);
  }

}

0
投票

如果您不想覆盖 Label 类,则另一种解决方案:覆盖边框本身 - 但是,我在获取组件父级的背景时遇到问题:

public class NonOpaqueTitledBorder extends TitledBorder {
    public NonOpaqueTitledBorder(final String title) {
        super(title);
    }

    private static Color getParentBackground(final Component c) {
        if (c instanceof JLabel) {
            return c.getParent().getParent().getBackground();
        } else if (c instanceof JTextField) {
            return c.getParent().getParent().getBackground();
        } else {
            return c.getParent().getBackground();
        }
    }

    @Override
    public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) {
        Insets borderInsets = this.getBorderInsets(c);
        g.setColor(getParentBackground(c));

        // top and bottom
        g.fillRect(x, y, width, borderInsets.top);
        g.fillRect(x, y + height - borderInsets.bottom, width, borderInsets.bottom);

        // left and right
        g.fillRect(x, y, borderInsets.left, height);
        g.fillRect(x + width - borderInsets.right, y, borderInsets.right, height);

        super.paintBorder(c, g, x, y, width, height);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.