Java FlowLayout 内部的 FlowLayout
Java FlowLayout inside FlowLayout
我正在尝试设计类似于浏览器标题栏(浏览器顶部)的设计。左侧有标签,右侧有最小化、调整大小(minimize/maximize)、退出按钮。
为此,我试过了。
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.RIGHT));
JPanel tabpanel= new JPanel();
tabpanel.setLayout(new FlowLayout(FlowLayout.LEFT));
tabpanel.add(new JButton("Tab 1"));
tabpanel.add(new JButton("Tab 2"));
panel.add(tabpanel);
panel.add(new JButton("Minimize"));
panel.add(new JButton("Resize"));
panel.add(new JButton("Quit"));
根据需要在右侧创建了退出、调整大小、最小化按钮,但在最小化按钮附近创建的选项卡不是框架的左侧。我认为应该有方法或任何东西来填充剩余的内容,还是我应该使用其他布局?任何帮助表示赞赏
我建议使用BoxLayout
作为panel
的布局管理器来组织左右部分。
下面是完整的演示代码:
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(()->{
JFrame frame = new JFrame("Solution");
JPanel container = new JPanel();
container.setLayout(new BorderLayout());
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
JPanel tabpanel= new JPanel();
tabpanel.setLayout(new FlowLayout(FlowLayout.LEFT));
tabpanel.add(new JButton("Tab 1"));
tabpanel.add(new JButton("Tab 2"));
panel.add(tabpanel);
panel.add(new JButton("Minimize"));
panel.add(new JButton("Resize"));
panel.add(new JButton("Quit"));
container.add(panel, BorderLayout.PAGE_START);
frame.add(container);
frame.pack();
frame.setSize(new Dimension(500,500));
frame.setVisible(true);
});
}
}
外观:
如评论中所建议:一种解决方案是将 "tabs" 和 "buttons" 放入单独的面板中,并将它们添加到 WEST
和 EAST
中标题面板,其中有一个 BorderLayout
:
这是 MCVE:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TitleBarLayout
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui()
{
JFrame f = new JFrame();
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel titleBar = new JPanel(new BorderLayout());
JPanel tabPanel = new JPanel();
tabPanel.setLayout(new FlowLayout());
tabPanel.add(new JButton("Tab 1"));
tabPanel.add(new JButton("Tab 2"));
titleBar.add(tabPanel, BorderLayout.WEST);
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(new JButton("Minimize"));
buttonsPanel.add(new JButton("Resize"));
buttonsPanel.add(new JButton("Quit"));
titleBar.add(buttonsPanel, BorderLayout.EAST);
mainPanel.add(titleBar, BorderLayout.NORTH);
f.getContentPane().add(mainPanel);
f.setSize(800, 600);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
我强烈推荐 GridBagLayout
,它是可用的最灵活和可配置的布局管理器之一,但它确实带来了复杂性
public class HeaderPane extends JPanel {
public HeaderPane() {
setLayout(new GridBagLayout());
add(new JButton("Tab 1"));
add(new JButton("Tab 2"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.BASELINE_TRAILING;
add(new JButton("Minimize"), gbc);
add(new JButton("Maximise"));
add(new JButton("Close"));
}
}
Arrgggh,复杂性在燃烧,它在燃烧 讽刺
因此,此解决方案是一个容器,具有一个布局管理器。我并不是说更复杂的需求可能会受益于复合解决方案(我很想将 min/max/close 和选项卡按钮放在自己的容器中),但作为起点,它相对简单。
可运行示例
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new HeaderPane(), BorderLayout.NORTH);
frame.add(new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 200);
}
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class HeaderPane extends JPanel {
public HeaderPane() {
setLayout(new GridBagLayout());
add(new JButton("Tab 1"));
add(new JButton("Tab 2"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.BASELINE_TRAILING;
add(new JButton("Minimize"), gbc);
add(new JButton("Maximise"));
add(new JButton("Close"));
}
}
}
我正在尝试设计类似于浏览器标题栏(浏览器顶部)的设计。左侧有标签,右侧有最小化、调整大小(minimize/maximize)、退出按钮。
为此,我试过了。
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.RIGHT));
JPanel tabpanel= new JPanel();
tabpanel.setLayout(new FlowLayout(FlowLayout.LEFT));
tabpanel.add(new JButton("Tab 1"));
tabpanel.add(new JButton("Tab 2"));
panel.add(tabpanel);
panel.add(new JButton("Minimize"));
panel.add(new JButton("Resize"));
panel.add(new JButton("Quit"));
根据需要在右侧创建了退出、调整大小、最小化按钮,但在最小化按钮附近创建的选项卡不是框架的左侧。我认为应该有方法或任何东西来填充剩余的内容,还是我应该使用其他布局?任何帮助表示赞赏
我建议使用BoxLayout
作为panel
的布局管理器来组织左右部分。
下面是完整的演示代码:
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(()->{
JFrame frame = new JFrame("Solution");
JPanel container = new JPanel();
container.setLayout(new BorderLayout());
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
JPanel tabpanel= new JPanel();
tabpanel.setLayout(new FlowLayout(FlowLayout.LEFT));
tabpanel.add(new JButton("Tab 1"));
tabpanel.add(new JButton("Tab 2"));
panel.add(tabpanel);
panel.add(new JButton("Minimize"));
panel.add(new JButton("Resize"));
panel.add(new JButton("Quit"));
container.add(panel, BorderLayout.PAGE_START);
frame.add(container);
frame.pack();
frame.setSize(new Dimension(500,500));
frame.setVisible(true);
});
}
}
外观:
如评论中所建议:一种解决方案是将 "tabs" 和 "buttons" 放入单独的面板中,并将它们添加到 WEST
和 EAST
中标题面板,其中有一个 BorderLayout
:
这是 MCVE:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TitleBarLayout
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui()
{
JFrame f = new JFrame();
JPanel mainPanel = new JPanel(new BorderLayout());
JPanel titleBar = new JPanel(new BorderLayout());
JPanel tabPanel = new JPanel();
tabPanel.setLayout(new FlowLayout());
tabPanel.add(new JButton("Tab 1"));
tabPanel.add(new JButton("Tab 2"));
titleBar.add(tabPanel, BorderLayout.WEST);
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(new JButton("Minimize"));
buttonsPanel.add(new JButton("Resize"));
buttonsPanel.add(new JButton("Quit"));
titleBar.add(buttonsPanel, BorderLayout.EAST);
mainPanel.add(titleBar, BorderLayout.NORTH);
f.getContentPane().add(mainPanel);
f.setSize(800, 600);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
我强烈推荐 GridBagLayout
,它是可用的最灵活和可配置的布局管理器之一,但它确实带来了复杂性
public class HeaderPane extends JPanel {
public HeaderPane() {
setLayout(new GridBagLayout());
add(new JButton("Tab 1"));
add(new JButton("Tab 2"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.BASELINE_TRAILING;
add(new JButton("Minimize"), gbc);
add(new JButton("Maximise"));
add(new JButton("Close"));
}
}
Arrgggh,复杂性在燃烧,它在燃烧 讽刺
因此,此解决方案是一个容器,具有一个布局管理器。我并不是说更复杂的需求可能会受益于复合解决方案(我很想将 min/max/close 和选项卡按钮放在自己的容器中),但作为起点,它相对简单。
可运行示例
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new HeaderPane(), BorderLayout.NORTH);
frame.add(new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 200);
}
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class HeaderPane extends JPanel {
public HeaderPane() {
setLayout(new GridBagLayout());
add(new JButton("Tab 1"));
add(new JButton("Tab 2"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.anchor = GridBagConstraints.BASELINE_TRAILING;
add(new JButton("Minimize"), gbc);
add(new JButton("Maximise"));
add(new JButton("Close"));
}
}
}