Я хочу вертикально выровнять 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);
}
Как я могу выровнять их по вертикали?
3 кнопки подряд
FlowLayout
(макет JPanel
по умолчанию) должен делать это автоматически. КСТАТИ: Не звоните [Container].setPreferredSize(..)
или [Window].setSize(..)
. Какие бы числа ни были предоставлены, они будут: а) догадкой и б) неправильным.
Хм, я очень новичок в свинге. что вы предлагаете мне использовать?
Для КСТАТИ? Window.pack()
после добавления всех компонентов.
да, но для размера компонентов? Удалив все, теперь окно очень маленькое
Есть несколько способов увеличить размер кнопок. НАПРИМЕР. Установите более длинный текст или более крупный значок, шрифт или Insets
. Для панели добавьте EmptyBorder
. Кроме того, в большинстве макетов есть способы увеличить расстояние между компонентами. Для получения дополнительной информации см. документацию по конструкторам.
да, но как я могу выровнять эти кнопки по вертикали?
Мне непонятно, что вы имеете в виду. Предоставьте графическое изображение ASCII или простой рисунок графического интерфейса с размером по умолчанию и при перетаскивании большего размера по ширине и высоте.
Взгляните на Размещение компонентов внутри контейнера
Например, в следующем примере используется 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
, которая в основном предоставляла простой менеджер компоновки для кнопок компоновки, аналогичный тому, как это делает большинство ОС (т.е. кнопки имеют одинаковый размер).
Ниже приведен ОЧЕНЬ простой пример этой концепции.
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;
}
}
}
как разместить кнопки друг рядом с другом? (по горизонтали)
@Diaskyyy Вы должны прочитать связанный учебник. Вы «могли бы» просто использовать FlowLayout
, как раньше, или вы могли бы использовать GridBagConstraints#gridy
(вместо (GridBagConstraints#gridwidth
), но вы потеряете «равный размер»
это очень мило, но это не совсем то, что я искал. Я искал панель в нижней части окна. затем я хочу, чтобы кнопки были выровнены по горизонтали друг относительно друга, но по вертикали относительно панели. prnt.sc/IezXEDqLPCeh небольшая ничья.
когда я использую ButtonLayout.Alignment.HORIZONTAL и ButtonLayout.Anchor.CENTER, они находятся в середине окна. И когда я ButtonLayout.Alignment.VERTICAL и ButtonLayout.Anchor.CENTER, они снизу, но выровнены по вертикали
@Diaskyyy Когда я использую HORIZONTAL
/CENTER
и VERTICAL
/CENTER
, компоненты привязываются к середине компонента — цель макета Button
состоит в том, чтобы воздействовать ТОЛЬКО на кнопки. Итак, судя по тому, что вы рисуете, панель «кнопка» должна быть с использованием HORIZONTAL
/CENTER
, а сама панель размещена в позиции SOUTH
в BorderLayout
, как и в первом примере — это широко известно как составные макеты, где вы используете ряд компонентов. со своими собственными макетами для создания сложных представлений
DYM 3 кнопки в ряд или 3 кнопки в столбец?