[英]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.