简体   繁体   English

JPanel 在 JFrame 上没有改变

[英]JPanel not changing on JFrame

The idea is to have one "global" JFrame which I can then add/remove JPanels as needed to make a smooth flowing application.这个想法是拥有一个“全局”JFrame,然后我可以根据需要添加/删除 JPanel 以制作流畅的应用程序。 Currently, when I try changing from the first JPanel to the second, the second won't display.目前,当我尝试从第一个 JPanel 更改为第二个时,第二个不会显示。 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();"我曾尝试同时使用 CardLayout 和“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.我想避免完全删除它,因为它是更改 JFrame 大小的平滑过渡。

@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 @John smith 这是从一个面板切换到另一个面板的基本示例,希望这能帮助您解决问题

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

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.当计时器停止时,它不会去任何地方,导致 UI 无法加载。 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.感谢您让我消除周围的混乱并找到问题的根源 @matt 和 @Hovercraft Full of Eels 为你们俩点赞。

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());在 jframe 中更改面板时要考虑的主要事项是布局,对于要更改为任何其他面板的 body(main) 面板,父面板的类型必须为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();
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM