gpt4 book ai didi

Java GUI 更改 'tile' 的位置

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

我正在使用 GUI 制作 A* 寻路应用程序。我有:

- 枚举 TileType

START(Color.GREEN), 
WALL(Color.BLACK),
BLANK(new Color(240, 240, 240)),
END(Color.RED);

- 网格类

public class Grid extends JPanel {

private final Color lineColour = new Color(200, 200, 200);
private Color defaultColour;
private final int pixelsPerTile;
private final int rows;
private final int columns;
private TileType[][] tiles;

public Grid(int rows, int columns, int pixelsPerTile) {
this.pixelsPerTile = pixelsPerTile;
this.rows = rows;
this.columns = columns;
this.tiles = new TileType[rows][columns];
this.setPreferredSize(new Dimension(rows * pixelsPerTile, columns * pixelsPerTile));
setTile(rows / 2 - 5, columns / 2, TileType.START);
setTile(rows / 2 + 5, columns / 2, TileType.END);
}

public void resetBoard() {
for (int i = 0; i < tiles.length; i++) {
for (int j = 0; j < tiles[0].length; j++) {
if (getTile(i, j) != TileType.START && getTile(i, j) != TileType.END) {
tiles[i][j] = null;
}
}
}
}

public void removeTile(int x, int y) {
tiles[x][y] = TileType.BLANK;
}

public TileType getTile(int x, int y) {
return tiles[x][y];
}

public Point getTile(boolean start) {
for (int x = 0; x < tiles.length; x++) {
for (int y = 0; y < tiles[0].length; y++) {
if (tiles[x][y] == (start ? TileType.START : TileType.END)) {
return new Point(x, y);
}
}
}
return null;
}

public void setTile(int x, int y, TileType tile) {
if (getTile(x, y) != TileType.START && getTile(x, y) != TileType.END) {
tiles[x][y] = tile;
}
}

@Override
public void paint(Graphics g1) {
Graphics2D g = (Graphics2D) g1;
for (int x = 0; x < columns; x++) {
for (int y = 0; y < columns; y++) {
if (getTile(x, y) != null) {
g.setColor(getTile(x, y).getColour());
g.fillRect(x * pixelsPerTile, y * pixelsPerTile, pixelsPerTile, pixelsPerTile);
}
}
}
// have the grid appear on top of blank tiles
g.setColor(lineColour);
for (int x = 0; x < columns; x++) {
for (int y = 0; y < rows; y++) {
g.drawLine(x * pixelsPerTile, 0, x * pixelsPerTile, getHeight());
g.drawLine(0, y * pixelsPerTile, getWidth(), y * pixelsPerTile);
}
}
}

public int getPixelsPerTile() {
return pixelsPerTile;
}

public int getRows() {
return rows;
}

public int getColumns() {
return columns;
}
}

- Frame 类

