JPanel not changing on JFrame

徘徊边缘 提交于 2021-02-17 05:43:25

问题


The idea is to have one "global" JFrame which I can then add/remove JPanels as needed to make a smooth flowing application. Currently, when I try changing from the first JPanel to the second, the second won't display. My code is below:

Handler (class to run the app):

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;
}

Global Frame:

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;
}

First Panel:

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;
}

Second Panel:

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;
}

I have tried using both a CardLayout and the "revalidate();" "repaint();" and "pack();" options and I'm stumped as to why it's not showing. Thanks in advance for any help that can be offered.

EDIT: While cutting down my code, if the "resizing" method is removed, the objects are shown when the panels change. I would like to avoid having to remove this completely as it's a smooth transition for changing the JFrame size.


回答1:


@John smith it is basic example of switch from one panel to other panel I hope this will help you to sort out your problem

Code:

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();
  }
}



回答2:


As mentioned in the edit, the problem lay within the resizing method. When the timer stopped, it wouldn't go anywhere, causing the UI to not load. The fix to the code is clearing the screen and adding the call to resizing to the actionlistener. Then adding a call to the next method after:

timer.stop();

Thanks for getting me to remove the mess around it and find the source of the problem @matt & @Hovercraft Full of Eels upvotes for both of you.




回答3:


The main thing to consider while changing panel in a jframe is the layout, for a body(main) panel to change to any other panel the parent panel must be of type CardLayout body.setLayout(new java.awt.CardLayout());

After that you can now easily switch between panels wiht the sample code below

 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();
    }


来源:https://stackoverflow.com/questions/45278460/jpanel-not-changing-on-jframe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!