COMPOUND BORDER : 在 java Swing 的 Jpanel 之外获取带标题的轮廓边框

COMPOUND BORDER : Get a outline border with title outside the Jpanel in java Swing

我唯一的问题是我不知道如何将边框放在面板之外。我试过 compound 和其他一些边界代码,但到目前为止我无法将它放在外面。它要么消失,要么根本没有改变。

我想要的输出:

我得到的输出:

我是 swing 的新手,我一直在搜索并发现了复合边框,但我仍然不太熟悉它是如何将按钮添加到面板中的。 (我已经删除了我尝试做复合边框的代码,因为它只是一团糟,充满了错误)

代码:

package activityswing;

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


public class swing {
public static void main (String args []) {
     JFrame pa= new JFrame("Swing Activity");
        //boarder
        pa.setLayout(new BorderLayout());
        //panels
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
            //buttons
        JButton button1 = new JButton("Button 1");
        JButton button2 = new JButton("Button 2");
        JButton button3 = new JButton("Button 3");
        JButton button4 = new JButton("Button 4");
        JButton button5 = new JButton("Button 5");
        JButton button6 = new JButton("Button 6");

        //label
        JLabel lb1= new JLabel("Panel 1");
        JLabel lb2= new JLabel("Panel 2");

        //adding label to panel
        lb1.add(panel1);
        lb1.add(panel2);

        //panel1
        Border line1 = BorderFactory.createLineBorder(Color.blue);
        panel1.setBorder(line1);
        panel1.add(button1);
        panel1.add(button2);
        panel1.add(button3);
        panel1.setBorder(BorderFactory.createTitledBorder("Panel 1"));
        panel1.setBackground(Color.BLUE);
        panel1.setPreferredSize(new Dimension(270,40));

        //panel2
        Font font2 = new Font("Verdana",Font.ITALIC,12);
        Border line2 = BorderFactory.createLineBorder(Color.blue);
        lb2.setFont(font2);
        panel2.setBorder(line2);
        LayoutManager layout = new FlowLayout();  
        panel2.setLayout(layout);
        panel2.add(button4);
        panel2.add(button5);
        panel2.add(button6);
        panel2.add(lb2);
        panel2.setBorder(BorderFactory.createTitledBorder("Panel 2"));
        panel2.setBackground(Color.GREEN);
        panel2.setPreferredSize(new Dimension(270,40));

        //FRAME
        FlowLayout flow = new FlowLayout(FlowLayout.CENTER, 50,50);
        pa.setLayout(flow);
        pa.pack();
        pa.add(panel1);
        pa.add(panel2);
        pa.setSize(700,200);
        pa.setResizable(false);
        pa.setVisible(true);
        pa.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pa.setLocationRelativeTo(null);

}
}

不要向标签添加组件

lb1.add(panel1);
lb1.add(panel2);

标签根据标签属性 (text/icon/font/etc) 而不是 child 组件计算其首选大小。

不要弄乱组件的 preferredSize 除非你绝对确定你愿意承担计算组件大小的所有责任。

简单的解决方案是自己创建一个 TitledBorder 的实例,例如...

Font font2 = new Font("Verdana", Font.ITALIC, 12);
TitledBorder border = new TitledBorder("Panel 1");
border.setTitleFont(font2);

我有点想创建一个工厂方法来使这更容易,但你明白了一般的想法

为了使边框与组件“分离”,我会使用复合组件方法,其中外部面板包含标题,然后将内部面板添加到其中。

如果需要,您可以使用 CompoundBorder 并在外面板的一侧使用 EmptyBorder

看看:

...了解更多详情

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.LayoutManager;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

public class Test {

    public static void main(String args[]) {
        JFrame pa = new JFrame("Swing Activity");
        //boarder
        pa.setLayout(new BorderLayout());
        //panels
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
        //buttons
        JButton button1 = new JButton("Button 1");
        JButton button2 = new JButton("Button 2");
        JButton button3 = new JButton("Button 3");
        JButton button4 = new JButton("Button 4");
        JButton button5 = new JButton("Button 5");
        JButton button6 = new JButton("Button 6");

        Font font2 = new Font("Verdana", Font.ITALIC, 12);
        TitledBorder border1 = new TitledBorder("Panel 1");
        border1.setTitleFont(font2);
        
        JPanel outter1 = new JPanel(new BorderLayout());
        outter1.setBorder(border1);
        panel1.add(button1);
        panel1.add(button2);
        panel1.add(button3);
        panel1.setBackground(Color.BLUE);
        outter1.add(panel1);

        //panel2
        LayoutManager layout = new FlowLayout();
        TitledBorder border2 = new TitledBorder("Panel 2");
        JPanel outter2 = new JPanel(new BorderLayout());
        outter2.setBorder(border2);
        
        panel2.setLayout(layout);
        panel2.add(button4);
        panel2.add(button5);
        panel2.add(button6);
        panel2.setBackground(Color.GREEN);
        
        outter2.add(panel2);

        //FRAME
        FlowLayout flow = new FlowLayout(FlowLayout.CENTER, 50, 50);
        pa.setLayout(flow);
        pa.add(outter1);
        pa.add(outter2);
        pa.pack();
        pa.setLocationRelativeTo(null);
        pa.setVisible(true);
        pa.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pa.setLocationRelativeTo(null);

    }
}

您可以嵌套 JPanel。这就是我如何实现 你想要的输出 .

下面的代码不是对您的代码的更正,它是如何实现您想要的输出的示例。由于代码中的两个 JPanel 非常相似,下面的代码只显示一个 JPanel。我假设您可以进行适当的更改。

package activityswing;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;

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

public class Swing2 {
    private JPanel createInner() {
        JPanel inner = new JPanel();
        inner.setBackground(Color.GREEN);
        JButton button1 = new JButton("Button 1");
        inner.add(button1);
        JButton button2 = new JButton("Button 2");
        inner.add(button2);
        JButton button3 = new JButton("Button 3");
        inner.add(button3);
        return inner;
    }

    private JPanel createOuter() {
        JPanel outer = new JPanel();
        TitledBorder titledBorder = new TitledBorder(new LineBorder(Color.blue), "Panel 1");
        Font font2 = new Font("Verdana", Font.BOLD + Font.ITALIC, 12);
        titledBorder.setTitleFont(font2);
        EmptyBorder emptyBorder = new EmptyBorder(10, 10, 10, 10);
        CompoundBorder compoundBorder = new CompoundBorder(titledBorder, emptyBorder);
        outer.setBorder(compoundBorder);
        outer.add(createInner());
        return outer;
    }

    private void showGui() {
        JFrame frame = new JFrame("Swing2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createOuter());
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new Swing2().showGui());
    }
}

运行以上代码显示如下window.