簡體   English   中英

JPanel 在 JFrame 上沒有改變

[英]JPanel not changing on JFrame

這個想法是擁有一個“全局”JFrame,然后我可以根據需要添加/刪除 JPanel 以制作流暢的應用程序。 目前,當我嘗試從第一個 JPanel 更改為第二個時,第二個不會顯示。 我的代碼如下:

處理程序(運行應用程序的類):

package com.example.Startup;

import com.example.Global.Global_Frame;

public class Handler 
{
public Handler()
{
    gf = new Global_Frame();

        gf.getAccNum();
        gf.setVisible(true);
}

public static void main(String[] args) 
{
    new Handler();
}

Global_Frame gf = null;
}

public static void main(String[] args) 
{
    new Handler();
}

Global_Vars gv = null;
Global_Frame gf = null;
}

全局框架:

package com.example.Global;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import com.example.FirstRun.AccDetails;
import com.example.FirstRun.FirstTimeRun;

public class Global_Frame extends JFrame 
{
private static final long serialVersionUID = 1L;

ActionListener val = new ActionListener()
{
    public void actionPerformed(ActionEvent e) 
    {
        getUserDetails();
    }
};

public Global_Frame()
{

    try 
    {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // get look and feel based on OS
    } 
    catch (ClassNotFoundException ex) // catch all errors that may occur
    {
        Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
    } 
    catch (InstantiationException ex) 
    {
        Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
    } 
    catch (IllegalAccessException ex) 
    {
        Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
    } 
    catch (UnsupportedLookAndFeelException ex) 
    {
        Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
    }

    EventQueue.invokeLater(new Runnable()
    {
        public void run() //run the class's constructor, therefore starting the UI being built
        {
            initComponents();
        }
    });
}

public void initComponents()
{
    setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe

    revalidate(); // revalidate the elements that will be displayed
    repaint(); // repainting what is displayed if going coming from a different form
    pack(); // packaging everything up to use
    setLocationRelativeTo(null); // setting form position central
}

public void getAccNum()
{
    setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
    FirstTimeRun panel1 = new FirstTimeRun(val);
    add(panel1);

    revalidate();
    repaint();
    pack();
}

public void getUserDetails()
{
    getContentPane().removeAll();

    resizing(750, 500);
    AccDetails panel2 = new AccDetails();
    add(panel2);

    revalidate();
    repaint();
    pack();
}

private void resizing(int width, int height)
{
    timer = new Timer (10, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent arg0) 
        {
            getContentPane().removeAll();
            setPreferredSize(new Dimension(sizeW, sizeH));

            revalidate();
            repaint();
            pack();

            if (!wToggle)
                sizeW += 2;

            if (!hToggle)
            sizeH += 2;

            if (toggle)
            {
                setLocationRelativeTo(null);
                toggle = false;
            }
            else
                toggle = true;

            if (sizeW == width)
                wToggle = true;

            if (sizeH == height)
                hToggle = true;

            if (hToggle && wToggle)
                timer.stop();
        }
    });

    timer.start();
}

//variables used for window resizing
private Timer timer;
private int sizeW = 600;
private int sizeH = 400;
private boolean toggle = false;
private boolean wToggle = false;
private boolean hToggle = false;

public int accNum = 0;
}

第一個面板:

package com.example.FirstRun;

import java.awt.Dimension;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;

public class FirstTimeRun extends JPanel 
{
private static final long serialVersionUID = 1L;

public FirstTimeRun()
{
}

public FirstTimeRun(ActionListener val)
{
    initComponents(val);
}

private void initComponents(ActionListener val) // method to build initial view for user for installation
{
    pnlStart = new JPanel[1];
    btnNext = new JButton();
    pnlStart[0] = new JPanel();

    btnNext.setText("Next"); // adding text to button for starting
    btnNext.setPreferredSize(new Dimension(80, 35)); //positioning start button
    btnNext.addActionListener(val);
    pnlStart[0].add(btnNext); // adding button to JFrame

    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    add(pnlStart[0]);
}

// objects used in UI
private JPanel[] pnlStart;
private JButton btnNext;
}

第二面板:

package com.example.FirstRun;

