Java CardLayout:"JButton visible if..." 不工作

Java CardLayout: "JButton visible if..." not working

亲爱的 Whosebug 朋友们, 我一直在尝试解决这个问题 2 周。预先感谢您的帮助。 我想做什么

问题: 该变量已正确设置为 1,但当我返回 Pan1 时,该按钮不可见。我试过重绘、重新验证,但似乎没有任何效果

我的代码

package prove3;

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.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class PRINCIPAL extends Level1{
JFrame MainWindow; 
JPanel panelCont; 
Pan1 Pan1Window; 
Pan2 Pan2Window; 
CardLayout cards; 

public PRINCIPAL(){
    MainWindow = new JFrame("Game Window"); 
    panelCont = new JPanel(); 
    cards = new CardLayout(); 
    Pan1Window = new Pan1(cards, panelCont, Level1Completed); 
    Pan2Window = new Pan2(Pan1Window, cards, panelCont, Level1Completed); 

    panelCont.setLayout(cards);
    panelCont.add(Pan1Window, "1"); 
    panelCont.add(Pan2Window, "2"); 
    cards.show(panelCont, "1");

    MainWindow.add(panelCont);
    MainWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    MainWindow.setSize(800, 800);
    MainWindow.setVisible(true);

}

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

class Level1 extends JPanel{

    static int Level1Completed = 0;    

    public void setLevel1Completed (int newLevel1Completed){
        Level1Completed = newLevel1Completed;  
    }

    public int getLevel1Completed(){
        return Level1Completed; 
    }
}

class Pan1 extends Level1 {
JPanel panelCont; 
CardLayout LayoutPan1; 
JLabel label; 
JButton OpenPan2; 
JButton buttonLevel2; 
int L1Completed; 

public Pan1(
            final CardLayout LayoutPan1, 
            final JPanel panelCont, 
            final int Level1Completed)
{
    this.L1Completed = super.getLevel1Completed(); 
    this.panelCont = panelCont; 
    this.LayoutPan1 = LayoutPan1; 

    OpenPan2 = new JButton("Open Pan2 Window"); 
    buttonLevel2 = new JButton("Progress to Level 2"); 
    OpenPan2.addActionListener
    (new ActionListener()
        {
            public void actionPerformed (ActionEvent GoToPan2)
            {
                if (GoToPan2.getSource() == OpenPan2){
                    LayoutPan1.show(panelCont, "2"); 
                }
            }
        }
    );
    add(OpenPan2); 

    //this printout is to see that, at the beginning, the Level1 variable is set to 0 (see the command line)
    System.out.println(getLevel1Completed());                    

    //this is where the problem is: what I want is that this button is initially not visible as the variable is set to 0
    //but when, in the next pan, I'll set it to 1, this button becomes visible
    if (super.getLevel1Completed()==1){
        add(buttonLevel2);  
        buttonLevel2.setVisible(true);
        invalidate(); 
        revalidate(); 
    }          

    setBackground(Color.GREEN);
}   
}

class Pan2 extends Level1 {
JPanel Pan1Window; 
CardLayout LayoutPan1Window; 
JPanel panelCont;     
JButton OpenPan1; 
JButton L1Done; 
int L1Completed; 

public Pan2(
        final JPanel Pan1Window, 
        final CardLayout LayoutPan1Window, 
        final JPanel panelCont, 
        final int L1Completed
){
    this.L1Completed = super.getLevel1Completed(); 
    OpenPan1 = new JButton("Go back to Pan 1");         
    OpenPan1.addActionListener
    (new ActionListener()
        {
            public void actionPerformed(ActionEvent ApriFinestraLancio)
            {
                if(ApriFinestraLancio.getSource()==OpenPan1){
                    LayoutPan1Window.show(panelCont, "1");                        
                }
            }
        }
    );
    add(OpenPan1); 

    L1Done = new JButton("Set Level 1 as Completed"); 
    L1Done.addActionListener
    (new ActionListener()
        {
            public void actionPerformed(ActionEvent SettaL1Complet)
            {
                setLevel1Completed(1); 
                System.out.println(getLevel1Completed());//this print shows that the value of the variable is correctly changed to 1
            }
        }
    );
    add(L1Done); 

    setBackground(Color.RED);
}       
}

非常欢迎任何帮助

if (super.getLevel1Completed()==1){
    add(buttonLevel2);  
    buttonLevel2.setVisible(true);
    invalidate(); 
    revalidate(); 
}  

应该在设置 level1Completed 的地方调用代码。它可能在 setter 本身内部或在您调用

的 actionPerfomed() 中
            setLevel1Completed(1); 
            System.out.println(getLevel1Completed());

无需调用 invalidate() 和 revalidate()。重新验证就足够了。我建议最初添加按钮并使其不可见。因此你只需要调用

buttonLevel2.setVisible(super.getLevel1Completed()==1); to change the button's visibility

问题是,您只检查 Pan1 的构造函数中是否设置了 level1。因此,如果您调用 show LayoutPan1Window.show(panelCont, "1");,则不再检查该变量。 解决方案是为 Pan1 实施 ComponentListener。 ComponentListener 提供了一种方法 onComponentShown(),每次显示组件时都会调用该方法。在此方法中,您可以执行 level1 变量的检查。代码可能如下所示:

    import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class PRINCIPAL extends Level1 {
    JFrame MainWindow;
    JPanel panelCont;
    Pan1 Pan1Window;
    Pan2 Pan2Window;
    CardLayout cards;

    public PRINCIPAL() {
        MainWindow = new JFrame("Game Window");
        panelCont = new JPanel();
        cards = new CardLayout();
        Pan1Window = new Pan1(cards, panelCont, Level1Completed);
        Pan2Window = new Pan2(Pan1Window, cards, panelCont, Level1Completed);

        panelCont.setLayout(cards);
        panelCont.add(Pan1Window, "1");
        panelCont.add(Pan2Window, "2");
        cards.show(panelCont, "1");

        MainWindow.add(panelCont);
        MainWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        MainWindow.setSize(800, 800);
        MainWindow.setVisible(true);

    }

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

    class Level1 extends JPanel {

    static int Level1Completed = 0;

    public void setLevel1Completed(int newLevel1Completed) {
        Level1Completed = newLevel1Completed;
    }

    public int getLevel1Completed() {
        return Level1Completed;
    }
    }

    class Pan1 extends Level1 implements ComponentListener {
    JPanel panelCont;
    CardLayout LayoutPan1;
    JLabel label;
    JButton OpenPan2;
    JButton buttonLevel2;
    int L1Completed;

    public Pan1(final CardLayout LayoutPan1, final JPanel panelCont,
            final int Level1Completed) {
        this.L1Completed = super.getLevel1Completed();
        this.panelCont = panelCont;
        this.LayoutPan1 = LayoutPan1;
        addComponentListener(this);

        OpenPan2 = new JButton("Open Pan2 Window");
        buttonLevel2 = new JButton("Progress to Level 2");
        OpenPan2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent GoToPan2) {
                if (GoToPan2.getSource() == OpenPan2) {
                    LayoutPan1.show(panelCont, "2");
                }
            }
        });
        add(OpenPan2);

        // this printout is to see that, at the beginning, the Level1 variable
        // is set to 0 (see the command line)
        System.out.println(getLevel1Completed());

        setBackground(Color.GREEN);
    }

    @Override
    public void componentHidden(ComponentEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void componentMoved(ComponentEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void componentResized(ComponentEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void componentShown(ComponentEvent e) {
        // this is where the problem is: what I want is that this button is
        // initially not visible as the variable is set to 0
        // but when, in the next pan, I'll set it to 1, this button becomes
        // visible
        if (super.getLevel1Completed() == 1) {
            add(buttonLevel2);
            buttonLevel2.setVisible(true);
            invalidate();
            revalidate();
        }
    }
    }

    class Pan2 extends Level1 {
    JPanel Pan1Window;
    CardLayout LayoutPan1Window;
    JPanel panelCont;
    JButton OpenPan1;
    JButton L1Done;
    int L1Completed;

    public Pan2(final JPanel Pan1Window, final CardLayout LayoutPan1Window,
            final JPanel panelCont, final int L1Completed) {
        this.L1Completed = super.getLevel1Completed();
        OpenPan1 = new JButton("Go back to Pan 1");
        OpenPan1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ApriFinestraLancio) {
                if (ApriFinestraLancio.getSource() == OpenPan1) {
                    LayoutPan1Window.show(panelCont, "1");
                }
            }
        });
        add(OpenPan1);

        L1Done = new JButton("Set Level 1 as Completed");
        L1Done.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent SettaL1Complet) {
                setLevel1Completed(1);
                System.out.println(getLevel1Completed());// this print shows
                                                            // that the value of
                                                            // the variable is
                                                            // correctly changed
                                                            // to 1
            }
        });
        add(L1Done);

        setBackground(Color.RED);
    }
    }