Java JInternalFrame 未刷新并返回错误

Java JInternalFrame not refreshing and returning an error

亲爱的 Whosebug 朋友,

由于我被困在一个小接口的编程中,我恳请您的帮助:

这是我正在尝试做的事情: 我有一个带有几个内部框架的 JDesktopPane。逻辑是: - DesktopPane 以 Launch Window(一个 JInternalFrame)开始,它有级别 1 的按钮 - 用户点击 Level 1,一个新的 JInternal Window Level 1 打开(launch window closes)一个按钮 - 用户点击按钮并设置level 1完成 - JInternal Window 1 级关闭 - launch window 重新打开,但是,由于 1 级已设置为已完成,现在 Launch window 有一个新按钮可以访问 2 级 - 用户单击该按钮并访问级别 2,依此类推

事情是这样的 - 我启动了程序,我得到了带有 1 级按钮的启动 window - 我点击按钮然后返回启动 window 但 - 2级没有按钮 - 此外:如果我再次单击按钮级别 1,我会收到错误消息

这是我的代码:我希望有人能指出我正确的方向 主要CLASS

package gioco;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDesktopPane; 
import javax.swing.JFrame; 
import javax.swing.JInternalFrame; 
import javax.swing.border.EmptyBorder;

public class AllInAWindow extends JFrame {
//create components outside constructor    
JDesktopPane MainDesktopPane = new JDesktopPane();
JInternalFrame IFrameLaunchWindow = new JInternalFrame(); 
JInternalFrame IFrameLevel1 = new JInternalFrame(); 
JInternalFrame IFrameLevel2 = new JInternalFrame();


//let's create the constructor    
public AllInAWindow() {
    initUI(); 
}
public void initUI(){

    VariablesSetEGet VariablesSetEGetObj = new VariablesSetEGet(); 
    //-------------------------IFrame Level1--------------------------//        
    //interface of IFrame Level1
    IFrameLevel1.setTitle("Level 1");
    IFrameLevel1.setSize(200, 200);
    IFrameLevel1.setLocation(200, 200);
    IFrameLevel1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);  
    JButton action1L1 = new JButton("action 1 Level1");
    action1L1.setBorder(new EmptyBorder(5 ,5, 5, 5));
    IFrameLevel1.add(action1L1);
    //button action
    roundLevelAction1 roundLevelAction1Obj = new roundLevelAction1(); //create object of the constructor                  
    action1L1.addActionListener(roundLevelAction1Obj);//add listener to JButton and pass it through the constructor

    //-------------------------IFrame Level2--------------------------//        
    //interface of IFrame Level2
    IFrameLevel2.setTitle("Level 2");
    IFrameLevel2.setSize(200, 200);
    IFrameLevel2.setLocation(300, 300);        
    IFrameLevel2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);  
    JButton action1L2 = new JButton("action 1 Level2");
    action1L2.setBorder(new EmptyBorder(5 ,5, 5, 5));
    IFrameLevel2.add(action1L2);
    //button action
    roundLevelAction2 roundLevelAction2Obj = new roundLevelAction2(); //create object of the constructor                  
    action1L2.addActionListener(roundLevelAction2Obj);//add listener to JButton and pass it through the constructor

    //-------------------------iFrame Launch window-----------------------------//
    IFrameLaunchWindow.setLayout(null);
    IFrameLaunchWindow.setTitle("INIZIO");
    IFrameLaunchWindow.setClosable(true);
    IFrameLaunchWindow.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE);
    IFrameLaunchWindow.setSize(400, 400);                
    //button level 1
    JButton ButtonLevel1 = new JButton("level1"); //create the button variable
    ButtonLevel1.setSize(200, 40);
    ButtonLevel1.setLocation(100, 120);
    ButtonLevel1.addActionListener//add the listener so that the button can launch the window with the board level
    (new ActionListener()
        {
            public void actionPerformed (ActionEvent lanciaLevel1) //create the action
            {                    
                MainDesktopPane.add(IFrameLevel1); //launch the frame with the level 1
                IFrameLevel1.setVisible(true); //set it to visible
                IFrameLaunchWindow.dispose();//close this launch window                     
            }
        }
    );
    IFrameLaunchWindow.add(ButtonLevel1); //add the button of the level 1
    ButtonLevel1.setVisible(true);
    //button level 2
    JButton ButtonLevel2 = new JButton("level2"); 
    ButtonLevel2.setSize(200, 40);
    ButtonLevel2.setLocation(100, 180);
    ButtonLevel2.addActionListener
    (new ActionListener()
        {
            public void actionPerformed (ActionEvent lanciaLevel2)
            {                                             
                MainDesktopPane.add(IFrameLevel2); //launch the frame with the level 2
                IFrameLevel1.setVisible(true); //set it to visible
                IFrameLaunchWindow.dispose();//close this launch window                     
            }
        }
    );
    //same as before but here the if: if level1 is not set to completed the button for level2 won't appear
    if (VariablesSetEGetObj.getL1()==1){
        IFrameLaunchWindow.add(ButtonLevel2);  
        ButtonLevel2.setVisible(true);
    }        
    //button level 3 (just for image, same logic)
    JButton ButtonLevel3 = new JButton("level3"); 
    ButtonLevel3.setSize(200, 40);
    ButtonLevel3.setLocation(100, 240);
    if (VariablesSetEGetObj.getL2()==1){
        IFrameLaunchWindow.add(ButtonLevel3);  
        ButtonLevel3.setVisible(true);
    }        

    MainDesktopPane.add(IFrameLaunchWindow); //start the main panel with the launch window
    IFrameLaunchWindow.setVisible(true);
    add(MainDesktopPane);//add the main desktopPane to the Frme                
}

