我是一名计算机科学二年级学生(正在寒假),我正在尝试自学 Swing。最终,这只是一个项目,旨在添加到我的代码组合中,并巩固我这学期在数据结构和算法中学到的知识。
然而,在深入研究 Swing 时,我遇到了障碍(也许一下子咬得太多了)。我一直试图让我的两个 JLabels
:heading
和 dets
出现在 JPanel
中的彼此下方> tbdItem
。
我四处搜寻并尝试了解决方案 here (使用 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
的顶部中间添加组件,当您尝试添加更多组件时,它会将之前添加的组件移至左侧,但随着行被填满后,它将新组件移动到下一行,再次从下一行的中间开始整个过程。
How you want to make this use case work, is by using a nested layout
在进入 Swing 世界之前需要记住的一些要点:
- 尽量不要在代码中随机使用
setXxXSize()
方法。反而 让LayoutManager
如此选择来担心这方面。这个线程 关于should I avoid the use of setXxXSize() methods , 是一个 该主题的良好起点 - 由于这是 Swing,请尝试使用
frame.pack()
,而不是设置 上面有手动尺寸。这样 GUI 看起来会更有吸引力,因为 Swing 用于计算一切,GUI 应该如何显示 屏幕以某种方式不同于任意值可以 做
您可能需要深入了解 various layouts ,并一起使用它们,或单独使用它们来完成需求。
一个小程序:
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);
}
}
关于java - JPanel 的 FlowLayout() 未在流程布局中显示 JLabels,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24675608/