GridBagLayout无法正常工作?

时间:2015-01-29 01:11:42

标签: java swing jframe layout-manager gridbaglayout

我在JFrame中为我的组件使用GridBagLayout。我刚开始使用它,我一直在困惑自己。我想要的是;左上方的补丁说明,右侧的按钮(垂直),底部的播放按钮。我不确定这个问题究竟是什么,但你可以帮我组织一下吗?

这是我的代码:

package counter.main;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;

public class HomeFrame {

private static JPanel panel;
private static JButton play = new JButton("Play");
private static JPanel p;
File patch = new File(Main.class.getResource("/counter/res/ResourceCounterPatchNotes.txt").getFile());

//private static JLabel text;
public static JLabel greet = new JLabel("", SwingConstants.CENTER);

static JFrame frame = new JFrame("Resource Counter - Home"); {
    frame.setSize(800, 500);
    frame.setLocationRelativeTo(null);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.repaint();
    frame.revalidate();

    createView();
}

private void createView() {
    setIcon();

    panel = new JPanel();
    frame.getContentPane().add(panel);
    p = new JPanel();
    frame.getContentPane().add(p);
    p.setLayout(new FlowLayout(FlowLayout.CENTER, 400, 360));
    play.setPreferredSize(new Dimension(200, 70));
    p.add(play);
    JPanel p2 = new JPanel();
    frame.getContentPane().add(p2);
    p2.setLayout(new GridBagLayout());

    JButton button = new JButton("         Button         ");

    play.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                Thread.sleep(500);   
            } catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
            SelectionFrame.frame1.setVisible(true);
            frame.setVisible(false);
        }

    });

    JTextArea ta = new JTextArea();
    p2.setBackground(Color.BLACK);
    ta.setForeground(Color.WHITE);
    ta.setFont(new Font("Lucida Sans", Font.PLAIN, 12));

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.insets = new Insets(-150, 5, 5, 30);
    gbc.gridx = 0;
    gbc.gridy = 0;
    p2.add(ta, gbc);
    gbc.gridx = 1;
    gbc.gridy = 0;
    p2.add(button, gbc);
    /*gbc.anchor = GridBagConstraints.SOUTH;
    gbc.gridx = 0;
    gbc.gridy = 2;
    p2.add(play, gbc);*/

    try {
        ta.read(new FileReader(patch), null);
        ta.setEditable(false);
        //p2.add(ta, BorderLayout.WEST);
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
    } catch (IOException e1) {
        e1.printStackTrace();
    }


    greet.setFont(new Font( "Dialog", Font.BOLD, 20));
    frame.getContentPane().add(greet, BorderLayout.NORTH);

}

    public void setIcon() {
        frame.setIconImage(Toolkit.getDefaultToolkit().getImage(Main.class.getResource("/counter/res/Iron-Pickaxe-icon.png")));
    }
}

这是我得到的:

enter image description here

1 个答案:

答案 0 :(得分:3)

你的代码很乱(抱歉),我可能花了很多时间来解开你的复合布局,但重新开始会更容易。不是说你可能不会考虑使用复合布局概念,但我认为这就是让你陷入如此混乱的状态......

所以我基本上创建了一个简单的例子,说明我的“猜测”你的描述要求...

GridBagLayout

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.gridheight = gbc.REMAINDER;
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.BOTH;

            JTextArea patch = new JTextArea(10, 20);

            add(new JScrollPane(patch), gbc);

            gbc = new GridBagConstraints();
            gbc.gridx = 1;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            for (int index = 0; index < 6; index++) {
                add(new JButton("Button #" + index), gbc);
                gbc.gridy++;
            }

            gbc.gridx = 1;
            gbc.anchor = GridBagConstraints.SOUTH;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            add(new JButton("Play >"), gbc);


        }

    }

}

对于布局,最好从笔和纸开始,将您需要的元素组合在一起(例如右侧的按钮),并制定一个计划,说明如何将它们放置出来并制作视图创意原型。 ..

<强>更新

  

1)我怎样才能让TextArea和按钮之间有空间,按钮上有垂直空间?我尝试使用Insets,但我还没有以正确的方式排列数字。

insets是正确的方法......

gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(2, 8, 2, 4);
gbc.anchor = GridBagConstraints.NORTH;
for (int index = 0; index < 6; index++) {
    core.add(new JButton("Button #" + index), gbc);
    gbc.gridy++;
}
  

2)我想在屏幕中央底部的“播放”按钮,并让它更大

你“可以”用GridBagLayout执行此操作,但我决定不这样做,因为如果您不小心设置其他组件的约束,可能会导致一些问题,所以相反,我使用了BorderLayoutGridBagLayout的组合。

要使“播放”按钮变大,您可以修改字体或调整按钮的边距...

playButton.setMargin(new Insets(12, 12, 12, 12));

取决于您之后的效果

enter image description here

public class TestPane extends JPanel {

    public TestPane() {

        setLayout(new BorderLayout(0, 4));

        JPanel core = new JPanel(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridheight = GridBagConstraints.REMAINDER;
        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.fill = GridBagConstraints.BOTH;

        JTextArea patch = new JTextArea(10, 20);

        core.add(new JScrollPane(patch), gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(2, 8, 2, 4);
        gbc.anchor = GridBagConstraints.NORTH;
        for (int index = 0; index < 6; index++) {
            core.add(new JButton("Button #" + index), gbc);
            gbc.gridy++;
        }

        add(core);
        JButton playButton = new JButton("Play >");
        playButton.setMargin(new Insets(12, 12, 12, 12));
        add(playButton, BorderLayout.SOUTH);

    }

}