空白面板 - 从另一个 class 加载面板时(在基础 class 中创建的框架)

Blank panel - When loading panel from another class (frame created in the base class)

我创建了 3 个 classes(代码如下)。

BasicDetails - 基础 class - 此处创建的框架和面板 GradeSubjectList - 派生 class - 此处创建的另一个面板并加载到基础 class 中创建的框架中 SubjectList - 派生 class - 此处创建的另一个面板并加载到基础 class

中创建的框架中

Base class 有自己的面板,单击按钮会加载在 GradeSubjectList 中创建的面板。在此面板中创建的按钮调用基础 class 中的函数,该函数又将在 SubjectList 中创建的面板加载到基础 class.

中创建的框架中

在 BasicDetails 和 GradeSubjectList 中创建的面板加载有任何问题,当在 SubjectList 中创建的面板加载到在基础 class 中创建的框架中时,仅显示在空白框架中

public class BasicDetails{

    static int lec_no;
    static int sub_no;

    JFrame frame = new JFrame("Time Table");
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    JPanel panel_bd = new JPanel();

    public static void main(String[] args) {
        BasicDetails bd = new BasicDetails();
        bd.main_method_bd();
    }

    public void main_method_bd() {

        panel_bd.setBackground(Color.white);
        frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
        panel_bd.setLayout(null);

        JLabel lec_no_lbl = new JLabel("Enter the number of lectures required per day:");
        JTextField lec_no_txt = new JTextField(5);
        lec_no_txt.setText("5");

        JButton next_btn_1 = new JButton("Next");

        panel_bd.add(lec_no_lbl);
        panel_bd.add(lec_no_txt);
        panel_bd.add(next_btn_1);

        lec_no_lbl.setBounds(5,100,300,20);
        lec_no_txt.setBounds(320,100,50,20);
        next_btn_1.setBounds(520,350,100,20);

        next_btn_1.addActionListener(e->
        {

            lec_no=Integer.parseInt(lec_no_txt.getText());
            panel_bd.setVisible(false);
            gsl(); //calls function to load the next panel
        });

        frame.setSize(screenSize.width,screenSize.height);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        frame.add(panel_bd);        
    }

    //----this function loads the panel from GradeSubjectList.java
    public void gsl() {

            GradeSubjectList GSL = new GradeSubjectList();
            JPanel gsl_panel = GSL.main_method_gsl();
            frame.add(gsl_panel);   
    }

    //-----this function loads the panel from SubjectList.java (this function gets called from GradeSubjectList.java but the panel does not load)
    public void sl() {

        SubjectList sl = new SubjectList();
        JPanel sl_panel = sl.main_mehod_sl();
        frame.add(sl_panel);        
    }   
}
public class GradeSubjectList extends BasicDetails{

    JComboBox grd_cb = new JComboBox();
    JComboBox sub_cb_1 = new JComboBox();

    public JPanel main_method_gsl() {

        //-------Panel creation and loading components------------
        JPanel panel_gsl = new JPanel();
        panel_gsl.setBackground(Color.blue);
        panel_gsl.setLayout(null);

        JLabel tec_details_txt = new JLabel("Select the Grades and Subjects");
        JButton next_btn_5 = new JButton("Next");

        next_btn_5.setBounds(600,500,150,20);
        tec_details_txt.setBounds(100,50,250,20);

        grd_cb.setBounds(10,100,100,20);
        sub_cb_1.setBounds(130,100,100,20);

        panel_gsl.add(tec_details_txt);
        panel_gsl.add(next_btn_5);
        panel_gsl.add(grd_cb);
        panel_gsl.add(sub_cb_1);

        //On click perform actions
        next_btn_5.addActionListener(e->
        {
            panel_gsl.setVisible(false);                        
            sl(); //---------calls function in BasicDetails.java to load the next panel
        });

        return(panel_gsl); ////------returns panel to BasicDetails.java to load it in the frame
    }
}
public class SubjectList extends BasicDetails{

    public JPanel main_mehod_sl() {
        //-------Panel creation and loading components------------
        
        JPanel panel_sl = new JPanel();
        panel_sl.setBackground(Color.white);
        panel_sl.setLayout(null);

        JLabel sub_list_lbl = new JLabel("Enter Subject Name");
        JLabel max_day_lbl = new JLabel("Max Lectures Per Day");
        JLabel max_week_lbl = new JLabel("Max Lectures Per Week");

        sub_list_lbl.setBounds(25,50,150,20);
        max_day_lbl.setBounds(200,50,150,20);
        max_week_lbl.setBounds(375,50,150,20);

        JButton next_btn_2 = new JButton("Next");
        next_btn_2.setBounds(600,500,150,20);

        JTextField sub_name_txt = new JTextField();
        JTextField max_day_txt = new JTextField();
        JTextField max_week_txt = new JTextField();
        sub_name_txt.setBounds(25,100,150,20);
        max_day_txt.setBounds(200,100,105,20);
        max_week_txt.setBounds(375,100,150,20);

        panel_sl.add(sub_list_lbl);
        panel_sl.add(max_day_lbl);
        panel_sl.add(max_week_lbl);
        panel_sl.add(next_btn_2);
        panel_sl.add(sub_name_txt);
        panel_sl.add(max_day_txt);
        panel_sl.add(max_week_txt);
        
        //On click action
        next_btn_2.addActionListener(e->
        {
            panel_sl.setVisible(false);         
        });

        return(panel_sl); //------returns panel to BasicDetails.java to load it in the frame
    }
}

我已经更改了从其他 classes 加载面板的顺序。我注意到首先加载的面板(从另一个 class)加载没有任何问题,而另一个面板没有。

例如如果订单是

  1. GradeSubjectList - 面板正确加载
  2. SubjectList - 面板不显示

而且是顺序变了

  1. SubjectList - 面板正确加载
  2. GradeSubjectList - 面板不显示

所以我的猜测是大部分代码都工作正常...不能仅仅找出哪里出了问题...

序列中的第三个面板不可见的主要问题是因为它每次都被添加到 JFrame 的新实例中。因为 SubjectList 继承自 BasicDetails(与 GradeSubjectList 相同)并且因为 frame 引用不是 static,每个新的 BasicDetails 对象(包括任何新的GradeSubjectListSubjectList 的实例)获取 JFrame 的新实例,其中序列中的下一个面板(当按下相应的 Next 按钮时)被添加到新的 JFrame.

一个解决方案是将 frame 作为 static 参考 and/or 重新访问您的 class 图。

除此之外,始终尝试使用 LayoutManager(而不是 setLayout(null);)。在您的情况下, CardLayout 会在需要时处理将序列中的每个面板设置为 [in]visible 的工作,这样您就不必手动进行。您还可以为添加到 frame 的每个面板使用 LayoutManager(例如 GridBagLayout)。