import java.awt.BorderLayout;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class AccDetails extends JPanel
{
private static final long serialVersionUID = 1L;

public AccDetails()
{
    accAssets();
}

private void accAssets()
{   
    // instantiating elements of the GUI
    pnlAccDetails = new JPanel[2];
    lblWelcome = new JLabel();
    lblMain = new JLabel();

    for (int i = 0; i < 2; i++)
        pnlAccDetails[i] = new JPanel();

    lblWelcome.setText("Welcome to Example_App"); // label welcoming user
    pnlAccDetails[0].setLayout(new BoxLayout(pnlAccDetails[0], BoxLayout.LINE_AXIS));
    pnlAccDetails[0].add(lblWelcome); // adding label to form

    lblMain.setText("<html>The following information that is collected will be used as part of the Example_App process to ensure that each user has unique Example_App paths. Please fill in all areas of the following tabs:</html>"); // main label that explains what happens, html used for formatting
    pnlAccDetails[1].setLayout(new BorderLayout());
    pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_START);
    pnlAccDetails[1].add(lblMain, BorderLayout.CENTER); //adding label to JFrame
    pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_END);

    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    add(pnlAccDetails[0]);
    add(pnlAccDetails[1]);
}

private JLabel lblWelcome;  
private JLabel lblMain;
private JPanel[] pnlAccDetails;
}

我曾嘗試同時使用 CardLayout 和“revalidate();” “重繪();” 和“包();” 選項,我很困惑為什么它沒有顯示。 在此先感謝您提供的任何幫助。

編輯:在削減我的代碼時,如果刪除了“調整大小”方法,則在面板更改時會顯示對象。 我想避免完全刪除它,因為它是更改 JFrame 大小的平滑過渡。

@John smith 這是從一個面板切換到另一個面板的基本示例,希望這能幫助您解決問題

代碼:

package stack;

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.JLabel;
import javax.swing.JPanel;

public class RemoveAndAddPanel implements ActionListener{
  JFrame frame;
  JPanel firstPanel;
  JPanel secondPanel;
  JPanel controlPanel;
  JButton nextButton;

  public RemoveAndAddPanel() {
    JFrame.setDefaultLookAndFeelDecorated(true);
    frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    firstPanel = new JPanel();
    firstPanel.add(new JLabel("FirstPanel"));
    firstPanel.setPreferredSize(new Dimension(100,100));

    secondPanel = new JPanel();
    secondPanel.add(new JLabel("Second panel"));
    secondPanel.setPreferredSize(new Dimension(100,100));

    nextButton = new JButton("Next panel");
    controlPanel = new JPanel();

    nextButton.addActionListener(this);

    controlPanel.add(nextButton);

    frame.setLayout(new BorderLayout());
    frame.add(firstPanel,BorderLayout.CENTER);
    frame.add(controlPanel, BorderLayout.SOUTH);

    frame.setVisible(true);
    frame.setSize(300,100);
  }
  @Override
  public void actionPerformed(ActionEvent e) {
    if(e.getSource() == nextButton) {
      frame.remove(firstPanel);
      frame.add(secondPanel);

      nextButton.setEnabled(false);
    }
    frame.validate();
  }
  public static void main(String args[]) {
    new RemoveAndAddPanel();
  }
}

正如編輯中提到的,問題在於調整大小方法。 當計時器停止時,它不會去任何地方,導致 UI 無法加載。 代碼的修復是清除屏幕並將調整大小的調用添加到動作偵聽器。 然后在之后添加對下一個方法的調用:

timer.stop();

感謝您讓我消除周圍的混亂並找到問題的根源 @matt 和 @Hovercraft Full of Eels 為你們倆點贊。

在 jframe 中更改面板時要考慮的主要事項是布局,對於要更改為任何其他面板的 body(main) 面板,父面板的類型必須為CardLayout body.setLayout(new java.awt.CardLayout());

之后,您現在可以使用下面的示例代碼輕松地在面板之間切換

 private void updateViewLayout(final HomeUI UI, final JPanel paneeelee){

        final JPanel body = UI.getBody(); //this is the JFrame body panel and must be of type cardLayout
        System.out.println("Page Loader Changing View");

        new SwingWorker<Object, Object>() {

            @Override
            protected Object doInBackground() throws Exception {
                body.removeAll();//remove all visible panel before
                body.add(paneeelee);
                body.revalidate();
                body.repaint();
               return null;
            }

            @Override
            protected void done() {
                UI.getLoader().setVisible(false);
            }  
        }.execute();
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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