使用Java pack()方法

我不能使pack()方法工作。 我尝试了几件事。 我的代码目前看起来像这样:

第1类:

public static void main( String[] args ) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { JavaGui mygui = new JavaGui(); // mygui.setSize(1154, 753); mygui.setVisible(true); mygui.pack(); 

第2类:

 public class JavaGui extends javax.swing.JFrame { public JavaGui() { getContentPane().setLayout(null); .. getContentPane().add(panelLeft); ... getContentPane().add(panelRight); 

我尝试将pack方法放在任何地方,但它不能用这种方式添加gui元素。 有什么建议吗? 我也尝试将所有内容添加到JFrame而不是getContentPane(),但我也无法做到这一点。

  1. 不要将null布局与pack()一起使用。 pack方法告诉布局管理器和组件以最佳方式调整自己的大小,如果你使用null布局,那么gui可能会缩小到最小的大小,因为没有布局可以将它们保持在一起。
  2. 在大多数情况下,根本不要使用空布局。 利用这些风险,您可以创建几乎不可能扩展,改进和调试的严格GUI。
  3. 不要使用setSize(...)pack() 。 布局主要考虑组件的首选尺寸,而不是尺寸。

代替:

  1. 使用嵌套JPanel的令人愉悦和明智的组合,每个都使用自己的布局管理器。
  2. 让组件和布局管理器自己resize。
  3. 然后打包应该有帮助。
  4. 我做的一般顺序是将所有组件添加到GUI,然后调用pack() ,然后setLocationByPlatform(true) (我认为),然后setVisible(true)

如需更好的帮助,请查看Swing Layout Manager教程 。

以下是本网站上使用各种布局管理器的其他问题的几个示例:

  • BorderLayout和GridLayout的组合来创建计算器
  • BorderLayout和BoxLayout组合标签和JTextFields
  • 使用GridBagLayout创建灵活的标签/文本域网格

我会建议初学者建立摇摆guis,使用一个内置的gui设计师,如eclipse和windowbuilder或netbeans与matisse的良好的ide。 它将帮助您构建所需gui的原型,并让您深入了解如何在源代码中完成布局。 尝试使用不同的布局以及更改某些值时发生的情况。

一个人不会简单地建立一个表现良好的gui而不了解布局是如何工作的,所以做推荐的教程并查看Hovercraft Full Of Eels已经发布的例子是绝对必要的。

对于你的情况,我只是猜你在做什么。 因为你提到左右面板我建议使用JSplitPane,它可以让你的屏幕在两个可以自定义大小和方向的区域中划分。

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSplitPane; public class JavaGui extends JFrame { //SerialVersionId http://stackoverflow.com/questions/285793/what-is-a-serialversionuid-and-why-should-i-use-it private static final long serialVersionUID = 1L; public static void main(String[] args) { //Calls to Gui Code must happen on the event dispatch thread that the gui does not get stuck EventQueue.invokeLater(new Runnable() { @Override public void run() { new JavaGui().setVisible(true); } }); } public JavaGui() { // Set the desired size of the frame to determine the maximum size of its components setPreferredSize(new Dimension(1024, 768)); // Set the default close operation, if press x on frame, destroy the frame and exit the application - others are just destroy the frame or just hide the // frame setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // BorderLayout because we just need a centric gui with one component, here JSplitPane in full size getContentPane().setLayout(new BorderLayout(0, 0)); // JsplitPane is a bit special as it depends on the divider location between both panels, for the sake of a small example we take the default -1, JSplitPane splitPane = new JSplitPane(); // 0.5 divides extra space equally to left and right component when resizing the frame - so specifiying a size for the left and right component is not // necessary // use the divider location default -1 to let the width of the left component decide where the right component begins, in that case because of the // resize weight half and half splitPane.setDividerLocation(-1); splitPane.setResizeWeight(0.5); getContentPane().add(splitPane, BorderLayout.CENTER); // For the panels the same layout as default as the intention is not stated in your question JPanel leftPanel = new JPanel(); splitPane.setLeftComponent(leftPanel); leftPanel.setLayout(new BorderLayout(0, 0)); JPanel rightPanel = new JPanel(); splitPane.setRightComponent(rightPanel); rightPanel.setLayout(new BorderLayout(0, 0)); // Add a button Panel to the south for doing something - flow layout for letting the components flow to the right side JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); getContentPane().add(buttonPanel, BorderLayout.SOUTH); // Close Button for closing the frame JButton btnExit = new JButton("Destroy this frame, but let application run"); btnExit.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dispose(); } }); buttonPanel.add(btnExit); // Set every component to its preferred size pack(); // Make it visible setVisible(true); } } 

如果您希望JFrame使用null布局,请重新排列代码,使其如下所示:

 public class JavaGui extends javax.swing.JFrame { public JavaGui() { setMinimumSize(1154, 753); // Make sure you do setMinimumSize() instead of setSize() when using pack() so that the JFrame does not shrink to 0 size setLayout(null); add(panelLeft); add(panelRight); pack(); } // Next is main method 

主要:

 public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new JavaGui().setVisible(true); // Do not do any formatting for your JFrame here } }); 

之前,您在设置可见修改JFrame ,因此除了pack()之外通常不起作用。 如果您使用的是匿名内部类,则JFrame所有组件和设置都不应位于main方法中。

您还可以使用其他布局。 空布局用于在精确位置获取像素,用于高级GUI设计,例如创建自定义GUI,但似乎您正在使用JPanel制作通用GUI。 为此,我建议使用GridBagLayout ,如果框架resize并且易于使用,它会使所有内容保持居中。 要使用GridBagLayout ,您必须替换setLayout(null); with setLayout(new GridBagLayout()); 并设置GridBagConstraints 。 下面是一个使用组件和GridBagLayout制作面板的示例代码:

 JPanel pane = new JPanel(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); if (shouldFill) { //natural height, maximum width c.fill = GridBagConstraints.HORIZONTAL; } //For each component to be added to this container: //...Create the component... //...Set instance variables in the GridBagConstraints instance... pane.add(theComponent, c); // Source: Oracle Docs