class roundLevelAction1 implements ActionListener {//action of the button in IFrame 1
    public roundLevelAction1(){
            //there are graphical elements here in the original code but not relevant for this
    }         
        @Override
        public void actionPerformed(ActionEvent ActionLevel1) {//if button is clicked
            VariablesSetEGet VariablesSetEGetObj = new VariablesSetEGet(); 
            VariablesSetEGetObj.setL1(1);//set Level 1 to complete 
            IFrameLevel1.dispose(); //close L1 window
            //go back to launch window but now it should show button to access L2 as L1 has been set to completed
            MainDesktopPane.add(IFrameLaunchWindow); 
            IFrameLaunchWindow.setVisible(true);

        }
}

class roundLevelAction2 implements ActionListener {//action of button in IFrame2
    public roundLevelAction2(){
            //there are graphical elements here in the original code but not relevant for this
    }         
        @Override
        public void actionPerformed(ActionEvent ActionLevel2) {//if button is clicked
            VariablesSetEGet VariablesSetEGetObj = new VariablesSetEGet(); 
            VariablesSetEGetObj.setL2(1);//set level 2 to complete
            IFrameLevel2.dispose(); //close L2 window
            //go back to launch window but now it should show button to access L3 as L2 has been set to completed
            MainDesktopPane.add(IFrameLaunchWindow); 
            IFrameLaunchWindow.setVisible(true);                
        }
}


public static void main (String[]args) {
    //as this will launch the "fresh" new game, we set each level (and therefore button) 
    //to disabled except button 1. we do it here outside the runnable
    VariablesSetEGet VariablesSetEGetObj = new VariablesSetEGet(); 
    VariablesSetEGetObj.setL1(0);
    VariablesSetEGetObj.setL2(0);
    //TRIGGER LAUNCH WINDOW (see ZCode1)
    EventQueue.invokeLater
    (new Runnable() 
        { 
            @Override
            public void run() 
            {
                AllInAWindow AllInAWindowObj = new AllInAWindow(); 
                AllInAWindowObj.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                AllInAWindowObj.setVisible(true);
                AllInAWindowObj.setSize(800, 800);
            }
        }   
    );
}
}

分开CLASS

public class VariablesSetEGet {
static int L1 = 0; 
public void setL1 (int L1){
    this.L1 = L1; 
}
public int getL1 (){
    return L1; 
}
static int L2 = 0; 
public void setL2 (int L2){
    this.L2 = L2; 
}
public int getL2 (){
    return L2; 
}    
}

非常感谢您的帮助

这不是最初问题的解决方案:这是根据 MadProgrammer 的建议更改逻辑,即放弃 JInternalFrame 并使用 CardLayout。通过对 CardLayout 的研究,我设法做到了我最初想做的事情。 代码在这里

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CLayout {
    //1) create the Frame
    JFrame MainWindow = new JFrame("Finestra di Gioco"); 
    //2) create as many JPanels as messages + levels, but...
    JPanel panelCont = new JPanel(); //...the first one needs to contain them all
    JPanel FinestraLancio = new JPanel(); 
    JPanel Livello1 = new JPanel(); 
    JPanel Livello2 = new JPanel(); 
    //3) create the buttons to switch among panels
    JButton OpenLevel1 = new JButton("Open Level 1"); 
    JButton CompleteLevel1 = new JButton("Complete Level 1"); 
    JButton OpenLevel2 = new JButton("Open Level 2"); 
    JButton CompleteLevel2 = new JButton("Complete Level 2"); 

    //4) create an instance of the card Layout method
    CardLayout cl = new CardLayout(); 

    //5) create the constructor
    public CLayout(){
        //5.a) assign the instance of the card Layout to the container panel
        panelCont.setLayout(cl);

        //5.b) create the windows insert the buttons, assign the actions
        FinestraLancio.add(OpenLevel1); 
        FinestraLancio.add(OpenLevel2);
        OpenLevel2.setVisible(false);
        Livello1.add(CompleteLevel1); 
        Livello2.add(CompleteLevel2); 

        Livello1.setBackground(Color.yellow);
        Livello2.setBackground(Color.blue);

        OpenLevel1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent OpenLevel1){
                cl.show(panelCont, "2"); //this "2" is the position indicator, 
                                        //we'll discuss it at 5c
            }
        });

        OpenLevel2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent OpenLevel2){
                cl.show(panelCont, "3");
            }
        });

        CompleteLevel1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent CompleteLevel1){
                OpenLevel2.setVisible(true);
                cl.show(panelCont, "1");
            }
        });
        CompleteLevel2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent CompleteLevel2){
                OpenLevel2.setVisible(false);
                cl.show(panelCont, "1");
            }
        });        
        //5.c) now put the elements in the container panel, and add the name of 
        //the element and the position indicator you will need that position 
        //indicator when you want to call that specific window
        panelCont.add(FinestraLancio, "1"); //"1" is the position indicator
        panelCont.add(Livello1, "2"); 
        panelCont.add(Livello2, "3"); 

        //now indicate that the instance of the cardlayout has the container as 
        //its main panel and inside the container the first panel to be displayed 
        //is the one with the position indicator "1", i.e. the LaunchWindow
        cl.show(panelCont, "1");

        //create the main window
        MainWindow.add(panelCont); 
        MainWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        MainWindow.setSize(400, 400);
        MainWindow.setVisible(true);

    }

    public static void main (String[]args){
        SwingUtilities.invokeLater
        (new Runnable(){
            @Override
            public void run(){
                new CLayout(); 
            }
        }); 
    }

}