gpt4 book ai didi

java - 无法在 JPanel 上移动 JLabel

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

好的,所以我正在制作一个垄断游戏。到目前为止,我有一个 JFrame,其中有一个 JPanel 作为板。我已经加载了所有必要的图像。我创建了一个扩展 JLabelPlayer 对象,以代表棋盘上的玩家。

我正在尝试设置(希望在棋盘上移动棋子)Player 对象(这是一个 JLabel)在棋盘上(这是JPanel)。我尝试了 .setLocation 方法、.setBounds 方法。

出于某种原因,无论我做什么,Player 对象都只显示在 JPanel 的顶部中间。我想知道如何移动板上的 Player 对象。

JFrame 代码(我尝试移动构造函数底部的 JLabel):

   package com.Game.Monopoly;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.Timer;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;

import net.miginfocom.swing.MigLayout;

//a class that represent the board (JFrame) and all of it components
public class GameFrame extends JFrame {
private final double SCALE;
// all the graphical components
private Board board;
private JLabel lblPlayerMoney;
private JLabel lblCurrentPlayer;
private JLabel lblDice1;
private JLabel lblDice2;
private JList lstPropertiesList;
private JButton btnEndTurn;
private JButton btnBuyProperty;
private JButton btnRollDice;

// all images needed
private ImageIcon imgDice1;
private ImageIcon imgDice2;
private ImageIcon imgDice3;
private ImageIcon imgDice4;
private ImageIcon imgDice5;
private ImageIcon imgDice6;
private ImageIcon icnAirplane;

// all players
private Player[] playerList;
// all properties
private Property[] propertiesList;

public GameFrame(double scale) {
// SCALE = scale;
SCALE = 1;

// set up the JFrame
setResizable(true);
setTitle("Monopoly");
// etUndecorated(true);
// set size to a scale of 1080p
setSize((int) (1920 * SCALE), (int) (1080 * SCALE));
setLayout(new MigLayout());
loadImages();

// add the components to the frame
board = new Board(SCALE);
board.setPreferredSize(new Dimension((int) (1024 * SCALE),
(int) (1024 * SCALE)));
board.setBackground(Color.BLACK);
add(board, "east, gapbefore 80");
lblCurrentPlayer = new JLabel("Current Player:" + " Player 1");
add(lblCurrentPlayer, "wrap");
lblPlayerMoney = new JLabel("Player1's money:" + "$14000000");
add(lblPlayerMoney, "wrap");
lstPropertiesList = new JList();
add(new JScrollPane(lstPropertiesList),
"span 2 2, grow, height 70:120:200");
btnRollDice = new JButton("Roll Dice");
add(btnRollDice, "wrap");
lblDice1 = new JLabel(imgDice1);
add(lblDice1);
lblDice2 = new JLabel(imgDice1);
add(lblDice2, "wrap");
btnBuyProperty = new JButton("Buy Property");
add(btnBuyProperty, "wrap, top");
btnEndTurn = new JButton("End Turn");
add(btnEndTurn, "aligny bottom");

setUpEventListeners();
loadProperties();

// load players
playerList = new Player[6];
playerList[0] = new Player("Player 1", icnAirplane);

// add Players to the board

board.add(playerList[0]);
playerList[0].setLocation(new Point(500, 230));
}

public static void main(String[] args) {
GameFrame board = new GameFrame(1);
board.setVisible(true);

}

// method to add event listeners
public void setUpEventListeners() {

// roll dice
btnRollDice.addActionListener(new ActionListener() {
// creates an object with an timers to help with rolling dice
class RollDice implements ActionListener {
private Timer time = new Timer(152, this);
private int count = 0;

public void actionPerformed(ActionEvent e) {
count++;
if (count == 21)
time.stop();

int whatDice1 = (int) (Math.random() * 6) + 1;
int whatDice2 = (int) (Math.random() * 6) + 1;

// set the icons of the labels according to the random
// number

if (whatDice1 == 1)
lblDice1.setIcon(imgDice1);
else if (whatDice1 == 2)
lblDice1.setIcon(imgDice2);
else if (whatDice1 == 3)
lblDice1.setIcon(imgDice3);
else if (whatDice1 == 4)
lblDice1.setIcon(imgDice4);
else if (whatDice1 == 5)
lblDice1.setIcon(imgDice5);
else if (whatDice1 == 6)
lblDice1.setIcon(imgDice6);

if (whatDice2 == 1)
lblDice2.setIcon(imgDice1);
else if (whatDice2 == 2)
lblDice2.setIcon(imgDice2);
else if (whatDice2 == 3)
lblDice2.setIcon(imgDice3);
else if (whatDice2 == 4)
lblDice2.setIcon(imgDice4);
else if (whatDice2 == 5)
lblDice2.setIcon(imgDice5);
else if (whatDice2 == 6)
lblDice2.setIcon(imgDice6);
}

public void roll() {
count = 0;
time.start();
}
}

// create a new dice roll object
RollDice roll = new RollDice();

// if the roll dice button is clicked
public void actionPerformed(ActionEvent arg0) {
roll.roll();
}

});

}

// load all images to memory
public void loadImages() {
BufferedImage i = null;
try {
i = ImageIO.read((getClass().getResource("/resources/Dice 1.png")));
imgDice1 = new ImageIcon(i.getScaledInstance(100, 100,
java.awt.Image.SCALE_SMOOTH));

i = ImageIO.read((getClass().getResource("/resources/Dice 2.png")));
imgDice2 = new ImageIcon(i.getScaledInstance(100, 100,
java.awt.Image.SCALE_SMOOTH));

i = ImageIO.read((getClass().getResource("/resources/Dice 3.png")));
imgDice3 = new ImageIcon(i.getScaledInstance(100, 100,
java.awt.Image.SCALE_SMOOTH));

i = ImageIO.read((getClass().getResource("/resources/Dice 4.png")));
imgDice4 = new ImageIcon(i.getScaledInstance(100, 100,
java.awt.Image.SCALE_SMOOTH));

i = ImageIO.read((getClass().getResource("/resources/Dice 5.png")));
imgDice5 = new ImageIcon(i.getScaledInstance(100, 100,
java.awt.Image.SCALE_SMOOTH));

i = ImageIO.read((getClass().getResource("/resources/Dice 6.png")));
imgDice6 = new ImageIcon(i.getScaledInstance(100, 100,
java.awt.Image.SCALE_SMOOTH));

i = ImageIO.read((getClass()
.getResource("/resources/Airplane Icon.png")));
icnAirplane = new ImageIcon(i.getScaledInstance(40, 40,
java.awt.Image.SCALE_SMOOTH));

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

// load all properties
public void loadProperties() {
propertiesList = new Property[40];

// set up the properties list
// (name, index, isBuyable, price, initial rent)
propertiesList[0] = new Property("Go", 0, false, 0, 0);
propertiesList[1] = new Property("Jacob's Field", 1, true, 600000,
20000);
propertiesList[2] = new Property("Community Chest", 2, false, 0, 0);
propertiesList[3] = new Property("Texas Stadium", 3, true, 600000,
40000);
propertiesList[4] = new Property("Income Tax", 4, false, 0, 0);
propertiesList[5] = new Property("O'Hare International Airport", 5,
true, 2000000, 250000);
propertiesList[6] = new Property("Grand Ole Opry", 6, true, 1000000,
60000);
propertiesList[7] = new Property("Chance", 7, false, 0, 0);

}
}

JPanel 代码:

package com.Game.Monopoly;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class Board extends JPanel {
private static final long serialVersionUID = 1L;
private Image board;

public Board(double scale) {
this.setPreferredSize(new Dimension((int) (1024 * scale),
(int) (1024 * scale)));

BufferedImage i = null;
try {
i = ImageIO.read((getClass().getResource("/resources/monopoly-board-web.jpg")));

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
board = i.getScaledInstance((int) (1024 * scale), (int) (1024 * scale), java.awt.Image.SCALE_SMOOTH);

}

public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(board, 0, 0, this);
}

}

玩家对象代码:

package com.Game.Monopoly;

import javax.swing.ImageIcon;
import javax.swing.JLabel;

//a class representing a player with its graphical component
public class Player extends JLabel {

private String playerName;
private int money;
private Property[] propertiesOwned;

public Player(String n, ImageIcon icon) {
playerName = n;
this.setIcon(icon);
}

// changes the amount of money available
public void changeMoney(int amount) {
money = money + amount;
}

public void movePlayer(int x, int y){
this.setLocation(x, y);
}

}

最佳答案

有几种方法可以实现这一点,就个人而言,最简单的方法是直接使用自定义绘画,而不必为播放器使用基于 Swing 的组件。

您遇到的基本问题是 JPanel 默认情况下使用 FlowLayout,这意味着您将始终与布局管理器作斗争。在这种情况下,您可能会考虑使用自定义布局管理器,例如...

Monopoly

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager2;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Monopoly {

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

public Monopoly() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MonopolyBoard());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class MonopolyBoard extends JPanel {

private List<JLabel> players;

public MonopolyBoard() {
setLayout(new MonopolyBoardLayout());

players = new ArrayList<>(2);
try {
players.add(makePlayer("/Dog.png"));
players.add(makePlayer("/Car.png"));

for (JLabel player : players) {
add(player, new Integer(0));
}
} catch (IOException exp) {
exp.printStackTrace();
}

Timer timer = new Timer(1000, new ActionListener() {
private int count = 0;
private Random rnd = new Random();

@Override
public void actionPerformed(ActionEvent e) {
int playerIndex = count % players.size();
JLabel player = players.get(playerIndex);

MonopolyBoardLayout layout = (MonopolyBoardLayout) getLayout();
int position = layout.getPosition(player);

position += rnd.nextInt(5) + 1;
if (position > 35) {
position -= 35;
}

layout.setPosition(player, position);

revalidate();
repaint();
count++;
}
});
timer.start();
}

protected JLabel makePlayer(String path) throws IOException {
JLabel label = new JLabel(new ImageIcon(ImageIO.read(getClass().getResource(path))), JLabel.CENTER);
return label;
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth();
int height = getHeight();

for (int index = 0; index < 36; index++) {
Rectangle bounds = MonopolyBoardLayoutHelper.getCellBounds(index, width, height);
g2d.draw(bounds);
}

g2d.dispose();
}

}

public static class MonopolyBoardLayoutHelper {

private static Map<Integer, Point> mapBoardCells;

static {
mapBoardCells = new HashMap<>(25);

mapBoardCells.put(10, new Point(0, 8));
mapBoardCells.put(11, new Point(0, 7));
mapBoardCells.put(12, new Point(0, 6));
mapBoardCells.put(13, new Point(0, 5));
mapBoardCells.put(14, new Point(0, 4));
mapBoardCells.put(15, new Point(0, 3));
mapBoardCells.put(16, new Point(0, 2));
mapBoardCells.put(17, new Point(0, 1));
mapBoardCells.put(18, new Point(0, 0));

mapBoardCells.put(0, new Point(9, 9));
mapBoardCells.put(1, new Point(8, 9));
mapBoardCells.put(2, new Point(7, 9));
mapBoardCells.put(3, new Point(6, 9));
mapBoardCells.put(4, new Point(5, 9));
mapBoardCells.put(5, new Point(4, 9));
mapBoardCells.put(6, new Point(3, 9));
mapBoardCells.put(7, new Point(2, 9));
mapBoardCells.put(8, new Point(1, 9));
mapBoardCells.put(9, new Point(0, 9));

mapBoardCells.put(19, new Point(1, 0));
mapBoardCells.put(20, new Point(2, 0));
mapBoardCells.put(21, new Point(3, 0));
mapBoardCells.put(22, new Point(4, 0));
mapBoardCells.put(23, new Point(5, 0));
mapBoardCells.put(24, new Point(6, 0));
mapBoardCells.put(25, new Point(7, 0));
mapBoardCells.put(26, new Point(8, 0));
mapBoardCells.put(27, new Point(9, 0));

mapBoardCells.put(28, new Point(9, 1));
mapBoardCells.put(29, new Point(9, 2));
mapBoardCells.put(30, new Point(9, 3));
mapBoardCells.put(31, new Point(9, 4));
mapBoardCells.put(32, new Point(9, 5));
mapBoardCells.put(33, new Point(9, 6));
mapBoardCells.put(34, new Point(9, 7));
mapBoardCells.put(35, new Point(9, 8));

}

public static Rectangle getCellBounds(int index, int width, int height) {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
int size = Math.min(width, height);
int cellSize = size / 10;

int xOffset = (width - size) / 2;
int yOffset = (height - size) / 2;

Point point = mapBoardCells.get(index);
if (point != null) {

int x = xOffset + (point.x * cellSize);
int y = yOffset + (point.y * cellSize);
bounds = new Rectangle(x, y, cellSize, cellSize);

}

return bounds;

}

}

public static class MonopolyBoardLayout implements LayoutManager2 {

public static final int DEFAULT_CELL_SIZE = 64;

private Map<Component, Integer> cellConstraints;

public MonopolyBoardLayout() {
cellConstraints = new HashMap<>(5);
}

public Integer getPosition(Component comp) {
return cellConstraints.get(comp);
}

public void setPosition(Component comp, int position) {
cellConstraints.put(comp, position);
}

@Override
public void addLayoutComponent(Component comp, Object constraints) {
if (constraints instanceof Integer) {
int cell = (int) constraints;
if (cell >= 0 && cell <= 35) {
cellConstraints.put(comp, cell);
} else {
throw new IllegalArgumentException(constraints + " is not within the bounds of a valid cell reference (0-35)");
}
} else {
throw new IllegalArgumentException(constraints + " is not a valid cell reference (integer within 0-35)");
}
}

@Override
public Dimension maximumLayoutSize(Container target) {
return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10);
}

@Override
public float getLayoutAlignmentX(Container target) {
return 0.5f;
}

@Override
public float getLayoutAlignmentY(Container target) {
return 0.5f;
}

@Override
public void invalidateLayout(Container target) {
}

@Override
public void addLayoutComponent(String name, Component comp) {
}

@Override
public void removeLayoutComponent(Component comp) {
cellConstraints.remove(comp);
}

@Override
public Dimension preferredLayoutSize(Container parent) {
return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10);
}

@Override
public Dimension minimumLayoutSize(Container parent) {
return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10);
}

