如何从多个外部类中使用JPanel? [英] How do I draw on a JPanel from multiple outside classes?

查看:124
本文介绍了如何从多个外部类中使用JPanel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在制作一个带有主菜单和您实际玩过的世界的游戏.

I am currently making a game with a main menu and a world where you actually play.

我有一个名为Game的类,该类继承自JPanel并实现了RunnableMouseListenerKeyListenerActionListener接口 (仅包括重要部分)

I have a class called Game, which inherits from JPanel and implements the Runnable, MouseListener, KeyListener and ActionListener interfaces (only important parts included)

我还有两个类InWorldHandlerOutWorldHandler,分别用于处理世界范围内和外部的机制.

I also have two classes InWorldHandler and OutWorldHandler for handling the mechanics in the world and outside of it respectively.

Game类:

public class Game extends JPanel implements Runnable, KeyListener, MouseListener, ActionListener
{
    protected JFrame frame;
    private Timer timer = new Timer(25, this);

    private World world;
    private Player player = new Player();

    private boolean draw;

    Game(World world)
    {
        frame = new JFrame("Minecraft 2D");
        this.world = world;
        player.enterWorld(world, this);
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        Graphics2D g2d = (Graphics2D)g;

        if(draw)
        {
            g2d.setColor(new Color(255, 255, 255));
            g2d.fillRect(0, 0, frame.getWidth(), frame.getHeight());

            draw = false;
            //Here, the in-game mechanics should be handled
            if(player.inWorld())
            {
                Chunk chunk = player.getLoadedChunk();
                for(int x = 0; x < 16; x++)
                {
                    for(int y = 0; y < 16; y++)
                    {
                        Block block = chunk.getBlockAt(x, y);
                        BufferedImage texture = block.getTexture();

                        g2d.drawImage(block.getTexture(), x*32, y*32, texture.getWidth()*2, texture.getHeight()*2, null);
                    }
                }
            }
            //Here, the out-game mechanics should be handled
            else
            {

            }
        }
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        this.repaint();
        draw = true;
    }

    @Override
    public void run()
    {
        draw = true;

        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(this);
        frame.setMinimumSize(new Dimension(518, 540));
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.addKeyListener(this);
        frame.addMouseListener(this);
        frame.setFocusable(true);
        frame.setVisible(true);
        frame.pack();
        timer.start();
    }
}

其他两个类当前都具有空主体.我只是不知道该怎么做.

Both the other classes have empty bodies currently. I just have no idea how to do that.

我希望当玩家在游戏中时在面板上绘制InWorldHandler类,而当玩家在主菜单中时希望在面板上绘制OutWorldHandler类,两者均在Game类中调用.我该怎么办?

I want the InWorldHandler class to draw on the panel when the player is in game, and the OutWorldHandler class when the player is in the main menu, both called in the Game class. How do I do that?

推荐答案

为什么不使用单个JPanel,为什么不尝试使用

Instead of having a single JPanel, why don't you try with a CardLayout and switch whether to show the InnerWorld or the OuterWorld according to a flag that determines where in the program you're at.

在实施KeyListener时,我认为这是为了让您能够移动角色,请查看有关此问题的公认答案:

As you're implementing KeyListener, I think that's for you to be able to move your character, please take a look at the accepted answer on this question: Keylistener not working for JPanel and use KeyBindings instead.

还避免使用setMimimum/Maximum/PreferredSize()并改写那些方法:

Also avoid the use of setMimimum/Maximum/PreferredSize() and override those methods instead: Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?

以以下代码为例:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Game {
    private JFrame frame;
    private JButton button;
    private boolean status;
    private JPanel[] cards;
    private CardLayout cl;
    private JPanel gamePane;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Game().createAndShowGUI());
    }

    private void createAndShowGUI() {
        frame = new JFrame(getClass().getSimpleName());
        button = new JButton("Switch Worlds");
        status = true; //True = Inner / False = Outer

        cl = new CardLayout();

        gamePane = new JPanel(cl);
        cards = new JPanel[2];

        cards[0] = new InnerWorld();
        cards[1] = new OuterWorld();

        gamePane.add(cards[0], "innerWorld");
        gamePane.add(cards[1], "outerWorld");

        button.addActionListener(e -> {
            status = !status;
            if (status) {
                cl.show(gamePane, "innerWorld");
            } else {
                cl.show(gamePane, "outerWorld");
            }
        });

        frame.add(gamePane);
        frame.add(button, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

@SuppressWarnings("serial")
class InnerWorld extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;

        g2d.drawString("Inner World", 50, 50);
    }

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

@SuppressWarnings("serial")
class OuterWorld extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D) g;

        g2d.drawString("Outer World", 50, 50);
    }

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

这篇关于如何从多个外部类中使用JPanel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