Java CardLayout:“;JButton在以下情况下可见……”;不起作用
亲爱的朋友们:, 我已经试着解决这个问题两周了。提前感谢您的帮助。 我想做的事:Java CardLayout:“;JButton在以下情况下可见……”;不起作用,java,swing,cardlayout,Java,Swing,Cardlayout,亲爱的朋友们:, 我已经试着解决这个问题两周了。提前感谢您的帮助。 我想做的事: 我有一个卡片布局,可以在不同的JPanel之间切换 Pan1有不同的按钮,如果变量Level1设置为“1”,则这些按钮应该是可见的 Pan2由Pan1启动,有一个将变量Level1设置为“1”的按钮和一个随后返回Pan1的按钮 当我回到Pan1时,我现在应该看到一个按钮,因为变量是1 问题: 变量被正确设置为1,但当我返回Pan1时,按钮不可见。我试着重新油漆,重新验证,但似乎没有任何效果 我的代码 packa
- 我有一个卡片布局,可以在不同的JPanel之间切换李>
- Pan1有不同的按钮,如果变量Level1设置为“1”,则这些按钮应该是可见的
- Pan2由Pan1启动,有一个将变量Level1设置为“1”的按钮和一个随后返回Pan1的按钮
- 当我回到Pan1时,我现在应该看到一个按钮,因为变量是1
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本身内部,也可以在调用
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提供了一个方法OnComponentShowed()
,每次显示组件时都会调用该方法。在这种方法中,您可以执行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);
}
}
你好,StanislavL,感谢您抽出时间回答!我明白你说的:invalidate+revalidate太过分了,但我到了一个绝望的地步:)我不确定我是否能理解你的其他评论tho:按钮与我设置完成级别的窗口不同。你能帮我了解一下你是如何将按钮设置为从那里可见的吗?