繁体   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