如何用边框包围Java Swing组件?

时间:2012-10-11 11:55:34

标签: java swing user-interface border

我正在构建一个包含少量标签面板的应用程序。在每一个上,我都希望通过边框将各组件彼此分开。它看起来像是:

|- Titled Border 1 ---

[JTextField] [JComboBox] [JTextField] [JComboBox]

|--------

|- Titled Border 2 ---

[JTextField] [JComboBox] [JTextField] [JComboBox]

|--------

... and so forth.

当我尝试简单地向面板添加新边框“标题边框2”时,它被添加并覆盖了第一个将组件留在顶部。在一些示例中,我看到在一个帧内定义了许多JPanel,并且每个面板都有自己的边框。它可能适用于我的情况,但如何添加这些面板以显示在一个选项卡中?

Oracle的一个教程显示了一个标签窗格,其中包含多种边框的演示。当我尝试编辑它并在其中放置一个组件时,它出现在两个边框之间而不是被包围。而另一种选择对我来说是不成功的。

第二件事是,我没有使用任何布局管理器,组件位置是固定的,老实说我会保留这个设置。或者您可能建议在这种特定情况下使用任何布局管理器?

您对如何解决此问题有任何提示吗?

编辑:我似乎还不允许附上截图,但这是代码中显示边框的部分:

    lenMicro = new JPanel();
    lenMicro.setLayout(null);

    bGreyLine = BorderFactory.createLineBorder(Color.GRAY, 1, true);
    bTitled1 = BorderFactory.createTitledBorder(bGreyLine, "Length (1/2)", TitledBorder.LEFT, TitledBorder.TOP);
    lenMicro.setBorder(bTitled1);
    bTitled2 = BorderFactory.createTitledBorder(bGreyLine, "Length (2/2)", TitledBorder.LEFT, TitledBorder.TOP);
    lenMicro.setBorder(bTitled2); 

取消注释最后两行时,会显示标题为“长度(2/2)”的边框。

2 个答案:

答案 0 :(得分:18)

使用Absolute Positioning时,您必须为每个组件提供位置,这些组件将成为视图的一部分。因此,如果不确切地看到你在做什么,很难预测事情的确切位置。虽然使用Layout Managers,但是如果在视图上放置不同的组件,将会减轻您的负担。

此外,您必须为相应组件设置边框。所以我决不会假设您添加了一个组件并且它出现在两个边框之间(尽管考虑到您使用绝对定位的事实,您可能在视图上为所述组件提供了错误的坐标)。请看一下这个示例代码,它可能会对您有所帮助:

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

public class BorderExample
{
    private JPanel topPanel;
    private JPanel centerPanel;
    private JPanel bottomPanel;
    private int hgap;
    private int vgap;
    private JTextField tfield1, tfield2;
    private JComboBox cbox1, cbox2;
    private String[] data = {"One", "Two"};

    public BorderExample()
    {
        hgap = 5;
        vgap = 5;
    }

    private void displayGUI()
    {
        JFrame frame = new JFrame("Border Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setOpaque(true);
        contentPane.setBackground(Color.WHITE);
        contentPane.setBorder(
            BorderFactory.createEmptyBorder(hgap, hgap, hgap, hgap));
        contentPane.setLayout(new BorderLayout(hgap, vgap));

        topPanel = new JPanel();
        topPanel.setOpaque(true);
        topPanel.setBackground(Color.WHITE);
        topPanel.setBorder(
            BorderFactory.createTitledBorder("Top Panel"));
        tfield1 = new JTextField(10);   
        tfield1.setBorder(
            BorderFactory.createTitledBorder(
            BorderFactory.createEtchedBorder(
                    EtchedBorder.RAISED, Color.GRAY
                    , Color.DARK_GRAY), "JTextField"));
        JPanel comboPanel = new JPanel();           
        cbox1 = new JComboBox(data);
        cbox1.setBorder(
            BorderFactory.createTitledBorder("JComboBox")); 
        topPanel.add(tfield1);  
        topPanel.add(cbox1);

        centerPanel = new JPanel(); 
        centerPanel.setOpaque(true);
        centerPanel.setBackground(Color.WHITE);
        centerPanel.setBorder(
            BorderFactory.createTitledBorder("Center Panel"));
        tfield2 = new JTextField(10);   
        tfield2.setBorder(
            BorderFactory.createLoweredBevelBorder());
        cbox2 = new JComboBox(data);
        cbox2.setBorder(
            BorderFactory.createRaisedBevelBorder());   
        centerPanel.add(tfield2);   
        centerPanel.add(cbox2);

        bottomPanel = new JPanel(); 
        bottomPanel.setOpaque(true);
        bottomPanel.setBackground(Color.WHITE);
        bottomPanel.setBorder(
            BorderFactory.createTitledBorder("Center Panel"));

        contentPane.add(topPanel, BorderLayout.PAGE_START);
        contentPane.add(centerPanel, BorderLayout.CENTER);
        contentPane.add(bottomPanel, BorderLayout.PAGE_END);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new BorderExample().displayGUI();
            }
        });
    }
}

以下是相同的输出:

BORDER_EXAMPLE

答案 1 :(得分:3)

好的,所以这解决了我对使用布局管理器以及为组件组添加边框的问题的很大一部分:

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

