简体   繁体   English

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

[英]How to surround Java Swing components with border?

I'm building an application which will consist of few tabbed panels. 我正在构建一个由几个标签面板组成的应用程序。 On each of them, I'd like to put sets of components separated from each other by borders. 在每一个上,我都希望通过边框将各组件彼此分开。 It would look like: 它看起来像:

|- Titled Border 1 ---

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

|--------

|- Titled Border 2 ---

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

|--------

... and so forth.

When I tried to simply add new border, Titled Border 2, to the panel, it was added and covered the first one leaving components on top though. 当我尝试简单地向面板添加新的边框“标题边框2”时,它被添加并覆盖了第一个将组件留在顶部。 In some examples I saw many JPanels defined within one frame and each panel had its own border. 在一些示例中,我看到在一个帧内定义了许多JPanel,并且每个面板都有自己的边框。 It might work in my case but how to add these panels to be displayed within one tab? 它可能适用于我的情况,但如何添加这些面板以显示在一个选项卡中?

One of Oracle's tutorials shows exactly a tabbed pane with demo of many kinds of borders. Oracle的一个教程显示了一个带有多种边框演示的选项卡式窗格。 When I tried to edit it and put a component there, it appeared between two borders instead of being surrounded. 当我尝试编辑它并在其中放置一个组件时,它出现在两个边框之间而不是被包围。 And it was another option that was unsuccessful for me. 而另一种选择对我来说是不成功的。

Second thing is, I don't use any layout manager, components positions are fixed and honestly I would keep this setting. 第二件事是,我没有使用任何布局管理器,组件位置是固定的,老实说我会保留这个设置。 Or maybe you recommend using any layout manager in this specific case? 或者您可能建议在这种特定情况下使用任何布局管理器?

Would you have any hints on how to solve this problem? 您对如何解决这个问题有任何暗示吗?

Edit: it seems I'm not allowed yet to attach a screenshot, but here's the part of code taking care of displaying the borders: 编辑:似乎我还不允许附加截图,但这是代码的一部分,用于显示边框:

    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); 

The border titled "Length (2/2)" is displayed when the last two lines are uncommented. 取消注释最后两行时,将显示标题为“长度(2/2)”的边框。

When using Absolute Positioning , you have to provide Location for each and every component, that will become a part of the view. 使用绝对定位时 ,您必须为每个组件提供位置,这将成为视图的一部分。 Hence without looking at exactly what you doing it's hard to predict where exactly the things are going wrong. 因此,如果不确切地看到你在做什么,很难预测事情的确切位置。 Though using Layout Managers , will remove this big burden off your shoulders regarding placement of different components on the view. 虽然使用布局管理器 ,但是在视图上放置不同组件会消除这一巨大负担。

Moreover, you have to set the border for the respective component. 此外,您必须为相应组件设置边框。 So in no way I can assume that you added one component and it appeared between two borders (though considering the fact that you using Absolute Positioning, you might have given the wrong Co-ordinates for the said component on the view). 所以我决不会假设您添加了一个组件并且它出现在两个边框之间(尽管考虑到您使用绝对定位的事实,您可能在视图上为所述组件提供了错误的坐标)。 Please have a look at this example code, that might can help you a bit in this direction : 请看一下这个示例代码,它可以帮助您朝这个方向发展:

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();
            }
        });
    }
}

Here is the output of the same : 这是相同的输出:

BORDER_EXAMPLE

OK, so this solves a big part of my concerns regarding usage of Layout Manager and adding borders to groups of components: 好的,所以这解决了我对布局管理器的使用以及向组件组添加边框的大部分问题:

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 helper class is taken from Cay Horstmann's and Gary Cornell's Core Java and can be found here: http://www.horstmann.com/articles/GBC.java . GridBagConstraints辅助类来自Cay Horstmann和Gary Cornell的Core Java ,可以在这里找到: http//www.horstmann.com/articles/GBC.java

I managed to figure out from Gagandeep's example that panels can be put on top of, let's call it a mother-panel. 我设法从Gagandeep的例子中弄清楚,面板可以放在上面,我们称之为母板。 This way each of child-panels can have its own border. 这样每个子面板都可以有自己的边框。

Second thing: I decided to use GridBagLayout, as it seems to be the most accurate to be used in this and further projects of mine. 第二件事:我决定使用GridBagLayout,因为它似乎是最准确的用于我的这个和其他项目。 Well, I still have to learn a lot about it (for example, in order to make the components aligned to some lines ;-) [edit: just added setPreferredSize() to JComboBoxes; 好吧,我仍然需要学习很多东西(例如,为了使组件与某些行对齐;-) [edit:刚刚将setPreferredSize()添加到JComboBoxes; makes the layout better-looking ;-)]). 使布局更好看;-)])。

Thank you Everyone for help and valuable hints! 谢谢大家的帮助和宝贵的提示!

修正后的申请。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM