【问题标题】:Button in CardLayout not workingCardLayout 中的按钮不起作用
【发布时间】:2016-05-01 20:07:22
【问题描述】:

所以我在我的一个程序中使用了 cardLayout,并且我正在努力做到这一点,以便在您单击按钮时加载下一个面板。我有一个 panelHolder 类,其中保存了卡片布局,每次按下面板上的按钮时,它都会调用 panelHolder 类中的一个方法,该方法根据按钮将某个布尔变量设置为 true 并调用 repaint(面板所在的位置如图所示)。出于某种原因,我的按钮不起作用,我似乎无法找出原因。有人可以帮我吗?

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");
            }
            }
        }
    }

【问题讨论】:

  • 不要以这种方式使用paintComponent,这不是绘画应该如何完成的,也不是CardLayout的工作方式。相反,将所有组件添加到面板中,并在需要时调用 CardLayout#show
  • 按钮对 actionperformed 方法有反应吗?或者是没有为按钮声明的操作
  • 在您的教程课程中,您正在创建一个新的 PanelHolder 实例,它与屏幕上的实例无关。一般来说,我更喜欢有一个导航控制器,我可以将它传递给我的子视图,当他们想要更改时,它可以告诉它,然后由控制器决定如何进行更改
  • @MadProgrammer 这就是我最初所拥有的,但它不起作用,所以我尝试在paintcomponent中使用它。我编辑了这篇文章,并把我之前的版本放在了这里。
  • @DarkV1 该按钮确实会做出反应,我在与应该显示面板并运行的那个 if 语句相同的 if 语句中放置了一个 s,o.pln 行。只是面板没有显示是我的问题。

标签: java swing cardlayout


【解决方案1】:

我“怀疑”核心问题与您发布的原始代码有关,您在子视图的 ActionListener 中创建了 PanelHolder 的新实例,然后尝试切换视图,这个新的实例与屏幕上的实例没有关系。

有几种方法可以管理CardLayout,我首选的方法是使用某种“导航”控制器来定义导航的工作方式,例如,您可以使用“下一个”和“上一个”或“后退” ",或者您可以定义可以显示的实际视图,即showMenuViewshowTutorialView 等,具体取决于您希望为子视图提供多少控制权。

下面是一个简单的例子,它展示了基本思想,它使用enum 来定义可用的视图(因为它比01 更有意义...而且我不需要记住视图的实际名称,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了解更多详情

【讨论】:

    猜你喜欢
    • 2014-04-17
    • 2016-03-20
    • 1970-01-01
    • 2011-12-02
    相关资源
    最近更新 更多