Java 如何从卡上的按钮切换卡?
我已经寻找了一段时间的解决方案,尽管有很多类似的问题和答案,但没有发现任何有效的方法。我希望用户能够通过卡布局中设置的各种面板进行操作。但是,我希望用于在这些卡之间切换的按钮位于卡本身,而不是一组单独的按钮,这些按钮在程序中不会改变。以下是创建框架的主文件:Java 如何从卡上的按钮切换卡?,java,jframe,jpanel,Java,Jframe,Jpanel,我已经寻找了一段时间的解决方案,尽管有很多类似的问题和答案,但没有发现任何有效的方法。我希望用户能够通过卡布局中设置的各种面板进行操作。但是,我希望用于在这些卡之间切换的按钮位于卡本身,而不是一组单独的按钮,这些按钮在程序中不会改变。以下是创建框架的主文件: public class BattleGraphs_V1 { JPanel cards; public int cardNumber = 1; public void addComponentToPane (C
public class BattleGraphs_V1
{
JPanel cards;
public int cardNumber = 1;
public void addComponentToPane (Container pane)
{
JPanel MainMenuCard = new MainMenu_V1();
JPanel DifficultySelectorCard = new DifficultySelector_V1();
cards = new JPanel(new CardLayout());
cards.add(MainMenuCard);
cards.add(DifficultySelectorCard);
pane.add(cards, BorderLayout.CENTER);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("BattleGraphs");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
frame.setPreferredSize(new java.awt.Dimension(725, 420));
frame.setResizable(false);
BattleGraphs_V1 containerPanel = new BattleGraphs_V1();
containerPanel.addComponentToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
未来的两个面板将在项目中的两个独立文件中。我没有为它们添加代码,因为除了每个面板上单个按钮的操作侦听器之外,它都是自动生成的代码
编辑:
我在主菜单JPanel的按钮中添加了一个自动生成的动作侦听器,如下所示:
private void MainMenuCardSBActionPerformed(java.awt.event.ActionEvent evt) {
BattleGraphs_V1 BG_V1 = new BattleGraphs_V1();
CardLayout cardLayout = (CardLayout) (BG_V1.cards.getLayout());
cardLayout.show(BG_V1.cards, "DifficultyCard");
}
向主文件中添加的卡添加名称后,主文件如下所示:
cards.add(MainMenuCard, "MainMenuCard");
cards.add(DifficultySelectorCard, "DifficultyCard");
当我运行程序并点击按钮时,得到了一个空指针异常错误,就像我用类似的解决方案所做的那样。如果我认为这更多地是一个范围问题,我会错吗
第二次编辑:
好的,希望这会有所帮助,我已经将enite项目添加到GitHub存储库中-当您将卡添加到面板时,您应该命名它们,以便您可以选择要在特定事件中显示的切换卡
cards = new JPanel(new CardLayout());
cards.add(MainMenuCard, "first");
cards.add(DifficultySelectorCard, "second");
pane.add(cards, BorderLayout.CENTER);
图形用户界面:
编辑
这是一个演示CardLayout的简短示例,因为您没有共享完整的代码
主类
第一小组
第二小组
哪一行给了你NPE?另外,你不应该创建一个新的战斗图,你应该有一个你想要的参考,否则你永远不会初始化BG_V1.cards。这可能就是给你NPE的线路。这里有一个问题,卡/面板有什么责任确定下一个导航点?回答:没有,为什么?因为以这种方式修改导航是一场噩梦。解决方案有一个模型/控制器,可以从面板导航到下一步我认为你不应该在ActionListener中创建一个新的BattleGraphs_V1实例,这是你不应该这样做的另一个原因,小组应该不必做出这些决定,因为它正在对它是如何设置的进行假设。也请查看这篇文章:很难说问题出在哪里,我们无法看到您的完整代码。我在我的帖子中添加了一个示例。我已经链接到gitHub存储库,应该可以让您访问完整代码,而无需将此页面作为无休止的滚动条。此外,当我获取您提供的示例代码并从中创建netbeans项目时,当我尝试运行该项目时,线程AWT-EventQueue-0 java.lang.RuntimeException:不可编译的源代码-错误的树类型:。问题源于第31行-mainPanel.addnew FirstPanel mainPanel,FIRST;和66个新的主菜单_V1.setVisibletrue;
JButton button = new JButton("Click here");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, "second");
}
});
public class MainMenu_V1 extends JFrame {
private JMenuBar menuBar;
private JMenu file;
private JMenuItem exit;
private JPanel mainPanel;
public MainMenu_V1() {
setTitle("Main Panel");
setResizable(false);
setSize(new Dimension(400, 200));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setJMenuBar(createMainMenu());
setLocationRelativeTo(null);
mainPanel = new JPanel();
mainPanel.setLayout(new CardLayout());
mainPanel.add(new FirstPanel(mainPanel), "FIRST");
mainPanel.add(new SecondPanel(mainPanel), "SECOND");
setContentPane(mainPanel);
}
public JMenuBar createMainMenu() {
menuBar = new JMenuBar();
file = new JMenu("File");
exit = new JMenuItem("Exit");
exit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
file.add(exit);
menuBar.add(file);
return menuBar;
}
public void switchPanel(Container container, String panelName) {
CardLayout card = (CardLayout) (container.getLayout());
card.show(container, panelName);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MainMenu_V1().setVisible(true);
}
});
}
}
public class FirstPanel extends JPanel {
private JButton button;
private JPanel mainPanel;
public FirstPanel(JPanel mainPanel) {
this.mainPanel = mainPanel;
setPreferredSize(new Dimension(400, 200));
setBackground(Color.GRAY);
add(createButton());
}
private JButton createButton() {
button = new JButton("Switch to the second Panel");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MainMenu_V1 main = new MainMenu_V1();
main.switchPanel(mainPanel, "SECOND");
}
});
return button;
}
}
public class SecondPanel extends JPanel {
private JButton button;
private JPanel mainPanel;
public SecondPanel(JPanel mainPanel) {
this.mainPanel = mainPanel;
setPreferredSize(new Dimension(400, 200));
setBackground(Color.ORANGE);
add(createButton());
}
private JButton createButton() {
button = new JButton("Switch to the first Panel");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MainMenu_V1 main = new MainMenu_V1();
main.switchPanel(mainPanel, "FIRST");
}
});
return button;
}
}