如何从多个外部类中使用JPanel? [英] How do I draw on a JPanel from multiple outside classes?
问题描述
我目前正在制作一个带有主菜单和您实际玩过的世界的游戏.
I am currently making a game with a main menu and a world where you actually play.
我有一个名为Game
的类,该类继承自JPanel并实现了Runnable
,MouseListener
,KeyListener
和ActionListener
接口
(仅包括重要部分)
I have a class called Game
, which inherits from JPanel and implements the Runnable
, MouseListener
, KeyListener
and ActionListener
interfaces
(only important parts included)
我还有两个类InWorldHandler
和OutWorldHandler
,分别用于处理世界范围内和外部的机制.
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?
推荐答案
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屋!