public class Frame extends JFrame {

private Grid grid;

public Frame() {
grid = new Grid(33, 33, 15); // odd so there is a definitive middle point
this.setAutoRequestFocus(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle("A* Path finder");
this.setBounds(new Rectangle((grid.getRows()) * grid.getPixelsPerTile(),
(grid.getColumns() + 2) * grid.getPixelsPerTile()));
this.setResizable(true);
this.add(grid);
this.setVisible(true);
this.getContentPane().addMouseListener(new MouseLsntr()); // fixes alignment problems
ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(5);
se.scheduleAtFixedRate(new RedrawGrid(), 0L, 20L, TimeUnit.MILLISECONDS);
}

private class RedrawGrid implements Runnable {
@Override
public void run() {
grid.repaint();
}
}

private class MouseLsntr implements MouseListener {
@Override
public void mouseClicked(MouseEvent me) {
int x = me.getX() / grid.getPixelsPerTile();
int y = me.getY() / grid.getPixelsPerTile();
switch (me.getButton()) {
case MouseEvent.BUTTON1:
if (grid.getTile(x, y) != TileType.WALL) {
grid.setTile(x, y, TileType.WALL);
System.out.println(String.format("(%d, %d) (%d, %d) wall", x, y, x, y));
} else {
grid.removeTile(x, y);
System.out.println(String.format("(%d, %d) (%d, %d) blank", x, y, x, y));
}
break;
}
}

@Override
public void mousePressed(MouseEvent me) {}

@Override
public void mouseReleased(MouseEvent me) {}

@Override
public void mouseEntered(MouseEvent me) {}

@Override
public void mouseExited(MouseEvent me) {}
}
}
  • 显然还有一个调用 Frame() 的主类

当用户左键单击网格时,他们会在该位置制作一堵墙。如果它已经是一堵墙,它就会变成空白。我希望用户能够通过单击“开始”和“结束”图 block ,然后拖动到他们想要停止的位置来移动它,但我在执行此操作时遇到了麻烦。任何帮助将不胜感激,因为我已经被这个问题困扰了一段时间了。

最佳答案

您需要在 MouseListener 接口(interface)中实现 mousePressedmouseReleased 处理程序,以及在MouseMotionListener

首先,让您的 MouseLsntr 扩展 MouseAdapter 类,该类默认实现 MouseListenerMouseMotionListener

private class MouseLsntr extends MouseAdapter {
private int dragStartX, dragStartY;
private boolean dragging;

@Override
public void mouseClicked(MouseEvent me) {
int x = me.getX() / grid.getPixelsPerTile();
int y = me.getY() / grid.getPixelsPerTile();
switch (me.getButton()) {
case MouseEvent.BUTTON1:
if (grid.getTile(x, y) != TileType.WALL) {
grid.setTile(x, y, TileType.WALL);
System.out.println(String.format("(%d, %d) (%d, %d) wall", x, y, x, y));
} else {
grid.removeTile(x, y);
System.out.println(String.format("(%d, %d) (%d, %d) blank", x, y, x, y));
}
break;
}
}

@Override
public void mousePressed(MouseEvent me) {
switch (me.getButton()) {
case MouseEvent.BUTTON1:
// Save the drag starting position.
this.dragStartX = me.getX() / grid.getPixelsPerTile();
this.dragStartY = me.getY() / grid.getPixelsPerTile();
this.dragging = true;

break;
}
}

@Override
public void mouseReleased(MouseEvent me) {
switch (me.getButton()) {
case MouseEvent.BUTTON1:
if (this.dragging) {
moveTile(me);
}
this.dragging = false;

break;
}
}

@Override
public void mouseExited(MouseEvent me) {
this.dragging = false;
}

@Override
public void mouseDragged(MouseEvent me) {
if (this.dragging) {
moveTile(me);
}
}

private void moveTile(MouseEvent me) {
int dragEndX = me.getX() / grid.getPixelsPerTile();
int dragEndY = me.getY() / grid.getPixelsPerTile();

TileType dragStartType = grid.getTile(this.dragStartX, this.dragStartY);
TileType dragEndType = grid.getTile(dragEndX, dragEndY);
// If the starting tile was either START or END, move the tile to the destination.
if ((dragEndType == TileType.BLANK || dragEndType == null) &&
(dragStartType == TileType.START || dragStartType == TileType.END)) {

grid.removeTile(this.dragStartX, this.dragStartY);
grid.setTile(dragEndX, dragEndY, dragStartType);

// update the drag starting points
this.dragStartX = dragEndX;
this.dragStartY = dragEndY;
}
}
}

接下来,还将您的 MouseLsntr 实例添加为 MouseMotionListener,以便在拖动时调用 mouseDragged 处理程序。请注意,您不应创建两个单独的 MouseLsntr 实例,因为成员字段应共享。您应该在 Frame() 构造函数中执行以下操作。

    MouseLsntr listener = new MouseLsntr();
this.getContentPane().addMouseListener(listener);
this.getContentPane().addMouseMotionListener(listener);

执行此操作后,TileType.START/TileType.END 图 block 将在拖动时跟随鼠标。

关于Java GUI 更改 'tile' 的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18468435/

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