@Override
public void layoutContainer(Container parent) {
int width = parent.getWidth();
int height = parent.getHeight();

Map<Integer, List<Component>> components = new HashMap<>(25);

for (Component child : parent.getComponents()) {
Integer cell = cellConstraints.get(child);
if (cell != null) {
List<Component> children = components.get(cell);
if (children == null) {
children = new ArrayList<>(4);
components.put(cell, children);
}
children.add(child);
} else {
child.setBounds(0, 0, 0, 0);
}
}

for (Map.Entry<Integer, List<Component>> entry : components.entrySet()) {
int index = entry.getKey();
Rectangle bounds = MonopolyBoardLayoutHelper.getCellBounds(index, width, height);
List<Component> comp = entry.getValue();
int xDelta = 0;
int yDelta = 0;
int availableWidth = bounds.width;
int availableHeight = bounds.height;
switch (comp.size()) {
case 2:
availableWidth /= 2;
xDelta = availableWidth;
break;
case 3:
case 4:
availableWidth /= 2;
xDelta = availableWidth;
availableHeight /= 2;
yDelta = availableHeight;
break;
}
int x = bounds.x;
int y = bounds.y;
for (int count = 0; count < comp.size() && count < 4; count++) {
Component child = comp.get(count);
child.setSize(availableWidth, availableHeight);
child.setLocation(x, y);

x += xDelta;
if (x >= bounds.x + bounds.width) {
x = bounds.x;
y += yDelta;
}
}
}

}

}

}

正如您所看到的,这很快就会变得非常复杂。此示例目前每个单元格仅允许 4 名玩家,因此如果您想要更多玩家,则必须创建自己的算法

关于java - 无法在 JPanel 上移动 JLabel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33883330/

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