CardLayout 中的按钮不起作用
Button in CardLayout not working
因此,我在我的一个程序中使用了 cardLayout,并且我正在努力做到这一点,以便在您单击按钮时加载下一个面板。我有一个 panelHolder class,其中保存了卡片布局,每次按下面板上的按钮时,它都会调用 panelHolder class 中的一个方法,该方法根据按钮将某个布尔变量设置为 true并调用重绘(显示面板的位置)。出于某种原因,我的按钮不起作用,而且我似乎无法找出原因。有人可以帮助我吗?
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.Arrays;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.*;
public class SheetReader101 extends JFrame {
public SheetReader101(){
super("SheetReader101");
setSize(2000,1000);
setLocation(0,0);
setResizable(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
PanelHolder pg2 = new PanelHolder();
setContentPane(pg2);
setVisible(true);
}
public static void main(String[]args){
SheetReader101 z1 = new SheetReader101();
}
}
class PanelHolder extends JPanel { // HERE
CardLayout clayout = new CardLayout();
PianoGameContent x;
tutorial y;
boolean [] paneldecide;
PanelHolder() {
super();
y = new tutorial();
x = new PianoGameContent();
setLayout(clayout);
this.add("Tutorial", y);
this.add("FreePlay Mode", x);
paneldecide = new boolean[15];
}
public static void main(String[]args){
PanelHolder z1 = new PanelHolder();
z1.run();
}
public void run(){
layoutShower(0);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
}
public void layoutShower (int decide){
{
PianoGameContent y2 = new PianoGameContent();
PanelHolder.this.add("Piano", y2);
System.out.println("intro slide run");
if(decide == 1){
PanelHolder.this.add("Piano", y2);
System.out.println("testing11");
clayout.show(PanelHolder.this,"Piano");
}
}
}
}
我 "suspect" 核心问题与您发布的原始代码有关,您在子视图的 ActionListener
中创建 PanelHolder
的新实例,然后正在尝试切换视图,此新实例与屏幕上的实例无关。
有几种方法可以管理 CardLayout
,我的首选方法是使用某种 "navigation" 控制器来定义导航的工作方式,例如,您可以 "next" 和 "previous" 或 "back",或者您可以定义可以显示的实际视图,即 showMenuView
、showTutorialView
等,具体取决于您希望给予您多少控制权子视图。
下面是一个演示基本思想的简单示例,它使用 enum
来定义可用视图(因为它比 0
、1
.. . 而且我不需要记住视图的实际名称,IDE 可以为此提供自动更正 ;))
我在创建 PanelHolder
时预先创建并添加了每个视图,我还向每个视图传递了 NavigationController
的一个实例,因此它们可以与之交互
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
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.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class JavaApplication1013 {
public static void main(String[] args) {
new JavaApplication1013();
}
public JavaApplication1013() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new PanelHolder());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public enum View {
MENU,
TUTORIAL,
FREEPLAY;
}
public interface NavigationController {
public void showView(View view);
}
public class PanelHolder extends JPanel implements NavigationController {
private CardLayout cardLayout;
public PanelHolder() {
cardLayout = new CardLayout();
setLayout(cardLayout);
add(new MenuView(this), View.MENU.name());
add(new TutorialView(this), View.TUTORIAL.name());
add(new FreePlayView(this), View.FREEPLAY.name());
}
@Override
public void showView(View view) {
cardLayout.show(this, view.name());
}
}
public abstract class ViewPane extends JPanel {
private NavigationController controller;
public ViewPane(NavigationController controller) {
this.controller = controller;
}
public NavigationController getController() {
return controller;
}
protected void showView(View view) {
controller.showView(view);
}
}
public class MenuView extends ViewPane {
public MenuView(NavigationController controller) {
super(controller);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
JButton tut = new JButton("Tutorial");
JButton freePlay = new JButton("Free Play");
add(tut, gbc);
add(freePlay, gbc);
tut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showView(View.TUTORIAL);
}
});
freePlay.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showView(View.FREEPLAY);
}
});
}
}
public class TutorialView extends ViewPane {
public TutorialView(NavigationController controller) {
super(controller);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JButton menu = new JButton("Menu");
add(new JLabel("Tutorial"), gbc);
add(menu, gbc);
menu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showView(View.MENU);
}
});
}
}
public class FreePlayView extends ViewPane {
public FreePlayView(NavigationController controller) {
super(controller);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JButton menu = new JButton("Menu");
add(new JLabel("Free Play"), gbc);
add(menu, gbc);
menu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showView(View.MENU);
}
});
}
}
}
仔细查看 How to Use CardLayout 了解更多详情
因此,我在我的一个程序中使用了 cardLayout,并且我正在努力做到这一点,以便在您单击按钮时加载下一个面板。我有一个 panelHolder class,其中保存了卡片布局,每次按下面板上的按钮时,它都会调用 panelHolder class 中的一个方法,该方法根据按钮将某个布尔变量设置为 true并调用重绘(显示面板的位置)。出于某种原因,我的按钮不起作用,而且我似乎无法找出原因。有人可以帮助我吗?
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.Arrays;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.*;
public class SheetReader101 extends JFrame {
public SheetReader101(){
super("SheetReader101");
setSize(2000,1000);
setLocation(0,0);
setResizable(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
PanelHolder pg2 = new PanelHolder();
setContentPane(pg2);
setVisible(true);
}
public static void main(String[]args){
SheetReader101 z1 = new SheetReader101();
}
}
class PanelHolder extends JPanel { // HERE
CardLayout clayout = new CardLayout();
PianoGameContent x;
tutorial y;
boolean [] paneldecide;
PanelHolder() {
super();
y = new tutorial();
x = new PianoGameContent();
setLayout(clayout);
this.add("Tutorial", y);
this.add("FreePlay Mode", x);
paneldecide = new boolean[15];
}
public static void main(String[]args){
PanelHolder z1 = new PanelHolder();
z1.run();
}
public void run(){
layoutShower(0);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
}
public void layoutShower (int decide){
{
PianoGameContent y2 = new PianoGameContent();
PanelHolder.this.add("Piano", y2);
System.out.println("intro slide run");
if(decide == 1){
PanelHolder.this.add("Piano", y2);
System.out.println("testing11");
clayout.show(PanelHolder.this,"Piano");
}
}
}
}
我 "suspect" 核心问题与您发布的原始代码有关,您在子视图的 ActionListener
中创建 PanelHolder
的新实例,然后正在尝试切换视图,此新实例与屏幕上的实例无关。
有几种方法可以管理 CardLayout
,我的首选方法是使用某种 "navigation" 控制器来定义导航的工作方式,例如,您可以 "next" 和 "previous" 或 "back",或者您可以定义可以显示的实际视图,即 showMenuView
、showTutorialView
等,具体取决于您希望给予您多少控制权子视图。
下面是一个演示基本思想的简单示例,它使用 enum
来定义可用视图(因为它比 0
、1
.. . 而且我不需要记住视图的实际名称,IDE 可以为此提供自动更正 ;))
我在创建 PanelHolder
时预先创建并添加了每个视图,我还向每个视图传递了 NavigationController
的一个实例,因此它们可以与之交互
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
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.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class JavaApplication1013 {
public static void main(String[] args) {
new JavaApplication1013();
}
public JavaApplication1013() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new PanelHolder());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public enum View {
MENU,
TUTORIAL,
FREEPLAY;
}
public interface NavigationController {
public void showView(View view);
}
public class PanelHolder extends JPanel implements NavigationController {
private CardLayout cardLayout;
public PanelHolder() {
cardLayout = new CardLayout();
setLayout(cardLayout);
add(new MenuView(this), View.MENU.name());
add(new TutorialView(this), View.TUTORIAL.name());
add(new FreePlayView(this), View.FREEPLAY.name());
}
@Override
public void showView(View view) {
cardLayout.show(this, view.name());
}
}
public abstract class ViewPane extends JPanel {
private NavigationController controller;
public ViewPane(NavigationController controller) {
this.controller = controller;
}
public NavigationController getController() {
return controller;
}
protected void showView(View view) {
controller.showView(view);
}
}
public class MenuView extends ViewPane {
public MenuView(NavigationController controller) {
super(controller);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
JButton tut = new JButton("Tutorial");
JButton freePlay = new JButton("Free Play");
add(tut, gbc);
add(freePlay, gbc);
tut.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showView(View.TUTORIAL);
}
});
freePlay.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showView(View.FREEPLAY);
}
});
}
}
public class TutorialView extends ViewPane {
public TutorialView(NavigationController controller) {
super(controller);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JButton menu = new JButton("Menu");
add(new JLabel("Tutorial"), gbc);
add(menu, gbc);
menu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showView(View.MENU);
}
});
}
}
public class FreePlayView extends ViewPane {
public FreePlayView(NavigationController controller) {
super(controller);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JButton menu = new JButton("Menu");
add(new JLabel("Free Play"), gbc);
add(menu, gbc);
menu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showView(View.MENU);
}
});
}
}
}
仔细查看 How to Use CardLayout 了解更多详情