为什么即使在设置了 JPanels 的大小后我的框布局也会改变大小
Why does my box Layout change size even after setting Sizes of JPanels
我一直在尝试调整我的 JPanel 大小,同时使用 LayoutManager(例如 BoxLayout)以特定顺序在 Layout 中排列组件,我通过 NOT USING[= 实现了我想要的外观39=] 盒子布局管理器。
这张图片我想要的原创想法:
但我想在为面板使用 Box Layout Manager 时实现这一点,当我这样做时,我得到了这个输出:
添加 BoxLayout 时得到的输出:
这是代码:
AppPanel.java :
import javax.swing.*;
import java.awt.*;
public class AppPanel extends JPanel {
int Width, Height;
MenuButton mb;
AppPanel(int width, int height)
{
this.Width = width;
this.Height = height;
this.setMinimumSize(new Dimension(this.Width/ 4, this.Height));
this.setPreferredSize(new Dimension(3 * this.Width/ 4, this.Height));
this.setMaximumSize(new Dimension(this.Width/ 4, this.Height));
this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
this.setBackground(Color.GREEN);
this.mb = new MenuButton("HELLO",this.getPreferredSize());
this.add(mb);
}
public void update(int width, int height){
this.Width = width;
this.Height = height;
this.setPreferredSize(new Dimension(3 * this.Width/ 4, this.Height));
// this.mb.update(this.mb.getGraphics());
}
}
MenuPanel.java:
import javax.swing.*;
import java.awt.*;
public class MenuPanel extends JPanel {
JLabel l_AppMenu;
int Width, Height;
MenuButton mb;
MenuPanel(int width, int height)
{
this.Width = width;
this.Height = height;
this.setMinimumSize(new Dimension(this.Width/ 4, this.Height));
this.setPreferredSize(new Dimension(this.Width/ 4, this.Height));
this.setMaximumSize(new Dimension(this.Width/ 4, this.Height));
this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
this.setBackground(Color.BLACK);
this.mb = new MenuButton("HELLO 1",this.getPreferredSize());
l_AppMenu = new JLabel("App Menu");
l_AppMenu.setForeground(Color.GRAY);
this.add(l_AppMenu);
this.add(mb);
}
public void update(int width, int height){
this.Width = width;
this.Height = height;
this.setPreferredSize(new Dimension(3 * this.Width/ 4, this.Height));
// this.mb.update(this.mb.getGraphics());
}
}
MainFrame.java:
import javax.swing.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
public class MainFrame extends JFrame implements ComponentListener {
int Width, Height;
MenuPanel mp;
AppPanel ap;
public MainFrame()
{
this.Width = 1600;
this.Height = 900;
mp = new MenuPanel(this.Width, this.Height);
ap = new AppPanel(this.Width, this.Height);
this.setSize(this.Width, this.Height);
this.setVisible(true);
this.setTitle("ToolKit");
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE );
this.add(mp);
this.add(ap);
addComponentListener(this);
this.getContentPane().setLayout(new BoxLayout(this.getContentPane(),BoxLayout.X_AXIS));
}
public static void main(String[] args)
{
MainFrame m = new MainFrame();
}
@Override
public void componentResized(ComponentEvent componentEvent) {
System.out.println(this.getWidth() + " " + this.getHeight());
mp.update(this.getWidth(), this.getHeight());
ap.update(this.getWidth(), this.getHeight());
// this.setSize(this.getHeight() * 16 / 9 , this.getHeight());
}
@Override
public void componentMoved(ComponentEvent componentEvent) {
}
@Override
public void componentShown(ComponentEvent componentEvent) {
}
@Override
public void componentHidden(ComponentEvent componentEvent) {
}
}
MenuButton.java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class MenuButton extends JButton implements MouseListener {
String Text;
int Entered = 0;
int Pressed = 0;
MenuButton(String str, Dimension d)
{
super(str);
this.Text = str;
addMouseListener(this);
this.setMinimumSize(new Dimension((int) d.getWidth() - 20,40));
this.setMaximumSize(new Dimension((int) d.getWidth() - 20,40));
this.setPreferredSize(new Dimension((int) d.getWidth() - 20,40));
this.setBorder(null);
}
public void paintComponent(Graphics g)
{
if(this.Pressed == 0) {
g.setColor(new Color(182, 25, 25));
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(new Color(255, 107, 107));
g.fillRect(10, 10, this.getWidth() - 20, this.getHeight() - 20);
}
else{
g.setColor(new Color(255, 107, 107));
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(new Color(255, 107, 107));
g.fillRect(10, 10, this.getWidth() - 20, this.getHeight() - 20);
}
if(this.Entered == 0) {
g.setColor(new Color(253, 210, 199));
g.drawString(this.Text, this.getWidth() / 2 - g.getFontMetrics().stringWidth(this.Text) / 2, 25);
}
else{
g.setColor(new Color(1, 36, 67));
g.drawString(this.Text, this.getWidth() / 2 - g.getFontMetrics().stringWidth(this.Text) / 2, 25);
}
}
@Override
public void mouseClicked(MouseEvent mouseEvent) {
}
@Override
public void mousePressed(MouseEvent mouseEvent) {
this.Pressed = 1;
}
@Override
public void mouseReleased(MouseEvent mouseEvent) {
this.Pressed = 0;
}
@Override
public void mouseEntered(MouseEvent mouseEvent) {
this.Entered = 1;
}
@Override
public void mouseExited(MouseEvent mouseEvent) {
this.Entered = 0;
}
}
通过阅读 MenuButton
的源代码,我意识到它根据鼠标事件绘制边框和背景。您不必自己执行此操作,因为 JButton
s 支持 Border
s 和背景颜色。因此,您可以创建一个 MouseListener
来更新这些属性,并让它用这些属性重新绘制自身(我将在下面的代码示例中进行演示)。
无论如何,回到你的主要问题,这里是你如何做到的,只使用 BoxLayout
s:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Objects;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
public class BoxLayoutTest {
public static final class MainButtonAdapter extends MouseAdapter {
private final Color fgOnEntered, fgOnNotEntered, bgOnPressed, bgOnNotPressed;
private final Border onPressed, onNotPressed;
public MainButtonAdapter(final Color fgOnEntered,
final Color fgOnNotEntered,
final Color bgOnPressed,
final Color bgOnNotPressed,
final Border onPressed,
final Border onNotPressed) {
this.fgOnEntered = Objects.requireNonNull(fgOnEntered);
this.fgOnNotEntered = Objects.requireNonNull(fgOnNotEntered);
this.bgOnPressed = Objects.requireNonNull(bgOnPressed);
this.bgOnNotPressed = Objects.requireNonNull(bgOnNotPressed);
this.onPressed = Objects.requireNonNull(onPressed);
this.onNotPressed = Objects.requireNonNull(onNotPressed);
}
private void inside(final Component src) {
if (src != null) {
src.setForeground(fgOnEntered);
src.repaint();
}
}
private void released(final Component src) {
if (src != null) {
if (src instanceof JComponent)
((JComponent) src).setBorder(onNotPressed);
src.setBackground(bgOnNotPressed);
src.repaint();
}
}
//@Override
//public void mouseWheelMoved(final MouseWheelEvent e) {
// inside(e.getComponent());
//}
//
//@Override
//public void mouseDragged(final MouseEvent e) {
// inside(e.getComponent());
//}
@Override
public void mouseMoved(final MouseEvent e) {
inside(e.getComponent());
}
@Override
public void mouseClicked(final MouseEvent e) {
released(e.getComponent());
}
@Override
public void mousePressed(final MouseEvent e) {
final Component src = e.getComponent();
if (src != null) {
if (src instanceof JComponent)
((JComponent) src).setBorder(onPressed);
src.setBackground(bgOnPressed);
src.repaint();
}
}
@Override
public void mouseReleased(final MouseEvent e) {
released(e.getComponent());
}
@Override
public void mouseEntered(final MouseEvent e) {
inside(e.getComponent());
}
@Override
public void mouseExited(final MouseEvent e) {
final Component src = e.getComponent();
if (src != null) {
src.setForeground(fgOnNotEntered);
src.repaint();
}
}
}
public static JButton createMainButton(final String text,
final MouseAdapter adapter,
final Border border,
final Color background,
final Color foreground,
final ActionListener aL) {
final JButton button = (text == null)? new JButton(): new JButton(text);
if (adapter != null) {
button.addMouseListener(adapter);
button.addMouseMotionListener(adapter);
button.addMouseWheelListener(adapter);
}
if (border != null)
button.setBorder(border);
if (background != null) {
button.setContentAreaFilled(false);
button.setOpaque(true);
button.setBackground(background);
}
if (foreground != null)
button.setForeground(foreground);
if (aL != null)
button.addActionListener(aL);
button.setFocusPainted(false);
return button;
}
public static JPanel createBoxLayoutPanel(final int axis,
final Component... components) {
final JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, axis));
if (components != null)
for (final Component c: components) {
if (!c.isMinimumSizeSet())
c.setMinimumSize(c.getPreferredSize());
if (!c.isMaximumSizeSet())
c.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
panel.add(c);
}
return panel;
}
public static JLabel label(final String text,
final Component labelFor,
final Color foreground) {
final JLabel jLabel = new JLabel(text, JLabel.CENTER);
jLabel.setForeground(foreground);
jLabel.setLabelFor(labelFor);
return jLabel;
}
public static Box.Filler createNonOpaqueVerticalGlue() {
final Box.Filler vglue = new Box.Filler(new Dimension(0,0), new Dimension(0,0), new Dimension(0, Short.MAX_VALUE));
vglue.setOpaque(false);
return vglue;
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> {
final int buttonBorderThickness = 10,
paddingThickness = 20;
final Color borderOnPressed = new Color(182, 25, 25),
borderOnNotPressed = new Color(255, 107, 107),
backgroundOnPressed = new Color(255, 107, 107),
backgroundOnNotPressed = new Color(255, 107, 107),
foregroundOnEntered = new Color(253, 210, 199),
foregroundOnNotEntered = new Color(1, 36, 67),
leftBackground = Color.BLACK,
rightBackground = Color.GREEN,
labelForeground = Color.LIGHT_GRAY;
final String firstButtonText = "Main button with long text as label",
secondButtonText = "Short",
labelText = "Some random text.";
final Border onPressed = BorderFactory.createLineBorder(borderOnPressed, buttonBorderThickness),
onNotPressed = BorderFactory.createLineBorder(borderOnNotPressed, buttonBorderThickness),
padding = BorderFactory.createEmptyBorder(paddingThickness, paddingThickness, paddingThickness, paddingThickness);
final MainButtonAdapter mainButtonAdapter = new MainButtonAdapter(foregroundOnEntered, foregroundOnNotEntered, backgroundOnPressed, backgroundOnNotPressed, onPressed, onNotPressed);
final JButton firstButton = createMainButton(firstButtonText, mainButtonAdapter, onNotPressed, backgroundOnNotPressed, foregroundOnNotEntered, null),
secondButton = createMainButton(secondButtonText, mainButtonAdapter, onNotPressed, backgroundOnNotPressed, foregroundOnNotEntered, null);
final Dimension secondButtonPreferredSize = secondButton.getPreferredSize();
secondButton.setMaximumSize(new Dimension(Short.MAX_VALUE, secondButtonPreferredSize.height));
final JLabel lbl = label(labelText, firstButton, labelForeground);
lbl.setMaximumSize(lbl.getPreferredSize());
final JPanel firstPanel = createBoxLayoutPanel(BoxLayout.X_AXIS, lbl, Box.createHorizontalStrut(paddingThickness), firstButton);
firstPanel.setOpaque(false);
firstPanel.setMaximumSize(new Dimension(Short.MAX_VALUE, firstPanel.getPreferredSize().height));
//Ucomment the following lines to get bigger size proportion for the right (green) panel...
//secondButtonPreferredSize.width = Math.max(500, secondButtonPreferredSize.width);
//secondButton.setMinimumSize(secondButtonPreferredSize);
//secondButton.setPreferredSize(secondButtonPreferredSize);
final JPanel left = createBoxLayoutPanel(BoxLayout.Y_AXIS, firstPanel, createNonOpaqueVerticalGlue() /*replace this "glue" with your components...*/);
left.setBorder(padding);
left.setBackground(leftBackground);
final JPanel right = createBoxLayoutPanel(BoxLayout.Y_AXIS, secondButton, createNonOpaqueVerticalGlue() /*replace this "glue" with your components...*/);
right.setBorder(padding);
right.setOpaque(false); //Could almost be 'right.setBackground(rightBackground);' instead.
final JPanel contents = createBoxLayoutPanel(BoxLayout.X_AXIS, left, right);
contents.setBackground(rightBackground); //That's why we called 'right.setOpaque(false);' previously.
final JFrame frame = new JFrame("BoxLayout test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(contents);
frame.pack();
//frame.setSize(Math.max(1600, frame.getWidth()), Math.max(900, frame.getHeight()));
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
基本上,内容窗格包含 X_AXIS
上的 BoxLayout
中的两个彩色面板。然后左侧面板包含另一个带有标签和第一个按钮的 BoxLayout
面板。然后就是处理每个 Component
.
的最小、首选和最大尺寸
如果你想避免嵌套面板,我想你可以在自定义绘制的面板上使用 GridBagLayout
(绘制不同的背景颜色),这也会给你更多的权力来微调使用权重因子调整行为。不过我还没试过。
当你 运行 它时,记得用鼠标调整框架的大小以查看它的行为。
稍后您可以将两个 createNonOpaqueVerticalGlue
方法调用替换为您想要的 Component
s,因为我假设您稍后会需要黑色和绿色面板中的更多内容。如果您随后需要一些垂直间隙,请使用 vertical strut.
我一直在尝试调整我的 JPanel 大小,同时使用 LayoutManager(例如 BoxLayout)以特定顺序在 Layout 中排列组件,我通过 NOT USING[= 实现了我想要的外观39=] 盒子布局管理器。
这张图片我想要的原创想法:
但我想在为面板使用 Box Layout Manager 时实现这一点,当我这样做时,我得到了这个输出:
添加 BoxLayout 时得到的输出:
这是代码:
AppPanel.java :
import javax.swing.*;
import java.awt.*;
public class AppPanel extends JPanel {
int Width, Height;
MenuButton mb;
AppPanel(int width, int height)
{
this.Width = width;
this.Height = height;
this.setMinimumSize(new Dimension(this.Width/ 4, this.Height));
this.setPreferredSize(new Dimension(3 * this.Width/ 4, this.Height));
this.setMaximumSize(new Dimension(this.Width/ 4, this.Height));
this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
this.setBackground(Color.GREEN);
this.mb = new MenuButton("HELLO",this.getPreferredSize());
this.add(mb);
}
public void update(int width, int height){
this.Width = width;
this.Height = height;
this.setPreferredSize(new Dimension(3 * this.Width/ 4, this.Height));
// this.mb.update(this.mb.getGraphics());
}
}
MenuPanel.java:
import javax.swing.*;
import java.awt.*;
public class MenuPanel extends JPanel {
JLabel l_AppMenu;
int Width, Height;
MenuButton mb;
MenuPanel(int width, int height)
{
this.Width = width;
this.Height = height;
this.setMinimumSize(new Dimension(this.Width/ 4, this.Height));
this.setPreferredSize(new Dimension(this.Width/ 4, this.Height));
this.setMaximumSize(new Dimension(this.Width/ 4, this.Height));
this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
this.setBackground(Color.BLACK);
this.mb = new MenuButton("HELLO 1",this.getPreferredSize());
l_AppMenu = new JLabel("App Menu");
l_AppMenu.setForeground(Color.GRAY);
this.add(l_AppMenu);
this.add(mb);
}
public void update(int width, int height){
this.Width = width;
this.Height = height;
this.setPreferredSize(new Dimension(3 * this.Width/ 4, this.Height));
// this.mb.update(this.mb.getGraphics());
}
}
MainFrame.java:
import javax.swing.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
public class MainFrame extends JFrame implements ComponentListener {
int Width, Height;
MenuPanel mp;
AppPanel ap;
public MainFrame()
{
this.Width = 1600;
this.Height = 900;
mp = new MenuPanel(this.Width, this.Height);
ap = new AppPanel(this.Width, this.Height);
this.setSize(this.Width, this.Height);
this.setVisible(true);
this.setTitle("ToolKit");
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE );
this.add(mp);
this.add(ap);
addComponentListener(this);
this.getContentPane().setLayout(new BoxLayout(this.getContentPane(),BoxLayout.X_AXIS));
}
public static void main(String[] args)
{
MainFrame m = new MainFrame();
}
@Override
public void componentResized(ComponentEvent componentEvent) {
System.out.println(this.getWidth() + " " + this.getHeight());
mp.update(this.getWidth(), this.getHeight());
ap.update(this.getWidth(), this.getHeight());
// this.setSize(this.getHeight() * 16 / 9 , this.getHeight());
}
@Override
public void componentMoved(ComponentEvent componentEvent) {
}
@Override
public void componentShown(ComponentEvent componentEvent) {
}
@Override
public void componentHidden(ComponentEvent componentEvent) {
}
}
MenuButton.java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class MenuButton extends JButton implements MouseListener {
String Text;
int Entered = 0;
int Pressed = 0;
MenuButton(String str, Dimension d)
{
super(str);
this.Text = str;
addMouseListener(this);
this.setMinimumSize(new Dimension((int) d.getWidth() - 20,40));
this.setMaximumSize(new Dimension((int) d.getWidth() - 20,40));
this.setPreferredSize(new Dimension((int) d.getWidth() - 20,40));
this.setBorder(null);
}
public void paintComponent(Graphics g)
{
if(this.Pressed == 0) {
g.setColor(new Color(182, 25, 25));
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(new Color(255, 107, 107));
g.fillRect(10, 10, this.getWidth() - 20, this.getHeight() - 20);
}
else{
g.setColor(new Color(255, 107, 107));
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(new Color(255, 107, 107));
g.fillRect(10, 10, this.getWidth() - 20, this.getHeight() - 20);
}
if(this.Entered == 0) {
g.setColor(new Color(253, 210, 199));
g.drawString(this.Text, this.getWidth() / 2 - g.getFontMetrics().stringWidth(this.Text) / 2, 25);
}
else{
g.setColor(new Color(1, 36, 67));
g.drawString(this.Text, this.getWidth() / 2 - g.getFontMetrics().stringWidth(this.Text) / 2, 25);
}
}
@Override
public void mouseClicked(MouseEvent mouseEvent) {
}
@Override
public void mousePressed(MouseEvent mouseEvent) {
this.Pressed = 1;
}
@Override
public void mouseReleased(MouseEvent mouseEvent) {
this.Pressed = 0;
}
@Override
public void mouseEntered(MouseEvent mouseEvent) {
this.Entered = 1;
}
@Override
public void mouseExited(MouseEvent mouseEvent) {
this.Entered = 0;
}
}
通过阅读 MenuButton
的源代码,我意识到它根据鼠标事件绘制边框和背景。您不必自己执行此操作,因为 JButton
s 支持 Border
s 和背景颜色。因此,您可以创建一个 MouseListener
来更新这些属性,并让它用这些属性重新绘制自身(我将在下面的代码示例中进行演示)。
无论如何,回到你的主要问题,这里是你如何做到的,只使用 BoxLayout
s:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Objects;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
public class BoxLayoutTest {
public static final class MainButtonAdapter extends MouseAdapter {
private final Color fgOnEntered, fgOnNotEntered, bgOnPressed, bgOnNotPressed;
private final Border onPressed, onNotPressed;
public MainButtonAdapter(final Color fgOnEntered,
final Color fgOnNotEntered,
final Color bgOnPressed,
final Color bgOnNotPressed,
final Border onPressed,
final Border onNotPressed) {
this.fgOnEntered = Objects.requireNonNull(fgOnEntered);
this.fgOnNotEntered = Objects.requireNonNull(fgOnNotEntered);
this.bgOnPressed = Objects.requireNonNull(bgOnPressed);
this.bgOnNotPressed = Objects.requireNonNull(bgOnNotPressed);
this.onPressed = Objects.requireNonNull(onPressed);
this.onNotPressed = Objects.requireNonNull(onNotPressed);
}
private void inside(final Component src) {
if (src != null) {
src.setForeground(fgOnEntered);
src.repaint();
}
}
private void released(final Component src) {
if (src != null) {
if (src instanceof JComponent)
((JComponent) src).setBorder(onNotPressed);
src.setBackground(bgOnNotPressed);
src.repaint();
}
}
//@Override
//public void mouseWheelMoved(final MouseWheelEvent e) {
// inside(e.getComponent());
//}
//
//@Override
//public void mouseDragged(final MouseEvent e) {
// inside(e.getComponent());
//}
@Override
public void mouseMoved(final MouseEvent e) {
inside(e.getComponent());
}
@Override
public void mouseClicked(final MouseEvent e) {
released(e.getComponent());
}
@Override
public void mousePressed(final MouseEvent e) {
final Component src = e.getComponent();
if (src != null) {
if (src instanceof JComponent)
((JComponent) src).setBorder(onPressed);
src.setBackground(bgOnPressed);
src.repaint();
}
}
@Override
public void mouseReleased(final MouseEvent e) {
released(e.getComponent());
}
@Override
public void mouseEntered(final MouseEvent e) {
inside(e.getComponent());
}
@Override
public void mouseExited(final MouseEvent e) {
final Component src = e.getComponent();
if (src != null) {
src.setForeground(fgOnNotEntered);
src.repaint();
}
}
}
public static JButton createMainButton(final String text,
final MouseAdapter adapter,
final Border border,
final Color background,
final Color foreground,
final ActionListener aL) {
final JButton button = (text == null)? new JButton(): new JButton(text);
if (adapter != null) {
button.addMouseListener(adapter);
button.addMouseMotionListener(adapter);
button.addMouseWheelListener(adapter);
}
if (border != null)
button.setBorder(border);
if (background != null) {
button.setContentAreaFilled(false);
button.setOpaque(true);
button.setBackground(background);
}
if (foreground != null)
button.setForeground(foreground);
if (aL != null)
button.addActionListener(aL);
button.setFocusPainted(false);
return button;
}
public static JPanel createBoxLayoutPanel(final int axis,
final Component... components) {
final JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, axis));
if (components != null)
for (final Component c: components) {
if (!c.isMinimumSizeSet())
c.setMinimumSize(c.getPreferredSize());
if (!c.isMaximumSizeSet())
c.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
panel.add(c);
}
return panel;
}
public static JLabel label(final String text,
final Component labelFor,
final Color foreground) {
final JLabel jLabel = new JLabel(text, JLabel.CENTER);
jLabel.setForeground(foreground);
jLabel.setLabelFor(labelFor);
return jLabel;
}
public static Box.Filler createNonOpaqueVerticalGlue() {
final Box.Filler vglue = new Box.Filler(new Dimension(0,0), new Dimension(0,0), new Dimension(0, Short.MAX_VALUE));
vglue.setOpaque(false);
return vglue;
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(() -> {
final int buttonBorderThickness = 10,
paddingThickness = 20;
final Color borderOnPressed = new Color(182, 25, 25),
borderOnNotPressed = new Color(255, 107, 107),
backgroundOnPressed = new Color(255, 107, 107),
backgroundOnNotPressed = new Color(255, 107, 107),
foregroundOnEntered = new Color(253, 210, 199),
foregroundOnNotEntered = new Color(1, 36, 67),
leftBackground = Color.BLACK,
rightBackground = Color.GREEN,
labelForeground = Color.LIGHT_GRAY;
final String firstButtonText = "Main button with long text as label",
secondButtonText = "Short",
labelText = "Some random text.";
final Border onPressed = BorderFactory.createLineBorder(borderOnPressed, buttonBorderThickness),
onNotPressed = BorderFactory.createLineBorder(borderOnNotPressed, buttonBorderThickness),
padding = BorderFactory.createEmptyBorder(paddingThickness, paddingThickness, paddingThickness, paddingThickness);
final MainButtonAdapter mainButtonAdapter = new MainButtonAdapter(foregroundOnEntered, foregroundOnNotEntered, backgroundOnPressed, backgroundOnNotPressed, onPressed, onNotPressed);
final JButton firstButton = createMainButton(firstButtonText, mainButtonAdapter, onNotPressed, backgroundOnNotPressed, foregroundOnNotEntered, null),
secondButton = createMainButton(secondButtonText, mainButtonAdapter, onNotPressed, backgroundOnNotPressed, foregroundOnNotEntered, null);
final Dimension secondButtonPreferredSize = secondButton.getPreferredSize();
secondButton.setMaximumSize(new Dimension(Short.MAX_VALUE, secondButtonPreferredSize.height));
final JLabel lbl = label(labelText, firstButton, labelForeground);
lbl.setMaximumSize(lbl.getPreferredSize());
final JPanel firstPanel = createBoxLayoutPanel(BoxLayout.X_AXIS, lbl, Box.createHorizontalStrut(paddingThickness), firstButton);
firstPanel.setOpaque(false);
firstPanel.setMaximumSize(new Dimension(Short.MAX_VALUE, firstPanel.getPreferredSize().height));
//Ucomment the following lines to get bigger size proportion for the right (green) panel...
//secondButtonPreferredSize.width = Math.max(500, secondButtonPreferredSize.width);
//secondButton.setMinimumSize(secondButtonPreferredSize);
//secondButton.setPreferredSize(secondButtonPreferredSize);
final JPanel left = createBoxLayoutPanel(BoxLayout.Y_AXIS, firstPanel, createNonOpaqueVerticalGlue() /*replace this "glue" with your components...*/);
left.setBorder(padding);
left.setBackground(leftBackground);
final JPanel right = createBoxLayoutPanel(BoxLayout.Y_AXIS, secondButton, createNonOpaqueVerticalGlue() /*replace this "glue" with your components...*/);
right.setBorder(padding);
right.setOpaque(false); //Could almost be 'right.setBackground(rightBackground);' instead.
final JPanel contents = createBoxLayoutPanel(BoxLayout.X_AXIS, left, right);
contents.setBackground(rightBackground); //That's why we called 'right.setOpaque(false);' previously.
final JFrame frame = new JFrame("BoxLayout test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(contents);
frame.pack();
//frame.setSize(Math.max(1600, frame.getWidth()), Math.max(900, frame.getHeight()));
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
基本上,内容窗格包含 X_AXIS
上的 BoxLayout
中的两个彩色面板。然后左侧面板包含另一个带有标签和第一个按钮的 BoxLayout
面板。然后就是处理每个 Component
.
如果你想避免嵌套面板,我想你可以在自定义绘制的面板上使用 GridBagLayout
(绘制不同的背景颜色),这也会给你更多的权力来微调使用权重因子调整行为。不过我还没试过。
当你 运行 它时,记得用鼠标调整框架的大小以查看它的行为。
稍后您可以将两个 createNonOpaqueVerticalGlue
方法调用替换为您想要的 Component
s,因为我假设您稍后会需要黑色和绿色面板中的更多内容。如果您随后需要一些垂直间隙,请使用 vertical strut.