Java CardLayout:"JButton visible if..." 不工作
Java CardLayout: "JButton visible if..." not working
亲爱的 Whosebug 朋友们,
我一直在尝试解决这个问题 2 周。预先感谢您的帮助。
我想做什么:
- 我有一个在不同 JPanel 之间切换的 CardLayout。
- Pan1 有不同的按钮,如果变量 Level1 设置为“1”,这些按钮应该可见
- Pan2 由 Pan1 启动,并有一个将变量 Level1 设置为“1”的按钮和一个随后返回 Pan1 的按钮
- 当我回到 Pan1 时,我现在应该看到一个按钮,因为变量是 1
问题:
该变量已正确设置为 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);
}
}
亲爱的 Whosebug 朋友们, 我一直在尝试解决这个问题 2 周。预先感谢您的帮助。 我想做什么:
- 我有一个在不同 JPanel 之间切换的 CardLayout。
- Pan1 有不同的按钮,如果变量 Level1 设置为“1”,这些按钮应该可见
- Pan2 由 Pan1 启动,并有一个将变量 Level1 设置为“1”的按钮和一个随后返回 Pan1 的按钮
- 当我回到 Pan1 时,我现在应该看到一个按钮,因为变量是 1
问题: 该变量已正确设置为 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);
}
}