Java 使组件跨越GridBagLayout中的多个单元格
我正在构建一个简单的应用程序,我可以用它来放置一些问题和答案,并将它们保存到不同的数组列表中供以后使用,就像一张问答卡,一边有问题,另一边有答案。当我构建UI时,我碰到了一堵砖墙,似乎无法通过 在下面的代码中,我希望“下一步”按钮跨越多个列,并且比文本区域更宽 但是,当我试图将widthx变量设置为多列时,似乎什么都没有发生,有人能解释为什么会发生这种情况以及可能如何修复它吗? 谢谢Java 使组件跨越GridBagLayout中的多个单元格,java,swing,user-interface,layout-manager,gridbaglayout,Java,Swing,User Interface,Layout Manager,Gridbaglayout,我正在构建一个简单的应用程序,我可以用它来放置一些问题和答案,并将它们保存到不同的数组列表中供以后使用,就像一张问答卡,一边有问题,另一边有答案。当我构建UI时,我碰到了一堵砖墙,似乎无法通过 在下面的代码中,我希望“下一步”按钮跨越多个列,并且比文本区域更宽 但是,当我试图将widthx变量设置为多列时,似乎什么都没有发生,有人能解释为什么会发生这种情况以及可能如何修复它吗? 谢谢 好吧,你不小心碰到了一个怪癖。虽然布局看起来很简单,但它 我也花了一些时间来思考这个问题。 顺便说一下,水平拉伸
好吧,你不小心碰到了一个怪癖。虽然布局看起来很简单,但它 我也花了一些时间来思考这个问题。 顺便说一下,水平拉伸按钮并不是最佳的UI设计 原因在于管理者的构建方式。如果布局不包含在 一行中至少有两个组件,不可能跨越一个组件。 您的布局仅包含一列,因此,设置widthx>1不起作用 不工作。有两种方法可以解决这个问题:我们可以 虚拟组件到布局中,或者我们可以在布局前后放置一些空间 要减小其宽度的区域 我提供了三种解决方案:带虚拟标签的GridBagLayout,b GridBagLayout 带插图和带间隙的MIGC布局 解决方案1 两个标签放置在“下一步”按钮下方的第一个和第三个单元格中。 这不是一个干净的解决方案,主要是为了证明这个问题
gbc.fill = GridBagConstraints.NONE;
gbc.gridwidth = 1;
gbc.weighty = 0;
gbc.weightx = 0;
gbc.gridx = 0;
gbc.gridy = 3;
add(new JLabel(" "), gbc);
gbc.gridx = 2;
gbc.gridy = 3;
add(new JLabel(" "), gbc);
将创建两个虚拟标签。这些标签的宽度决定
左右间隙的宽度
解决方案2
在本例中,我们使用insets属性创建所需的
布局标签和文本区域的左侧和右侧插图更宽
那是按钮上的那个
gbc.insets.left = 5;
gbc.insets.right = 5;
gbc.gridwidth = 3;
gbc.weightx = 1;
gbc.weighty = 0;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(button, gbc);
左右插图从15px更改为5px。这样我们就实现了
按钮比其他组件宽
解决方案3
第三个解决方案是使用MigLayout管理器创建的。我们需要的更少
创建布局的代码
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import net.miginfocom.swing.MigLayout;
public class MigLayoutFillingCards extends JFrame {
public MigLayoutFillingCards() {
initUI();
setTitle("Quiz cards");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
setLayout(new MigLayout("wrap"));
JTextArea area1 = new JTextArea();
JTextArea area2 = new JTextArea();
area1.setBorder(
BorderFactory.createEtchedBorder()
);
area2.setBorder(
BorderFactory.createEtchedBorder()
);
JLabel label = new JLabel("Answer");
JButton btn = new JButton("Next");
add(area1, "w 250, h 150, grow, push, gap 15 15 0 0");
add(label, "gap 15 15 0 0");
add(area2, "w 250, h 150, grow, push, gap 15 15 0 0");
add(btn, "growx, pushx");
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MigLayoutFillingCards ex = new MigLayoutFillingCards();
ex.setVisible(true);
}
});
}
}
所需的布局是使用间隙约束创建的,这会添加额外的约束
组件两侧的间距。简短的回答是-gbc。gridwidth是允许组件跨越多个列的参数。例如,如果有3列4行,并且希望标签占据完整的顶行,则需要为标签指定第一个单元格。并设置gbc.gridwidth=3 GBC是基于的列。
package com.zetcode;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class FillingCards2 extends JPanel {
private JTextArea question;
private JTextArea answer;
private JButton button;
private JLabel label;
public FillingCards2() {
setupGUI();
}
private void setupGUI() {
question = new JTextArea(12, 22);
answer = new JTextArea(12, 22);
button = new JButton("Next");
label = new JLabel("Answer");
question.setBorder(
BorderFactory.createEtchedBorder()
);
answer.setBorder(
BorderFactory.createEtchedBorder()
);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.insets = new Insets(5, 15, 5, 15);
gbc.gridx = 1;
gbc.gridy = 0;
add(question, gbc);
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.NONE;
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weighty = 0;
gbc.weightx = 0;
add(label, gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 1;
gbc.gridy = 2;
gbc.weightx = 1;
gbc.weighty = 1;
add(answer, gbc);
gbc.insets.left = 5;
gbc.insets.right = 5;
gbc.gridwidth = 3;
gbc.weightx = 1;
gbc.weighty = 0;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(button, gbc);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Quiz cards");
FillingCards2 card = new FillingCards2();
frame.add(BorderLayout.CENTER, card);
frame.pack();
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
gbc.insets.left = 5;
gbc.insets.right = 5;
gbc.gridwidth = 3;
gbc.weightx = 1;
gbc.weighty = 0;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(button, gbc);
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import net.miginfocom.swing.MigLayout;
public class MigLayoutFillingCards extends JFrame {
public MigLayoutFillingCards() {
initUI();
setTitle("Quiz cards");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
setLayout(new MigLayout("wrap"));
JTextArea area1 = new JTextArea();
JTextArea area2 = new JTextArea();
area1.setBorder(
BorderFactory.createEtchedBorder()
);
area2.setBorder(
BorderFactory.createEtchedBorder()
);
JLabel label = new JLabel("Answer");
JButton btn = new JButton("Next");
add(area1, "w 250, h 150, grow, push, gap 15 15 0 0");
add(label, "gap 15 15 0 0");
add(area2, "w 250, h 150, grow, push, gap 15 15 0 0");
add(btn, "growx, pushx");
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MigLayoutFillingCards ex = new MigLayoutFillingCards();
ex.setVisible(true);
}
});
}
}