[英]FlowLayout() of JPanel not displaying JLabels in a flowlayout
我是CS的二年级学生(寒假期间),并且我正在尝试自学Swing。 最终,这只是一个项目,可以添加到我的代码组合中,并巩固我在整个学期中从数据结构和算法中学到的知识。
但是,进入Swing后,我遇到了一个障碍(也许一下子咬得太多了)。 我被困在试图让我的两个JLabels
: heading
和dets
,在彼此的下面出现JPanel
tbdItem
。
我到处搜索并在这里尝试了一个解决方案(使用GridLayout()
的解决方案),但这也不起作用。
如果您检查一下我的代码,我相信我已经正确使用了FlowLayout()
布局管理器,但是实际上输出看起来像是在忽略我的JPanel
,而是在使用我的JFrame
的布局管理器? 此处(错误)输出的图像:
这是我的代码供参考。 我真的不明白为什么它不起作用,因为我要插入的JPanel
是FlowLayout()
:
super("To Be Done");
setLocationRelativeTo(null); //Center window on open
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
getContentPane().setBackground(Color.LIGHT_GRAY);
addWindowListener( new CheckOnExit() );
setLayout( new BorderLayout() );
JPanel buttonPanel = new JPanel();
buttonPanel.setBackground(Color.LIGHT_GRAY);
JButton newTask = new JButton("New Task");
newTask.addActionListener( new NewTask() );
newTask.setPreferredSize(new Dimension(130, 40));
buttonPanel.add(newTask);
JButton editTask = new JButton("Edit Task");
editTask.addActionListener( new EditTask() );
editTask.setPreferredSize(new Dimension(130, 40));
buttonPanel.add(editTask);
JButton deleteTask = new JButton("Delete Task");
deleteTask.addActionListener( new DeleteTask() );
deleteTask.setPreferredSize(new Dimension(130, 40));
buttonPanel.add(deleteTask);
add(buttonPanel, BorderLayout.SOUTH);
/* TBD Box to display matters TBD */
JPanel tbdPanel = new JPanel( new FlowLayout() );
JPanel tbdItem = new JPanel( new FlowLayout() ); //
JLabel heading = new JLabel("Heading");
JLabel dets = new JLabel("The Body of the text goes here");
// Make heading bold -- find out if there's a better way to do this
Font font = heading.getFont();
Font boldFont = new Font(font.getFontName(), Font.BOLD, font.getSize());
heading.setFont(boldFont);
tbdItem.add(heading);
tbdItem.add(dets);
tbdPanel.add(tbdItem);
add( tbdPanel, BorderLayout.CENTER ); // Add TBD Panel to CENTER of JFrame
非常感谢。 对于此网站上的解决方案,我深表歉意。 老实说,我找不到它。
你描述的不自然的行为FlowLayout
的确,如何实际方式FlowLayout
工作。 默认情况下, FlowLayout
在Container
的顶部中间位置添加组件,当您尝试添加更多组件时,它将先前添加的组件移到左侧,但是当行被填充时,它将新组件移到下一行,再次从下一行的中间开始整个过程。
您想如何使用此用例,是通过使用嵌套布局
在进入Swing的世界之前,需要记住一些要点:
setXxXSize()
方法。 相反,让LayoutManager
选择担心该方面。 关于该线程, 应该避免使用setXxXSize()方法 ,这是该主题的一个很好的起点 frame.pack()
,而不要在其上设置手动大小。 这样,如果使用Swing来计算所有内容,则GUI看起来将更具吸引力,其显示方式与任意值可以执行的方式有所不同 您可能需要深入了解各种布局 ,然后一起使用或单独使用它们来满足需求。
一个小程序:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ToBeDone {
private JButton newTaskButton;
private JButton editTaskButton;
private JButton deleteTaskButton;
private static final int GAP = 5;
private void displayGUI() {
JFrame frame = new JFrame("Swing Worker Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(GAP, GAP));
JPanel centerPanel = new JPanel();
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new GridLayout(2, 1, GAP, GAP));
JLabel headingLabel = new JLabel(
"<html><h1>Heading</h1><html>", JLabel.CENTER);
JLabel subHeadingLabel = new JLabel(
"<html><h2>The body of the text goes here</h2>" +
"</html>",JLabel.CENTER);
labelPanel.add(headingLabel);
labelPanel.add(subHeadingLabel);
centerPanel.add(labelPanel);
contentPane.add(centerPanel, BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
newTaskButton = new JButton("New Task");
editTaskButton = new JButton("Edit Task");
deleteTaskButton = new JButton("Delete Task");
buttonPanel.add(newTaskButton);
buttonPanel.add(editTaskButton);
buttonPanel.add(deleteTaskButton);
contentPane.add(buttonPanel, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new ToBeDone().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
您将tbdPanel设置为FlowLayout,并且在前往此面板的标题和说明时,它们将被添加到一行中。 这可能就是为什么您将它们并排放置的原因。 尝试为tbdPanel使用其他布局,例如BorderLayout
您的问题的原因是,给tbdItem
一个new FlowLayout()
,如果有空间(有new FlowLayout()
,它将水平布置项目
Swing中的布局管理器可能是一个痛苦的学习过程,尤其是其中最可配置的学习器。 GridBagLayout
。
我建议从学习BorderLayout
首先如何工作开始,并使用它们中的许多(在层次结构中)包装所需的项目。 因此,相反,您将需要执行以下操作:
JPanel tbdItem = new JPanel( new BorderLayout() );
...
tbdItem.add(heading, BorderLayout.NORTH);
tbdItem.add(dets, BorderLayout.SOUTH);
看起来创建这些简单的布局( FlowLayout
, GridLayout
)对用户是不利的。 开始学习布局管理的人们自然会从这些简单的经理开始,他们没有意识到他们在实践中做不到很多。 他们感到困惑和挣扎。 答案在于更强大的布局管理器,例如GridBagLayout
, GroupLayout
或MigLayout
(外部)。 我一直主张MigLayout
因为它非常灵活且易于使用。
为了说明,我使用MigLayout
管理器创建了一个示例:
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import net.miginfocom.swing.MigLayout;
public class MigLayoutToBeDone extends JFrame {
public MigLayoutToBeDone() {
initUI();
setTitle("To Be Done");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
setLayout(new MigLayout("ins 15", "[grow]", "[][]30:push[]"));
JLabel heading = new JLabel("Heading");
JLabel dets = new JLabel("The body of the text goes here");
add(heading, "center, gapbottom 15, wrap");
add(dets, "center, wrap");
JButton newTask = new JButton("New Task");
JButton editTask = new JButton("Edit Task");
JButton deleteTask = new JButton("Delete Task");
add(newTask, "split 3, center, sgx");
add(editTask, "sgx");
add(deleteTask, "sgx");
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MigLayoutToBeDone ex = new MigLayoutToBeDone();
ex.setVisible(true);
}
});
}
}
布局由一列组成; 列被拉伸以占据整个窗口区域。 这两个标签在其列的单元格中水平居中。 标签下方有一个贪婪的间隙,该间隙占用了所有可用空间,因此将三个按钮推到底部。 最后,将按钮放置在一个单元的三个子单元中,将它们居中并使其具有相等的大小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.