Java 外部JPanel类在主JFrame类中未正确显示
基本上,我试图理解Java中的线程。所以我想我应该创建一个主JFrame类,其中包含来自外部类的两个JPanel,然后在其中执行一些操作,并使用来自第二个面板的消息来控制它。到目前为止,我只创建了第一个外部面板,问题就从这里开始了!虽然它看起来是“已加载”的,但显示不正确。(请参阅system.out行) 这是主要课程Java 外部JPanel类在主JFrame类中未正确显示,java,swing,java-threads,Java,Swing,Java Threads,基本上,我试图理解Java中的线程。所以我想我应该创建一个主JFrame类,其中包含来自外部类的两个JPanel,然后在其中执行一些操作,并使用来自第二个面板的消息来控制它。到目前为止,我只创建了第一个外部面板,问题就从这里开始了!虽然它看起来是“已加载”的,但显示不正确。(请参阅system.out行) 这是主要课程 package com.maybee.gui; import java.awt.*; import javax.swing.*; import javax.swing.bor
package com.maybee.gui;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class Maybee extends JFrame implements Runnable
{
public JFrame maynFrame = null;
public JPanel contentPanel = null;
public SimPanel simPanel = null;
public int screenWidth = 0;
public int screenHeight = 0;
public Maybee()
{
}
private void init()
{
System.out.println("In Inint");
maynFrame = new JFrame("Maybee");
maynFrame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
screenWidth = gd.getDisplayMode().getWidth();
screenHeight = gd.getDisplayMode().getHeight();
maynFrame.setPreferredSize(new Dimension(screenWidth,screenHeight - 100));
maynFrame.setContentPane(getContentPanel());
maynFrame.setVisible(true);
maynFrame.pack();
}
public JPanel getContentPanel()
{
if (contentPanel == null)
{
contentPanel = new JPanel();
contentPanel.setPreferredSize(new Dimension(screenWidth,screenHeight - 100));
contentPanel.setBorder(new LineBorder(Color.BLUE));
contentPanel.setBackground(Color.RED);
contentPanel.setLayout(new BorderLayout());
contentPanel.add(getSimPanel(),BorderLayout.CENTER);
}
return contentPanel;
}
public SimPanel getSimPanel()
{
if(simPanel == null)
{
simPanel = new SimPanel(this);
}
return simPanel;
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
System.out.println("Start");
Maybee maybee = new Maybee();
maybee.run();
}
});
}
public void run()
{
init();
}
}
现在是第一个外部JPanel类
package com.maybee.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class SimPanel extends JPanel
{
public Maybee localMaybee = null;
public JPanel simPanel = null;
private JButton btn;
public SimPanel(Maybee interMaybee)
{
localMaybee = interMaybee;
init();
}
public void init()
{
simPanel = new JPanel();
simPanel.setLayout(new BorderLayout());
simPanel.setPreferredSize(new Dimension(localMaybee.screenWidth/4,localMaybee.screenHeight - 100));
simPanel.setBackground(Color.GREEN);
simPanel.add(getBtn(),BorderLayout.CENTER);
simPanel.setVisible(true);
System.out.println("IN SIM" + localMaybee.screenWidth);
}
public JButton getBtn()
{
if(btn == null)
{
btn = new JButton("ENDE");
btn.setSize(70, 20);
btn.setForeground(Color.YELLOW);
btn.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
}
});
}
return btn;
}
}
那么我错过了什么
非常感谢 当前的问题是在
SimPanel.init()
中创建的JPanel
的第二个实例SimPanel
已经是JPanel
,不需要维护public JPanel SimPanel
成员
同样的问题也存在于Maybee
类中,该类扩展了JFrame
,但维护了publicjframemaynframe
成员
另外,正如上面的评论所提到的(谢谢@Frakcool!):
- 确保在
setVisible()之前调用
pack()
- 不要调用
,要重写setPreferredSize()
inteadgetPreferredSize()
- 无需扩展JFrame
- 无需在
上调用JPanel
setVisible
- 不要调用
,这是布局管理器的工作btn.setSize()
- 无需使用
,setContentPane()
默认情况下有一个JFrame
作为带有JPanel
的内容窗格。在这种情况下,调用BorderLayout
就足够了add()
JFrame
)没有意识到所有底层布局的复杂性,无法强制执行特定的大小。面板本身知道其内部布局和内容。因此,面板将其首选大小报告给布局管理器,布局管理器最终会打包内容。有关更多信息,请参阅
setBackground
虽然按钮占据了占据面板所有空间的BorderLayout
的中心,但仍有其作用。更改面板的布局并查看效果。或者将按钮移动到另一个区域,即-add(btn,BorderLayout.NORTH)代码>阅读更多信息 目前无法测试,但:1)调用pack()代码>在设置可见之前(true)代码>2)您正在Maybee
类上扩展JFrame
(并且不使用该JFrame
,因此删除扩展JFrame
部分是安全的。3)也不要调用setSize()
方法,而是重写getPreferredSize()
方法(或最大值/最小值)。您好FrakTool,这很快。不幸的是,(1)不起作用,(2)给出了一个错误。(3) 我不太明白。谢谢感谢@Frakcool!和@tenorsax。这里有很多值得思考的东西!!非常感谢。这里有很多值得思考的东西!!如果可以的话,我还有两个问题。问题1。为什么要覆盖首选尺寸,因为我希望能够随意改变组件尺寸。当我为面板设置背景颜色时,它不起作用,但当我为按钮设置背景颜色时,整个面板都会改变@斯塔福德3105这些都是好问题!请看最后的编辑。再次感谢您对我的问题的快速反应。你的解决方案和解释清楚易懂。我已经成功地实施了它们。再次感谢你和Stackoverflow@斯塔福德3105不客气!我很高兴它成功了:)
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Maybee2 {
static class SimPanel extends JPanel {
public SimPanel() {
setLayout(new BorderLayout());
JButton btn = new JButton("ENDE");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//TODO
}
});
add(btn, BorderLayout.CENTER);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
}
private static void createAndShowGUI() {
final JFrame frame = new JFrame("Maybee");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SimPanel simPanel = new SimPanel();
frame.add(simPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}