使用Java pack()方法

时间:2014-09-09 22:19:45

标签: java swing layout-manager 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(),但我也无法做到这一点。

3 个答案:

答案 0 :(得分:15)

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

    1. 使用令人愉悦且合理的嵌套JPanel组合,每个组合都使用自己的布局管理器。
    2. 让组件和布局管理器自行调整大小。
    3. 然后打包应该有帮助。
    4. 我所做的一般顺序是将所有组件添加到GUI,然后调用pack(),然后调用setLocationByPlatform(true)(我认为),然后调用setVisible(true)
    5. 如需更好的帮助,请查看Swing Layout Manager Tutorials

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

答案 1 :(得分:2)

我会建议初学者使用内置gui设计师(例如eclipse和windowbuilder)或netbeans with matisse来构建swing guis。它将帮助您构建所需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);
    }
}

答案 2 :(得分:-1)

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

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,如果框架调整大小并且易于使用,它会使所有内容保持居中。要使用GridBagLayout,您必须将setLayout(null);替换为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