【问题标题】:Using JButton in one class to change card in another class (using CardLayout)在一个类中使用 JButton 更改另一个类中的卡片(使用 CardLayout)
【发布时间】:2017-11-29 23:51:14
【问题描述】:

我构建了一个 GUI,其中我使用不同的类扩展面板将多个 JPanel 组件相互嵌套。在我的Menue 中,我有一个CenterPanel 和一个ButtonPanel。 ButtonPanel 包含实现ActionListener 接口的按钮。 CenterPanel 使用 CardLayout,我想使用上述按钮更改 CenterPanel 中的卡片。问题是,按钮对CenterPanel 或该面板中的卡片一无所知。

我想避免将所有内容都放在一个类中,但我不知道如何解决这个问题而不只是将所有内容都写在一个类中?

这是我的一些代码:

MenuePanel

public class MenuePanel extends JPanel{

JButton startButton;
JButton exitButton;
JButton anleitungButton;
ButtonPanel buttonPanel;
TitlePanel titlePanel;
JPanel centerPanel;
CardLayout cardLayout;
TextPanel anleitungPanel;
TextPanel gameOverPanel;
TextPanel gameWonPanel;
TextPanel nextLevelPanel;
StartPanel startPanel;

public MenuePanel() {
    super();
    cardLayout = new CardLayout();
    setBackground(Color.CYAN);
    setBounds(0,0,800,600);
    setLayout(new BorderLayout());

    titlePanel = new TitlePanel();
    add(titlePanel, BorderLayout.PAGE_START);

    startPanel = new StartPanel();
    gameOverPanel = new TextPanel("Game Over!");
    gameWonPanel = new TextPanel("Game Won!");
    anleitungPanel = new TextPanel();
    nextLevelPanel = new TextPanel("Next Level!");
    centerPanel = new JPanel();

    centerPanel.setLayout(cardLayout);
    add(centerPanel, BorderLayout.CENTER);
    centerPanel.add(startPanel, "1");
    centerPanel.add(gameOverPanel, "2");
    centerPanel.add(gameWonPanel, "3");
    centerPanel.add(anleitungPanel, "4");
    centerPanel.add(nextLevelPanel, "5");
    cardLayout.show(centerPanel, "2");

    buttonPanel = new ButtonPanel();
    add(buttonPanel, BorderLayout.PAGE_END);
    setVisible(true);
}

ButtonPanel

public class ButtonPanel extends JPanel{

JButton startButton;
JButton exitButton;
JButton anleitungButton;

public ButtonPanel() {
    super();
    setLayout(new FlowLayout());
    setPreferredSize(new Dimension(800, 100));
    setBackground(Color.CYAN);

    startButton = new JButton("start)");
    startButton.setPreferredSize(new Dimension(150,50));
    add(startButton);
    anleitungButton = new JButton("anleitung");
    anleitungButton.setPreferredSize(new Dimension(150,50));
    add(anleitungButton);
    exitButton = new JButton("exit");
    exitButton.setPreferredSize(new Dimension(150,50));
    add(exitButton);

    CloseListener closeListener = new CloseListener();
    StartListener startListener = new StartListener();
    AnleitungListener anleitungListener = new AnleitungListener();
    startButton.addActionListener(startListener);
    anleitungButton.addActionListener(anleitungListener);
    exitButton.addActionListener(closeListener);

}

TextPanel

public class TextPanel extends JPanel{
JLabel text;

public TextPanel(String panel) {
    super();
    text = new JLabel(panel, SwingConstants.CENTER);
    setPreferredSize(new Dimension(800, 400));
    text.setFont(new Font("Arial", Font.ITALIC, 75));
    add(text);
}

AnleitungListener

public class AnleitungListener implements ActionListener{

@Override
public void actionPerformed(ActionEvent e) {

}

我是不是做错了整件事,需要改变整个架构?如果,如何?大多数关于如何使用 ActionListeners 的示例要么只是写在一个类中,要么以复杂的方式让我理解。

【问题讨论】:

  • "使用不同的类扩展 JPanels" 不要无故扩展类。
  • @AndrewThompson 感谢编辑,下次我会做得更好。而且我认为传播代码而不是将其放入一个大类中是个好主意。这就是为什么我制作了几个作为特殊面板的类。我不知道这是好的做法还是坏的做法或任何做法,因为这是我的第一个项目......
  • “而且我认为传播代码而不只是将其放在一个大类中是一个好主意。” 当然,但没有必要扩展面板,只是让它来自一个单独的班级。例如,单独的类可能有一个创建标准面板(向其中添加组件并以其他方式配置它)然后返回它的方法。

标签: java swing architecture actionlistener


【解决方案1】:

您可以在两者之间创建一个类来协调整个切换,以防止在类之间共享大量实例。我已经创建了一个使用 CardSwitcher 的示例,它正是这样做的。

如果你觉得它有用,请告诉我。

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Test extends JPanel {

    public static void main(String[] args) {
        JFrame frame = new JFrame("Test");

        Test tst = new Test();
        frame.getContentPane().add(tst);

        frame.setSize(600, 600);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }

    public Test() {
        setLayout(new BorderLayout());
        CardLayout cardLayout = new CardLayout();

        JPanel centerPanel = new JPanel(cardLayout);

        JPanel panelA = new JPanel();
        panelA.add(new JLabel("Panel A"));
        centerPanel.add(panelA, "A");
        JPanel panelB = new JPanel();
        panelB.add(new JLabel("Panel B"));
        centerPanel.add(panelB, "B");
        JPanel panelC = new JPanel();
        panelC.add(new JLabel("Panel C"));
        centerPanel.add(panelC, "C");

        CardSwitcher switcher = new CardSwitcher(centerPanel, cardLayout);
        ButtonPanel buttons = new ButtonPanel(switcher);

        add(centerPanel, BorderLayout.CENTER);
        add(buttons, BorderLayout.SOUTH);


    }

    class ButtonPanel extends JPanel {
        public ButtonPanel(CardSwitcher switcher) {
            setLayout(new FlowLayout());

            JButton buttonA = new JButton("Show A");
            buttonA.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    switcher.switchTo("A");
                }
            });
            add(buttonA);

            JButton buttonB = new JButton("Show B");
            buttonB.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    switcher.switchTo("B");
                }
            });
            add(buttonB);

            JButton buttonC = new JButton("Show C");
            buttonC.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    switcher.switchTo("C");
                }
            });
            add(buttonC);

        }
    }


    class CardSwitcher {
        CardLayout layout;
        Container container;

        public CardSwitcher(Container container, CardLayout layout) {
            this.layout = layout;
            this.container = container;
        }

        public void switchTo(String card) {
            layout.show(container, card);
        }
    }
}

【讨论】:

  • 谢谢,需要一些时间来弄清楚它是如何以及为什么起作用的。试过了,它有效。现在我仍然有两个嵌套的 CardLayouts 并且按钮位于内部的问题。我想我必须通过外部容器,这样我才能更改外部卡片,如果我想更改内部卡片,请遍历外部容器的内容,直到找到我想要更改的面板:/
  • 基本上CardSwitcher封装了组件和切换的“复杂性”。它可以防止您传递对其他组件的大量引用。您可以创建它的两个实例,或者调整该类以容纳两个 CardLayouts。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-02
  • 2017-08-16
  • 1970-01-01
  • 2014-10-06
相关资源
最近更新 更多