[英]External JPanel classs does not show correctly in Main JFrame class
基本上我正在嘗試理解Java中的Threads。所以我想我會創建一個主JFrame類,其中包含兩個來自外部類的JPanel,然后在一個中執行某些操作並使用來自第二個面板的消息來控制它。到目前為止我只創建了第一個外部面板,問題開始了! 雖然它似乎是“已加載”但它沒有正確顯示。(請參閱system.out行)所以這里是主類
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
成員。
同樣的問題在於擴展JFrame
的Maybee
類,但維護public JFrame maynFrame
成員。
另外,正如上面的評論中已經提到的那樣(感謝@Frakcool!):
確保在setVisible()
之前調用pack()
setVisible()
;
不要調用setPreferredSize()
,重寫getPreferredSize()
intead;
無需擴展JFrame
;
無需在JPanel
上調用setVisible
;
不要調用btn.setSize()
,它是布局管理器的工作;
不需要setContentPane()
,默認情況下JFrame
將JPanel
作為帶有BorderLayout
內容窗格。 在這種情況下調用add()
就足夠了。
以下是原始代碼的略微修改版本(為簡潔起見而簡化):
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();
}
});
}
}
編輯 :
該應用程序可能包含許多面板。 諸如JFrame
高級容器不知道所有底層布局復雜性,並且不能強制執行特定大小。 面板本身知道其內部布局及其內容。 因此,面板向布局管理器報告其首選大小,布局管理器最終打包內容。 有關詳細信息,請參閱在容器中布置組件 。
setBackground
雖然按鈕占據了BorderLayout
的中心,但它占據了面板的所有空間。 更改面板的布局並查看效果。 或者將按鈕移動到另一個區域,即 - add(btn, BorderLayout.NORTH);
閱讀布局管理器可視指南中的更多內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.