如何解决如何在GridBagLayout中垂直对齐不同大小的按钮?
我从挥杆开始,我对如何在GridBagLayout中对齐元素有一些疑问,我不确定这是否是正确的方法,请提出建议。
我有以下代码
import javax.swing.*;
import java.awt.*;
public class App {
public void start() {
JPanel mainPanel = new JPanel(new FlowLayout());
mainPanel.setBorder(BorderFactory.createLineBorder(Color.CYAN,20));
//buttons for initial options
JButton button1 = new JButton("This is option A");
JButton button2 = new JButton("option B");
JButton button3 = new JButton("Another text");
JPanel second = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER;
second.setBackground(Color.GREEN);
second.add(button1,gbc);
second.add(button2,gbc);
second.add(button3,gbc);
mainPanel.add(second,BorderLayout.CENTER);
//frame configuration
JFrame frame = new JFrame();
frame.setContentPane(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setResizable(false);
}
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
SwingUtilities.invokeLater(() -> new App().start());
}
}
我的目标是产生以下输出:
到目前为止,我已经尝试过使用垂直对齐的BoxLayout并可以使用,但是问题是它会覆盖按钮的首选大小,并且我希望它们的宽度都相同。
此外,我尝试使用GridLayout和BorderLayout将元素添加到NORTH,CENTER和SOUTH,但是按钮的大小发生了变化。
建议将元素居中但保持其尺寸不变的方法是什么?
解决方法
我会嵌套布局:
- 一个JPanel,用于保存按钮并使用
new GridLayout(0,1,vGap)
-一种网格,其中包含一列和可变数量的行,按钮之间具有vGap间隙。 - 将该JPanel添加到另一个使用GridBagLayout的JPanel中,并以默认方式(无GridBagConstraints)添加它,这会将第一个JPanel居中放置在第二个JPanel中。显然,这一定是所需的大小。可以通过以下任一方式来实现
- 以明智的方式覆盖
getPreferredSize()
- 打电话给
setPreferredSize(new Dimension(someWidth,someHeight))
-简直不干净 - 为此设置边框,特别是
BorderFactor.EmptyBorder(gap,gap,gap)
,其中gap是JPanel周围边框的大小...
完成。
使用GridBagLayout的测试代码:
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.*;
public class ButtonLayout extends JPanel {
public static final int MY_WIDTH = 750;
public static final int MY_HEIGHT = 500;
private static final float BTN_SIZE = 24f;
private String[] buttonTexts = {"This is Option A","Option B","Something Else Entirely"};
public ButtonLayout() {
int colGap = 20;
JPanel buttonPanel = new JPanel(new GridLayout(0,colGap));
for (String btnText : buttonTexts) {
JButton button = new JButton(btnText);
// set first letter of text as mnemonic (alt-char shortcut)
int mnemonic = (int) btnText.charAt(0);
button.setMnemonic(mnemonic);
// make button bigger by increasing its font
button.setFont(button.getFont().deriveFont(BTN_SIZE));
// add to the GridLayout-using JPanel
buttonPanel.add(button);
}
// set layout of main panel to GridBag
setLayout(new GridBagLayout());
// add the button panel in a "default" manner (no constraints)
// which centers this panel
add(buttonPanel);
}
@Override
public Dimension getPreferredSize() {
Dimension superSize = super.getPreferredSize();
int width = Math.max(MY_WIDTH,superSize.width);
int height = Math.max(MY_HEIGHT,superSize.height);
return new Dimension(width,height);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
ButtonLayout mainPanel = new ButtonLayout();
JFrame frame = new JFrame("ButtonLayout");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
使用EmptyBorder的示例2:
import java.awt.GridLayout;
import javax.swing.*;
@SuppressWarnings("serial")
public class ButtonLayout extends JPanel {
public static final int MY_WIDTH = 750;
public static final int MY_HEIGHT = 500;
private static final float BTN_SIZE = 24f;
private String[] buttonTexts = {"This is Option A",colGap));
for (String btnText : buttonTexts) {
JButton button = new JButton(btnText);
// set first letter of text as mnemonic (alt-char shortcut)
int mnemonic = (int) btnText.charAt(0);
button.setMnemonic(mnemonic);
// make button bigger by increasing its font
button.setFont(button.getFont().deriveFont(BTN_SIZE));
// add to the GridLayout-using JPanel
buttonPanel.add(button);
}
add(buttonPanel);
int top = 60;
int left = top;
int bottom = 2 * top;
int right = left;
setBorder(BorderFactory.createEmptyBorder(top,left,bottom,right));
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
ButtonLayout mainPanel = new ButtonLayout();
JFrame frame = new JFrame("ButtonLayout");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
,
我不确定我是否完全理解这个问题,但是例如,如果您想垂直对齐按钮,但是允许它们保持其首选大小,例如,不要提供任何类型的fill
约束
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SoTest {
public static void main(String[] args) {
new SoTest();
}
public SoTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
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.gridwidth = GridBagConstraints.REMAINDER;
add(new JButton("This is option A"),gbc);
add(new JButton("Option B"),gbc);
add(new JButton("Another button"),gbc);
}
}
}
或者,如果您希望它们具有相同的宽度,请使用fill
约束
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SoTest {
public static void main(String[] args) {
new SoTest();
}
public SoTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
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.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.BOTH;
add(new JButton("This is option A"),gbc);
}
}
}
如果要混合使用更复杂的布局,则应考虑使用复合布局
但是等等,没有轮廓...
因此,您可能会通过多种方式做到这一点,例如,您可以使用CompoundBorder
....
setBorder(new CompoundBorder(new LineBorder(Color.CYAN,16),new EmptyBorder(32,32,32)));
但是细节决定成败
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。