gpt4 book ai didi

JAVA - 无法在 JPanel 上绘制组件(也是 Runnable 和 KeyListener)

转载 作者:行者123 更新时间:2023-12-01 12:20:25 25 4
gpt4 key购买 nike

这些是我正在使用 Java 和图形制作一个简单游戏的类

主要:

import javax.swing.*;
import java.awt.*;

public class FrameTest extends JFrame {

public FrameTest() {
setSize(800,600);
setVisible(true);
}

public static void main(String[] args) {
FrameTest frame = new FrameTest();
GamePanel panel = new GamePanel();
frame.add(panel);
}
}

面板测试:

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

public class PanelTest extends JPanel {

private PlayerTest playerRunnable;
private Thread playerThread;

public PanelTest() {
setSize(800,600);

playerRunnable = new PlayerTest();
playerThread = new Thread(playerRunnable);

//New
setLayout(new BorderLayout());
add(playerRunnable, BorderLayout.NORTH);
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.red);
}


}

它只是创建一个具有红色背景的面板(我这样做是为了看看 PaintComponent() 是否可以正常工作,而且它确实有效)。

玩家测试:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.*;
import javax.swing.JComponent;

public class PlayerTest extends JComponent implements Runnable, KeyListener {

public int x;
public int y;
private int speed;

public PlayerTest() {
speed = 10;
x = 800/2;
y = 600/4;

addKeyListener(this);
setFocusable(true);
}

public void run() {
while(true) {}
}

//New
public Dimension getPreferredSize() {
return new Dimension(30,30);
}

public void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
g.fillRect(x, y, 30, 30);
}

public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}

public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_LEFT) {
//Spostamento a sinistra player
move(speed*-1);
}

if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
//Spostamento a destra player
move(speed);
}

if(e.getKeyCode() == KeyEvent.VK_SPACE) {
//Lancio bomba
}
}

public void move(int s) {
if (s < 0) {
if(x-s > 0) {
x += s;
System.out.println("[PLAY] move left, x: " + x);
repaint();
}
} else {
if(x+s < 800) {
x += s;
System.out.println("[PLAY] move right, x: " + x);
repaint();
}
}
}
}

问题来了。这个类是一个 Runnable(用于动画)、一个 KeyListener(用于玩家移动)和一个 JComponent(用于显示玩家的图像,现在我们假设它是一个矩形)我已在 Panel 类上添加了此组件,但如果我尝试绘制它,它不会显示。我不明白为什么。我已经在这个问题上坚持了很长时间,我终于决定在这里问一个问题。

最佳答案

我发现您的代码有几个问题,但最直接的问题是您的 PlayerTest 组件没有设置首选大小,因此它的大小为 [1, 1],因此根本不会被看到。为其容器 PanelTest 提供一个 BorderLayout,以便 PlayerTest 组件填充其容器。

其他问题:

  • 不要设置组件的大小。如果必须的话,请重写getPreferredSize(),并让它返回最适合您的 GUI 的尺寸。这将更好地与您的布局管理器配合使用。
  • 请务必使用布局管理器,例如上面提到的 BorderLayout,以便 GUI 在需要时展开并放置在需要的位置。
  • 考虑使用 Swing 计时器,而不是使用线程和空的 run() 方法,因为它更容易使用并保证您的代码是 Swing 线程安全的。
  • 避免使用 KeyListener,而是使用键绑定(bind),因为在解决组件焦点问题时它们更容易使用。

例如:How to make an image move while listening to a keypress in Java.

<小时/>

在你的 JPanel 周围放置一个边框,你会发现它的大小 = GUI 的宽度,但只有 30 点高,因为你将其首选大小限制为 30 x 30,但试图在其中绘制一些东西远远超出此范围,因此绘图组件不足以显示您的绘图。我会以不同的方式构造事物,让 Player 类从 Swing 组件扩展,而是使其成为一个逻辑类,一个知道如何绘制自身的类。我会将主 JPanel 设为绘图 JPanel,并为其提供一个要移动和显示的 Player 对象。

例如,此代码显示并移动一个正方形,但仅在按下右箭头时向右移动:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class MyAnimationTest extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 600;
private static final Color BG = Color.RED;
private static final int TIMER_DELAY = 15;
public static final int X_STEP = 5;
private MyPlayer player = new MyPlayer(PREF_W / 2, PREF_H / 4);
private boolean right = false;
private Timer timer = new Timer(TIMER_DELAY, new TimerListener());

public MyAnimationTest() {
setBackground(BG);
setUpKeyBindings();
timer.start();
}

private void setUpKeyBindings() {
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inMap = getInputMap(condition);
ActionMap actMap = getActionMap();

KeyStroke rightArrowDownStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false);
KeyStroke rightArrowUpStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true);

inMap.put(rightArrowDownStroke, rightArrowDownStroke.toString());
inMap.put(rightArrowUpStroke, rightArrowUpStroke.toString());

actMap.put(rightArrowDownStroke.toString(), new RightMoveAction(true));
actMap.put(rightArrowUpStroke.toString(), new RightMoveAction(false));
}

@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
player.draw(g);
}

private class RightMoveAction extends AbstractAction {
private boolean move;

public RightMoveAction(boolean move) {
this.move = move;
}

@Override
public void actionPerformed(ActionEvent e) {
right = move;
}
}

private class TimerListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (right) {
int newX = player.getX() + X_STEP;
player.setX(newX);
repaint();
}
}
}

private static void createAndShowGui() {
MyAnimationTest mainPanel = new MyAnimationTest();

JFrame frame = new JFrame("My Animation");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

/**
* A logical class that does not extend a Swing component
*
* @author Pete
*
*/
class MyPlayer {
public static final Color COLOR = Color.blue;
public static final int WIDTH = 30;
private BufferedImage sprite = new BufferedImage(WIDTH, WIDTH, BufferedImage.TYPE_INT_ARGB);
private int x;
private int y;

public MyPlayer(int x, int y) {
this.x = x;
this.y = y;

Graphics g = sprite.getGraphics();
g.setColor(COLOR);
g.fillRect(0, 0, WIDTH, WIDTH);
g.dispose();
}

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

public int getY() {
return y;
}

public void setY(int y) {
this.y = y;
}

public void draw(Graphics g) {
g.drawImage(sprite, x, y, null);
}
}

关于JAVA - 无法在 JPanel 上绘制组件(也是 Runnable 和 KeyListener),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26701922/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com