public class TestingGround extends JFrame {

private JTextField tLenUnit, tLenResult, tAreUnit, tAreResult;
private JComboBox<String> cLenInUnit, cLenOutUnit, cAreInUnit, cAreOutUnit;
private JPanel lenMicro, lenMicro1, lenMicro2, lenNormal, lenMacro, area, volume;
private Border bGreyLine, bTitled1, bTitled2;

private TestingGround() {

    setTitle("Testing Ground for an Application");
    setVisible(true);
    setResizable(true);
    setLocationRelativeTo(null);

    try {
        UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (UnsupportedLookAndFeelException e) {
        e.printStackTrace();
    }

    lenMicro = new JPanel();
    lenMicro.setLayout(new GridBagLayout());

    lenMicro1 = new JPanel();
    lenMicro1.setLayout(new GridBagLayout());

    bGreyLine = BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1, true);
    bTitled1 = BorderFactory.createTitledBorder(bGreyLine, "Length", TitledBorder.LEFT, TitledBorder.TOP);
    lenMicro1.setBorder(bTitled1);

    tLenUnit = new JTextField("0.0");
    tLenUnit.setColumns(10);
    lenMicro1.add(tLenUnit, new GBC(0, 0, 2, 1).setAnchor(GBC.WEST).setInsets(5, 5, 5, 5));

    cLenInUnit = new JComboBox<String>();
    cLenInUnit.addItem("");
    cLenInUnit.addItem("First");
    cLenInUnit.addItem("Second");
    cLenInUnit.setSelectedIndex(0);
    cLenInUnit.setPreferredSize(new Dimension(120, 25));
    lenMicro1.add(cLenInUnit, new GBC(2, 0, 3, 1));

    tLenResult = new JTextField("");
    tLenResult.setColumns(10);
    lenMicro1.add(tLenResult, new GBC(5, 0, 2, 1).setInsets(5, 5, 5, 5));

    cLenOutUnit = new JComboBox<String>();
    cLenOutUnit.addItem("First");
    cLenOutUnit.addItem("Second");
    cLenOutUnit.setSelectedIndex(1);
    cLenOutUnit.setPreferredSize(new Dimension(120, 25));
    lenMicro1.add(cLenOutUnit, new GBC(7, 0, 1, 1));

    // Area part:

    lenMicro2 = new JPanel();
    lenMicro2.setLayout(new GridBagLayout());

    bTitled2 = BorderFactory.createTitledBorder(bGreyLine, "Area", TitledBorder.LEFT, TitledBorder.TOP);
    lenMicro2.setBorder(bTitled2);

    tAreUnit = new JTextField("0.0");
    tAreUnit.setColumns(10);
    lenMicro2.add(tAreUnit, new GBC(0, 1, 2, 1).setAnchor(GBC.WEST).setInsets(5, 5, 5, 5));

    cAreInUnit = new JComboBox<String>();
    cAreInUnit.addItem("");
    cAreInUnit.addItem("One sqm");
    cAreInUnit.addItem("Two sqm");
    cAreInUnit.setSelectedIndex(0);
    cAreInUnit.setPreferredSize(new Dimension(120, 25));
    lenMicro2.add(cAreInUnit, new GBC(2, 1, 3, 1));

    tAreResult = new JTextField("");
    tAreResult.setColumns(10);
    lenMicro2.add(tAreResult, new GBC(5, 1, 2, 1).setInsets(5, 5, 5, 5));

    cAreOutUnit = new JComboBox<String>();
    cAreOutUnit.addItem("One sqm");
    cAreOutUnit.addItem("Two sqm");
    cAreOutUnit.setSelectedIndex(1);
    cAreOutUnit.setPreferredSize(new Dimension(120, 25));
    lenMicro2.add(cAreOutUnit, new GBC(7, 1, 1, 1));

    // Joining all lenMicroX panels into one:

    lenMicro.add(lenMicro1, new GBC(0, 0, 8, 1).setAnchor(GBC.FIRST_LINE_START).setInsets(5, 5, 5, 5).setIpad(10, 10));
    lenMicro.add(lenMicro2, new GBC(0, 1, 8, 1).setAnchor(GBC.LINE_START).setInsets(5, 5, 5, 5).setIpad(10, 10));

    volume = new JPanel();
    volume.setLayout(null);

    // Panel definition --begin:

    JTabbedPane tPane = new JTabbedPane();

    tPane.addTab("Length & Area", null, lenMicro, "Length & Area units");
    tPane.addTab("Volume", null, volume, "Volume units");
    add(tPane);

    // Panel --end.
}

public static void main(String[] args) {

    TestingGround app = new TestingGround();
    app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    app.pack();
    app.setVisible(true);

}

}

GridBagConstraints助手类来自Cay Horstmann和Gary Cornell的 Core Java ,可以在这里找到:http://www.horstmann.com/articles/GBC.java

我设法从Gagandeep的例子中弄清楚,面板可以放在上面,我们称之为母板。这样,每个子面板都可以有自己的边框。

第二件事:我决定使用GridBagLayout,因为它似乎是最准确的用于我的这个和其他项目。好吧,我仍然需要学习很多东西(例如,为了使组件与某些行对齐;-) [edit:刚刚将 setPreferredSize()添加到JComboBoxes;使布局更好看; - )])。

感谢大家的帮助和宝贵的提示!

The application after correction.