底部面板的垂直对齐
Vertical alignment of a bottom panel
我想在底部面板中垂直对齐 3 个按钮。
这是我写的:
ClientWindow(){
pickBtn = new JButton();
attackBtn = new JButton();
placeBtn = new JButton();
JPanel userPanel = new JPanel();
userPanel.setPreferredSize(new Dimension(100,100));
userPanel.setBackground(Color.red);
JFrame frame = new JFrame();
frame.setTitle("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.setResizable(false);
frame.setSize(1280,720);
frame.setLocationRelativeTo(null);
frame.add(userPanel,BorderLayout.SOUTH);
userPanel.add(pickBtn);
userPanel.add(attackBtn);
userPanel.add(placeBtn);
frame.setVisible(true);
}
如何垂直对齐它们?
看看 在容器中布置组件
例如,以下使用 GridBagLayout
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JLabel label = new JLabel("This is just here to make some content");
label.setBorder(new EmptyBorder(32, 32, 32, 32));
JFrame frame = new JFrame();
frame.add(label);
frame.add(new UserPanel(), BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class UserPanel extends JPanel {
public UserPanel() {
JButton pickBtn = new JButton("Pick");
JButton attackBtn = new JButton("Attack");
JButton placeBtn = new JButton("Place");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(pickBtn, gbc);
add(attackBtn, gbc);
add(placeBtn, gbc);
}
}
}
做一个ButtonLayout
重要
请注意:以下内容旨在替换上面示例中的 GridBagLayout
,因为 GridBagLayout
很复杂,为此目的可能有点矫枉过正
很久以前,我可以理解 ButtonLayout
的一个非常简洁的概念,它基本上提供了一个简单的布局管理器来布局按钮,类似于大多数 OS 所做的(即,按钮大小相同)。
以下是该概念的一个非常基本的示例。
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.LayoutManager2;
import java.awt.Point;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new UserPanel());
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class UserPanel extends JPanel {
public UserPanel() {
JButton pickBtn = new JButton("Pick");
JButton attackBtn = new JButton("Attack");
JButton placeBtn = new JButton("Place");
setBorder(new LineBorder(Color.BLACK));
setLayout(new ButtonLayout(ButtonLayout.Alignment.VERTICAL, ButtonLayout.Anchor.TRAILING));
add(pickBtn);
add(attackBtn);
add(placeBtn);
}
}
public class ButtonLayout implements LayoutManager2 {
public enum Alignment {
VERTICAL, HORIZONTAL
}
public enum Anchor {
LEADING, CENTER, TRAILING
}
private Alignment alignment;
private Anchor anchor;
private int padding;
private Dimension virtualBounds;
public ButtonLayout() {
this(Alignment.HORIZONTAL, Anchor.TRAILING, 0);
}
public ButtonLayout(Alignment alignment, Anchor anchor) {
this(alignment, anchor, 0);
}
public ButtonLayout(Alignment alignment, Anchor anchor, int padding) {
this.alignment = alignment;
this.padding = padding;
this.anchor = anchor;
}
public Alignment getAlignment() {
return alignment;
}
public Anchor getAnchor() {
return anchor;
}
protected int getPadding() {
return padding;
}
protected int getTotalPadding(Container parent) {
int padding = getPadding();
return (padding * parent.getComponentCount()) - padding;
}
@Override
public void addLayoutComponent(Component comp, Object constraints) {
}
@Override
public void addLayoutComponent(String name, Component comp) {
}
@Override
public void removeLayoutComponent(Component comp) {
}
@Override
public void invalidateLayout(Container target) {
virtualBounds = null;
}
protected Dimension virtualLayout(Container parent) {
if (virtualBounds != null) {
return virtualBounds;
}
int maxWidth = 0;
int maxHeight = 0;
for (Component component : parent.getComponents()) {
Dimension preferredSize = component.getPreferredSize();
maxHeight = Math.max(maxHeight, preferredSize.height);
maxWidth = Math.max(maxWidth, preferredSize.width);
}
int padding = 0;
int width = 0;
int height = 0;
int componentCount = parent.getComponentCount();
switch (alignment) {
case HORIZONTAL:
width = (maxWidth * componentCount) + getTotalPadding(parent);
height = maxHeight;
break;
case VERTICAL:
width = maxWidth;
height = (maxHeight * componentCount) + getTotalPadding(parent);
break;
}
virtualBounds = new Dimension(width, height);
return virtualBounds;
}
@Override
public Dimension maximumLayoutSize(Container parent) {
return virtualLayout(parent);
}
@Override
public Dimension preferredLayoutSize(Container parent) {
return virtualLayout(parent);
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return virtualLayout(parent);
}
@Override
public float getLayoutAlignmentX(Container target) {
return 0.5f;
}
@Override
public float getLayoutAlignmentY(Container target) {
return 0.5f;
}
@Override
public void layoutContainer(Container parent) {
int maxWidth = 0;
int maxHeight = 0;
for (Component component : parent.getComponents()) {
Dimension preferredSize = component.getPreferredSize();
maxHeight = Math.max(maxHeight, preferredSize.height);
maxWidth = Math.max(maxWidth, preferredSize.width);
}
Dimension defaultSize = new Dimension(maxWidth, maxHeight);
Point point = offsetForAnchor(parent, defaultSize);
int xDelta = 0;
int yDelta = 0;
switch (alignment) {
case HORIZONTAL:
xDelta = getPadding() + defaultSize.width;
break;
case VERTICAL:
yDelta = getPadding() + defaultSize.height;
break;
}
for (Component component : parent.getComponents()) {
component.setSize(defaultSize);
component.setLocation(point);
point = new Point(point.x + xDelta, point.y + yDelta);
}
}
protected Point offsetForAnchor(Container parent, Dimension defaultSize) {
switch (anchor) {
case LEADING:
return leadingOffSet(parent, defaultSize);
case TRAILING:
return trailingOffSet(parent, defaultSize);
case CENTER:
return centerOffSet(parent, defaultSize);
}
return new Point(0, 0);
}
protected Point leadingOffSet(Container parent, Dimension defaultSize) {
Point point = new Point(0, 0);
switch (alignment) {
case HORIZONTAL:
point.x = padding;
point.y = (parent.getHeight() - defaultSize.height) / 2;
break;
case VERTICAL:
point.x = (parent.getWidth() - defaultSize.width) / 2;
point.y = padding;
break;
}
return point;
}
protected Point trailingOffSet(Container parent, Dimension defaultSize) {
Point point = new Point(0, 0);
int componentCount = parent.getComponentCount();
switch (alignment) {
case HORIZONTAL:
int totalWidth = (defaultSize.width * componentCount) + getTotalPadding(parent);
point.x = parent.getWidth() - totalWidth;
point.y = (parent.getHeight() - defaultSize.height) / 2;
break;
case VERTICAL:
int totalHeight = (defaultSize.height * componentCount) + getTotalPadding(parent);
point.x = (parent.getWidth() - defaultSize.width) / 2;
point.y = parent.getHeight() - totalHeight;
break;
}
return point;
}
protected Point centerOffSet(Container parent, Dimension defaultSize) {
Point point = new Point(0, 0);
int componentCount = parent.getComponentCount();
switch (alignment) {
case HORIZONTAL: {
int totalWidth = (defaultSize.width * componentCount) + getTotalPadding(parent);
point.x = (parent.getWidth() - totalWidth) / 2;
point.y = (parent.getHeight() - defaultSize.height) / 2;
}
break;
case VERTICAL: {
int totalHeight = (defaultSize.height * componentCount) + getTotalPadding(parent);
point.x = (parent.getWidth() - defaultSize.width) / 2;
point.y = (parent.getHeight() - totalHeight) / 2;
}
break;
}
return point;
}
}
}
我想在底部面板中垂直对齐 3 个按钮。
这是我写的:
ClientWindow(){
pickBtn = new JButton();
attackBtn = new JButton();
placeBtn = new JButton();
JPanel userPanel = new JPanel();
userPanel.setPreferredSize(new Dimension(100,100));
userPanel.setBackground(Color.red);
JFrame frame = new JFrame();
frame.setTitle("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.setResizable(false);
frame.setSize(1280,720);
frame.setLocationRelativeTo(null);
frame.add(userPanel,BorderLayout.SOUTH);
userPanel.add(pickBtn);
userPanel.add(attackBtn);
userPanel.add(placeBtn);
frame.setVisible(true);
}
如何垂直对齐它们?
看看 在容器中布置组件
例如,以下使用 GridBagLayout
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JLabel label = new JLabel("This is just here to make some content");
label.setBorder(new EmptyBorder(32, 32, 32, 32));
JFrame frame = new JFrame();
frame.add(label);
frame.add(new UserPanel(), BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class UserPanel extends JPanel {
public UserPanel() {
JButton pickBtn = new JButton("Pick");
JButton attackBtn = new JButton("Attack");
JButton placeBtn = new JButton("Place");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(pickBtn, gbc);
add(attackBtn, gbc);
add(placeBtn, gbc);
}
}
}
做一个ButtonLayout
重要
请注意:以下内容旨在替换上面示例中的 GridBagLayout
,因为 GridBagLayout
很复杂,为此目的可能有点矫枉过正
很久以前,我可以理解 ButtonLayout
的一个非常简洁的概念,它基本上提供了一个简单的布局管理器来布局按钮,类似于大多数 OS 所做的(即,按钮大小相同)。
以下是该概念的一个非常基本的示例。
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.LayoutManager2;
import java.awt.Point;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new UserPanel());
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class UserPanel extends JPanel {
public UserPanel() {
JButton pickBtn = new JButton("Pick");
JButton attackBtn = new JButton("Attack");
JButton placeBtn = new JButton("Place");
setBorder(new LineBorder(Color.BLACK));
setLayout(new ButtonLayout(ButtonLayout.Alignment.VERTICAL, ButtonLayout.Anchor.TRAILING));
add(pickBtn);
add(attackBtn);
add(placeBtn);
}
}
public class ButtonLayout implements LayoutManager2 {
public enum Alignment {
VERTICAL, HORIZONTAL
}
public enum Anchor {
LEADING, CENTER, TRAILING
}
private Alignment alignment;
private Anchor anchor;
private int padding;
private Dimension virtualBounds;
public ButtonLayout() {
this(Alignment.HORIZONTAL, Anchor.TRAILING, 0);
}
public ButtonLayout(Alignment alignment, Anchor anchor) {
this(alignment, anchor, 0);
}
public ButtonLayout(Alignment alignment, Anchor anchor, int padding) {
this.alignment = alignment;
this.padding = padding;
this.anchor = anchor;
}
public Alignment getAlignment() {
return alignment;
}
public Anchor getAnchor() {
return anchor;
}
protected int getPadding() {
return padding;
}
protected int getTotalPadding(Container parent) {
int padding = getPadding();
return (padding * parent.getComponentCount()) - padding;
}
@Override
public void addLayoutComponent(Component comp, Object constraints) {
}
@Override
public void addLayoutComponent(String name, Component comp) {
}
@Override
public void removeLayoutComponent(Component comp) {
}
@Override
public void invalidateLayout(Container target) {
virtualBounds = null;
}
protected Dimension virtualLayout(Container parent) {
if (virtualBounds != null) {
return virtualBounds;
}
int maxWidth = 0;
int maxHeight = 0;
for (Component component : parent.getComponents()) {
Dimension preferredSize = component.getPreferredSize();
maxHeight = Math.max(maxHeight, preferredSize.height);
maxWidth = Math.max(maxWidth, preferredSize.width);
}
int padding = 0;
int width = 0;
int height = 0;
int componentCount = parent.getComponentCount();
switch (alignment) {
case HORIZONTAL:
width = (maxWidth * componentCount) + getTotalPadding(parent);
height = maxHeight;
break;
case VERTICAL:
width = maxWidth;
height = (maxHeight * componentCount) + getTotalPadding(parent);
break;
}
virtualBounds = new Dimension(width, height);
return virtualBounds;
}
@Override
public Dimension maximumLayoutSize(Container parent) {
return virtualLayout(parent);
}
@Override
public Dimension preferredLayoutSize(Container parent) {
return virtualLayout(parent);
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return virtualLayout(parent);
}
@Override
public float getLayoutAlignmentX(Container target) {
return 0.5f;
}
@Override
public float getLayoutAlignmentY(Container target) {
return 0.5f;
}
@Override
public void layoutContainer(Container parent) {
int maxWidth = 0;
int maxHeight = 0;
for (Component component : parent.getComponents()) {
Dimension preferredSize = component.getPreferredSize();
maxHeight = Math.max(maxHeight, preferredSize.height);
maxWidth = Math.max(maxWidth, preferredSize.width);
}
Dimension defaultSize = new Dimension(maxWidth, maxHeight);
Point point = offsetForAnchor(parent, defaultSize);
int xDelta = 0;
int yDelta = 0;
switch (alignment) {
case HORIZONTAL:
xDelta = getPadding() + defaultSize.width;
break;
case VERTICAL:
yDelta = getPadding() + defaultSize.height;
break;
}
for (Component component : parent.getComponents()) {
component.setSize(defaultSize);
component.setLocation(point);
point = new Point(point.x + xDelta, point.y + yDelta);
}
}
protected Point offsetForAnchor(Container parent, Dimension defaultSize) {
switch (anchor) {
case LEADING:
return leadingOffSet(parent, defaultSize);
case TRAILING:
return trailingOffSet(parent, defaultSize);
case CENTER:
return centerOffSet(parent, defaultSize);
}
return new Point(0, 0);
}
protected Point leadingOffSet(Container parent, Dimension defaultSize) {
Point point = new Point(0, 0);
switch (alignment) {
case HORIZONTAL:
point.x = padding;
point.y = (parent.getHeight() - defaultSize.height) / 2;
break;
case VERTICAL:
point.x = (parent.getWidth() - defaultSize.width) / 2;
point.y = padding;
break;
}
return point;
}
protected Point trailingOffSet(Container parent, Dimension defaultSize) {
Point point = new Point(0, 0);
int componentCount = parent.getComponentCount();
switch (alignment) {
case HORIZONTAL:
int totalWidth = (defaultSize.width * componentCount) + getTotalPadding(parent);
point.x = parent.getWidth() - totalWidth;
point.y = (parent.getHeight() - defaultSize.height) / 2;
break;
case VERTICAL:
int totalHeight = (defaultSize.height * componentCount) + getTotalPadding(parent);
point.x = (parent.getWidth() - defaultSize.width) / 2;
point.y = parent.getHeight() - totalHeight;
break;
}
return point;
}
protected Point centerOffSet(Container parent, Dimension defaultSize) {
Point point = new Point(0, 0);
int componentCount = parent.getComponentCount();
switch (alignment) {
case HORIZONTAL: {
int totalWidth = (defaultSize.width * componentCount) + getTotalPadding(parent);
point.x = (parent.getWidth() - totalWidth) / 2;
point.y = (parent.getHeight() - defaultSize.height) / 2;
}
break;
case VERTICAL: {
int totalHeight = (defaultSize.height * componentCount) + getTotalPadding(parent);
point.x = (parent.getWidth() - defaultSize.width) / 2;
point.y = (parent.getHeight() - totalHeight) / 2;
}
break;
}
return point;
}
}
}