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

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

|- 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)”的边框。

使用绝对定位时 ,您必须为每个组件提供位置,这将成为视图的一部分。 因此,如果不确切地看到你在做什么,很难预测事情的确切位置。 虽然使用布局管理器 ,但是在视图上放置不同组件会消除这个巨大的负担。

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

 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

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

 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 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(); 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(); 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(); 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(); 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; 使布局更好看;-)])。

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

修正后的申请。