簡體   English   中英

外部JPanel類在Main JFrame類中無法正確顯示

[英]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成員。

同樣的問題在於擴展JFrameMaybee類,但維護public JFrame maynFrame成員。

另外,正如上面的評論中已經提到的那樣(感謝@Frakcool!):

  • 確保在setVisible()之前調用pack() setVisible() ;

  • 不要調用setPreferredSize() ,重寫getPreferredSize() intead;

  • 無需擴展JFrame ;

  • 無需在JPanel上調用setVisible ;

  • 不要調用btn.setSize() ,它是布局管理器的工作;

  • 不需要setContentPane() ,默認情況下JFrameJPanel作為帶有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM