简体   繁体   English

Java中的CardLayout通过其中一个“卡片”中的操作进行更改

[英]CardLayout in Java change by action in one of the 'cards'

I am making a simple game using a JFrame . 我正在使用JFrame制作一个简单的游戏。 I have made a simple "Start" screen which basically consists of a String and a JButton . 我做了一个简单的“开始”屏幕,它基本上由一个String和一个JButton I am picking up the button click with the actionPerformed(ActionEvent e) method. 我正在使用actionPerformed(ActionEvent e)方法单击按钮。 I don't know how to change the cards using a button click. 我不知道如何使用按钮点击更改卡片。 This may seem like a simple problem to solve, but the twist comes with this: My main JFrame, my StartScreen and my JPanel where the game takes place are all in separate files. 这可能看起来像是一个简单的问题需要解决,但这种扭曲伴随着:我的主要JFrame,我的StartScreen和我发生游戏的JPanel都在不同的文件中。 My main file, Virus.java, is where I create the JFrame . 我的主文件Virus.java是我创建JFrame My file VirusGamePanel.java is where the game takes place. 我的文件VirusGamePanel.java是游戏发生的地方。 My file StartScreen.java is the screen with the button. 我的文件StartScreen.java是带按钮的屏幕。 I want to change 'cards' to the game screen when the player clicks the button. 当玩家点击按钮时,我想将“卡片”更改为游戏屏幕。 How can I do this? 我怎样才能做到这一点? My StartScreen.java file: 我的StartScreen.java文件:

package virus;

import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
import javax.swing.JButton;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.CardLayout;




public class StartScreen extends JPanel implements ActionListener{
    private static final long serialVersionUID = 1L;
    JButton start = new JButton("Start");
    public StartScreen(){
        start.addActionListener(this);
        start.setBounds(new Rectangle(400,300,100,30));
        this.add(start);
    }
    public void paint(Graphics g){
        super.paint(g);
        g.setFont(new Font("Impact",Font.BOLD,72));
        g.setColor(Color.MAGENTA);
        g.drawString("Virus",275,300);
    }
    public void actionPerformed(ActionEvent e)
    {
        if(e.getSource()==start)
        {
            //what to do here?
        }
    }
}

My Virus.java file: 我的Virus.java文件:

package virus;

import javax.swing.*;
import java.awt.CardLayout;
import virus.StartScreen;

public class Virus extends JFrame{
    private static final long serialVersionUID =1L;
    JFrame jf = new JFrame("Virus");
    static JPanel thegame = new JPanel(new CardLayout());
    JPanel game = new VirusGamePanel();
    JPanel start = new StartScreen();

    public Virus(){
        jf.setResizable(false);
        jf.setSize(600,600);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(EXIT_ON_CLOSE);
        jf.setVisible(true);
        jf.add(thegame);
        thegame.add(start);
        thegame.add(game);

    }

    public static void main(String[] args) {
        new Virus();

    }

}

You simply have to right this in your actionPerformed(...) method : 你只需要在actionPerformed(...)方法中改为:

public void actionPerformed(ActionEvent e)
{
    if(e.getSource()==start)
    {
        //what to do here?
        CardLayout cardLayout = (CardLayout) Virus.thegame.getLayout();
        cardLayout.next(Virus.thegame);
    }
}

As very much pointed out by @kleopatra (THE EMPRESS) herself, don't override paint() instead do your painting stuff inside paintComponent(Graphics g) method of any JPanel/JComponent . 正如@kleopatra(THE EMPRESS)本人所指出的那样,不要覆盖paint()而是在任何JPanel/JComponent paintComponent(Graphics g)方法中进行绘画。 Moreover, first add the components to your JFrame , once it's size is realized, then only set it to Visible, not before that. 此外,首先将组件添加到JFrame ,一旦它的大小实现,然后只将其设置为Visible,而不是在此之前。 Instead of setting sizes for the JFrame simply override the JPanel 's method getPreferredSize() , make it return some valid Dimension Object. 而不是设置JFrame大小只是覆盖JPanel的方法getPreferredSize() ,使它返回一些有效的Dimension Object。

Do watch this sequence, as you write your code the next time : 在下次编写代码时,请观察此序列:

public Virus(){
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setResizable(false);                               
    thegame.add(start);
    thegame.add(game);
    jf.add(thegame);        
    jf.pack();
    jf.setLocationRelativeTo(null);
    jf.setVisible(true);
}

Here is your full code : 这是您的完整代码:

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.CardLayout;

public class Virus extends JFrame{
    private static final long serialVersionUID =1L;
    JFrame jf = new JFrame("Virus");
    static JPanel thegame = new JPanel(new CardLayout());
    JPanel game = new VirusGamePanel();
    JPanel start = new StartScreen();

    public Virus(){
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setResizable(false);                               
        thegame.add(start);
        thegame.add(game);
        jf.add(thegame);        
        jf.pack();
        jf.setLocationRelativeTo(null);
        jf.setVisible(true);
    }

    public static void main(String[] args) {
        new Virus();

    }

}

class StartScreen extends JPanel implements ActionListener{
    private static final long serialVersionUID = 1L;
    JButton start = new JButton("Start");
    public StartScreen(){
        start.addActionListener(this);
        start.setBounds(new Rectangle(400,300,100,30));
        this.add(start);
    }

    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        g.setFont(new Font("Impact",Font.BOLD,72));
        g.setColor(Color.MAGENTA);
        g.drawString("Virus",275,300);
    }

    @Override
    public Dimension getPreferredSize()
    {
        return (new Dimension(600, 600));
    }

    public void actionPerformed(ActionEvent e)
    {
        if(e.getSource()==start)
        {
            //what to do here?
            CardLayout cardLayout = (CardLayout) Virus.thegame.getLayout();
            cardLayout.next(Virus.thegame);
        }
    }
}

class VirusGamePanel extends JPanel
{
    public VirusGamePanel()
    {
        JLabel label = new JLabel("I am ON", JLabel.CENTER);
        add(label);
    }

    @Override
    public Dimension getPreferredSize()
    {
        return (new Dimension(600, 600));
    }
}

Your StartScreen class has to have access to the instance of the CardLayout of the JFrame and the instance of the VirusGamePanel class. 您的StartScreen类必须能够访问JFrameCardLayout实例和VirusGamePanel类的实例。 You can pass these instances in the constructor or a setLayout method and setVirusGamePanel method of your StartScreen class. 您可以在构造函数中传递这些实例,也可以在StartScreen类的setLayout方法和setVirusGamePanel方法中传递这些实例。

Something like: 就像是:

layout.next(virusGamePanel);

should work. 应该管用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM