我正在尝试创建以下GUI:
但我制作的GUI是:
我的网格是什么样的:
我不明白为什么我得到这个输出,因为我绘制了一个图表以帮助代码,它似乎有用。
addComp添加方法将输入组件添加到给定(x,y)位置和给定组件宽度和高度的输入面板。
代码:
import javax.swing.*;
import java.awt.*;
public class GUIError extends JFrame {
//initialise all the components
JPanel mainPanel = new JPanel();
JTextField txtDisplay = new JTextField();
JButton btnA = new JButton("A");
JButton btnB = new JButton("B");
JButton btnC = new JButton("C");
JButton btnD = new JButton("D");
JButton btnE = new JButton("E");
JButton btnF = new JButton("F");
JButton btnWA = new JButton("WA");
JButton btnWB = new JButton("WB");
JButton btnWC = new JButton("WC");
JButton btnWD = new JButton("WD");
private void addComp(JPanel panel, JComponent comp, int xPos, int yPos, int compWidth, int compHeight) {
GridBagConstraints gridConstraints = new GridBagConstraints();
gridConstraints.gridx = xPos;
gridConstraints.gridy = yPos;
gridConstraints.gridwidth = compWidth;
gridConstraints.gridheight = compHeight;
gridConstraints.weightx = 0.5;
gridConstraints.weighty = 0.5;
gridConstraints.insets = new Insets(5, 5, 5, 5);
gridConstraints.anchor = GridBagConstraints.CENTER;
gridConstraints.fill = GridBagConstraints.BOTH;
panel.add(comp, gridConstraints);
}
public static void main(String[] args) {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}
catch (Exception e) { }
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// create frame
JFrame frame = new JFrame("Calculator");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationRelativeTo(null);
Container c = frame.getContentPane();
// create GUI within frame
new GUIError(c);
// finish frame definition
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
}
});
}
public GUIError(Container cont) {
cont.setPreferredSize(new Dimension(610, 250));
// parent panel containes every other panel
mainPanel.setLayout(new GridBagLayout());
// text display
txtDisplay.setEditable(false);
addComp(mainPanel, txtDisplay, 0, 0, 12, 2); // width 16, height 2
addComp(mainPanel, btnA, 0, 2, 2, 1);
addComp(mainPanel, btnB, 2, 2, 2, 1);
addComp(mainPanel, btnC, 4, 2, 2, 1);
addComp(mainPanel, btnD, 6, 2, 2, 1);
addComp(mainPanel, btnE, 8, 2, 2, 1);
addComp(mainPanel, btnF, 10, 2, 2, 1);
addComp(mainPanel, btnWA, 0, 3, 3, 1);
addComp(mainPanel, btnWB, 3, 3, 3, 1);
addComp(mainPanel, btnWC, 6, 3, 3, 1);
addComp(mainPanel, btnWD, 9, 3, 3, 1);
cont.add(mainPanel);
}
}
答案 0 :(得分:5)
使用GridBagLayout
可以很容易地实现,如下面的示例所示。您只需为每个 ROW 分别取两个JPanel
个。两者都使用GridBagLayout
,并将组件添加到第一行, weightx = 0.16 ,因为每个JButton
假定占用这么多区域,而第二行 weightx = 0.25 因为,这是每个JButton
沿着 X方向占据的区域
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridBagExample {
private static final int SIZE = 10;
private JButton[] buttons;
private GridBagConstraints gbc;
public GridBagExample() {
buttons = new JButton[SIZE];
gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
}
private void createAndDisplayGUI() {
JFrame frame = new JFrame("Grid Game");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridLayout(2, 1, 5, 5));
contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel topPanel = new JPanel();
JTextField textField = new JTextField(10);
//topPanel.add(textField);
JPanel buttonPanel = new JPanel(new GridLayout(2, 1, 5, 5));
JPanel headerPanel = new JPanel(new GridBagLayout());
buttons[0] = new JButton("A");
addComp(headerPanel, buttons[0], 0, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);
buttons[1] = new JButton("B");
addComp(headerPanel, buttons[1], 1, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);
buttons[2] = new JButton("C");
addComp(headerPanel, buttons[2], 2, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);
buttons[3] = new JButton("D");
addComp(headerPanel, buttons[3], 3, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);
buttons[4] = new JButton("E");
addComp(headerPanel, buttons[4], 4, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);
buttons[5] = new JButton("F");
addComp(headerPanel, buttons[5], 5, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);
JPanel footerPanel = new JPanel(new GridBagLayout());
buttons[6] = new JButton("WA");
addComp(footerPanel, buttons[6], 0, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH);
buttons[7] = new JButton("WB");
addComp(footerPanel, buttons[7], 1, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH);
buttons[8] = new JButton("WC");
addComp(footerPanel, buttons[8], 2, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH);
buttons[9] = new JButton("WD");
addComp(footerPanel, buttons[9], 3, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH);
buttonPanel.add(headerPanel);
buttonPanel.add(footerPanel);
contentPane.add(textField);
contentPane.add(buttonPanel);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private void addComp(JPanel panel, JComponent comp, int x, int y,
double wx, double wy, int gw, int gh, int fill) {
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = wx;
gbc.weighty = wy;
gbc.gridwidth = gw;
gbc.gridheight = gh;
gbc.fill = fill;
panel.add(comp, gbc);
}
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GridBagExample().createAndDisplayGUI();
}
});
}
}
输出: 的的GridBagLayout:强>
GridLayout
可以实现相同的输出,如果GridBagLayout
在这种情况下不是必需的话,如下例所示:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridBagExample {
private static final int SIZE = 10;
private JButton[] buttons;
public GridBagExample() {
buttons = new JButton[SIZE];
}
private void createAndDisplayGUI() {
JFrame frame = new JFrame("Grid Game");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridLayout(2, 1, 5, 5));
contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel topPanel = new JPanel();
JTextArea tArea = new JTextArea(5, 30);
JScrollPane scroller = new JScrollPane();
scroller.setViewportView(tArea);
topPanel.add(scroller);
JPanel buttonPanel = new JPanel(new GridLayout(2, 1, 5, 5));
JPanel headerPanel = new JPanel(new GridLayout(1, 0, 5, 5));
buttons[0] = new JButton("A");
headerPanel.add(buttons[0]);
buttons[1] = new JButton("B");
headerPanel.add(buttons[1]);
buttons[2] = new JButton("C");
headerPanel.add(buttons[2]);
buttons[3] = new JButton("D");
headerPanel.add(buttons[3]);
buttons[4] = new JButton("E");
headerPanel.add(buttons[4]);
buttons[5] = new JButton("F");
headerPanel.add(buttons[5]);
JPanel footerPanel = new JPanel(new GridLayout(1, 0, 5, 5));
buttons[6] = new JButton("WA");
footerPanel.add(buttons[6]);
buttons[7] = new JButton("WB");
footerPanel.add(buttons[7]);
buttons[8] = new JButton("WC");
footerPanel.add(buttons[8]);
buttons[9] = new JButton("WD");
footerPanel.add(buttons[9]);
buttonPanel.add(headerPanel);
buttonPanel.add(footerPanel);
contentPane.add(topPanel);
contentPane.add(buttonPanel);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GridBagExample().createAndDisplayGUI();
}
});
}
}
输出: 的 GridLayout的:强>
答案 1 :(得分:5)
通常我会制作单独的面板,但嘿,谁不喜欢挑战?
问题在于某些列没有为GBL定义好(没有单个组件定义其宽度),因此按钮WA不知道要覆盖按钮B的一半等多远,等等。 / p>
因此,我在构成所需部分的列中添加了一些零宽度的间隔符。
全部在一个小组中:
import java.awt.*;
import javax.swing.*;
public class GridBagDemo3 implements Runnable
{
private JPanel panel;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new GridBagDemo3());
}
public void run()
{
JTextArea text = new JTextArea(10,10);
JButton btnA = new JButton("A");
JButton btnB = new JButton("B");
JButton btnC = new JButton("C");
JButton btnD = new JButton("D");
JButton btnE = new JButton("E");
JButton btnF = new JButton("F");
JButton btnWA = new JButton("WA");
JButton btnWB = new JButton("WB");
JButton btnWC = new JButton("WC");
JButton btnWD = new JButton("WD");
panel = new JPanel(new GridBagLayout());
add(text, 0,0, 12,1);
add(btnA, 0,1, 2,1);
add(btnB, 2,1, 2,1);
add(btnC, 4,1, 2,1);
add(btnD, 6,1, 2,1);
add(btnE, 8,1, 2,1);
add(btnF, 10,1, 2,1);
add(btnWA, 0,2, 3,1);
add(btnWB, 3,2, 3,1);
add(btnWC, 6,2, 3,1);
add(btnWD, 9,2, 3,1);
// SPACERS: define the 2 columns that button B spans
// so that WA and WB can split B, and same for button E
add(null, 2,2, 1,1);
add(null, 3,2, 1,1);
add(null, 8,2, 1,1);
add(null, 9,2, 1,1);
JFrame frame = new JFrame("Grig Bag");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
private void add(Component comp, int x, int y, int colspan, int rowspan)
{
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = colspan;
gbc.gridheight = rowspan;
gbc.weighty = .1;
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(5,5,5,5);
if (comp != null)
{
gbc.weightx = 1;
}
else
{
comp = Box.createHorizontalGlue();
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0.1;
gbc.weighty = 0;
}
panel.add(comp, gbc);
}
}
答案 2 :(得分:4)
@Matthieu写道 -
你能详细说明GBC是基于列吗?听起来像是一个 我注意到一个问题的解释......
我认为这种方式是GridBagLayout设计的,我总是使用JLabel(没有Borders :-)作为矩阵...
import java.awt.*;
import javax.swing.*;
public class CopyTextNorthPanel extends JPanel {
private static final long serialVersionUID = 1L;
private JLabel hidelLabel;
private JLabel firstLabel;
private JTextField firstText;
public CopyTextNorthPanel() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
for (int k = 0; k < 50; k++) {
hidelLabel = new JLabel(" ");
hidelLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 0.5;
gbc.weighty = 0.5;
gbc.gridx = k;
gbc.gridy = 0;
add(hidelLabel, gbc);
}
for (int k = 0; k < 5; k++) {
firstLabel = new JLabel("Testing Label : ", SwingConstants.RIGHT);
firstLabel.setFont(new Font("Serif", Font.BOLD, 20));
firstLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0, 0, 5, 0);
gbc.gridx = 0;
gbc.gridwidth = 8;
gbc.gridy = k + 1;
add(firstLabel, gbc);
}
for (int k = 0; k < 5; k++) {
firstText = new JTextField("Testing TextField");
firstText.setFont(new Font("Serif", Font.BOLD, 20));
firstText.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0, 0, 5, 0);
gbc.gridx = 9;
gbc.gridwidth = k + 8;
gbc.gridy = k + 1;
add(firstText, gbc);
}
for (int k = 0; k < 5; k++) {
firstLabel = new JLabel("Testing Label : ", SwingConstants.RIGHT);
firstLabel.setFont(new Font("Serif", Font.BOLD, 20));
firstLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0, 0, 5, 0);
gbc.gridx = 20 + k;
gbc.gridwidth = 8;
gbc.gridy = k + 1;
add(firstLabel, gbc);
}
for (int k = 0; k < 5; k++) {
firstText = new JTextField("Testing TextField");
firstText.setFont(new Font("Serif", Font.BOLD, 20));
firstText.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(0, 0, 5, 0);
gbc.gridx = 29 + k;
gbc.gridwidth = 21 - k;
gbc.gridy = k + 1;
add(firstText, gbc);
}
}
}
答案 3 :(得分:3)
如果您仍然有兴趣了解您的错误: 格&#39;布局不是FlowLayout,你不能简单地添加组件,它会在程序读取它的同一时刻绘制对象。在网格的情况下,虚拟机首先读取所有对象而不是构建网格,列的数量是在具有最大列数的行的基础上确定的。因此,您最好选择12列(因此您可以避免创建新的&#34; Panel&#34;以及备用系统资源),但为了做到这一点,您应该添加12个空格(不仅仅是空的)其中一行中的零大小)
// text display
txtDisplay.setEditable(false);
addComp(mainPanel, txtDisplay, 0, 0, 12, 2); // width 16, height 2
//now go with empty spaces
for(int i=0;i<12;i++){
GridBagConstraints gridConstraints = new GridBagConstraints();
gridConstraints.gridx = i; //12 times "i"
gridConstraints.gridy = 1; //you left y=1 empty, so why don't use it
gridConstraints.gridwidth = 1; //one column = one space in grid
gridConstraints.gridheight = 0; //we don't want it to occupied any space
gridConstraints.weightx = 0.5;
gridConstraints.weighty = 0.5;
gridConstraints.insets = new Insets(0, 0, 0, 0); //same reason, we don't want it to occupied any space
gridConstraints.anchor = GridBagConstraints.CENTER;
gridConstraints.fill = GridBagConstraints.BOTH ;
mainPanel.add(Box.createHorizontalGlue(), gridConstraints);
}
addComp(mainPanel, btnA, 0, 2, 2, 1);
addComp(mainPanel, btnB, 2, 2, 2, 1);
addComp(mainPanel, btnC, 4, 2, 2, 1);
addComp(mainPanel, btnD, 6, 2, 2, 1);
addComp(mainPanel, btnE, 8, 2, 2, 1);
addComp(mainPanel, btnF, 10, 2, 2, 1);
addComp(mainPanel, btnWA, 0, 3, 3, 1);
addComp(mainPanel, btnWB, 3, 3, 3, 1);
addComp(mainPanel, btnWC, 6, 3, 3, 1);
addComp(mainPanel, btnWD, 9, 3, 3, 1);