我正在尝试构建一个Scrabble游戏,以帮助您更熟悉构建GUI并练习一般的Java技能。该板主要由带有JPanels的JLayeredPane组成,包括电路板图像和电路板空间。我试图通过将tile添加到drag_layer然后从那里移动来将Tile对象(扩展JLabel)拖放到棋盘周围,类似于以下示例:dragging a jlabel around the screen。鼠标按下正在工作并正确地将图块添加到拖动图层,但在此之后,鼠标似乎完全停止了。我试着打印"拖动"在mouseDragged覆盖方法中,但它甚至不会打印它。有两个相关的类 - Console和MouseInput,我将在下面显示,但如果你想拉动整个项目,我还会在最后添加到GitHub仓库的链接。
控制台:
public Console () throws IOException{
// Create gameConsole
gameConsole = new JFrame();
final int frameWidth = 850;
final int frameHeight = 950;
gameConsole.setPreferredSize(new Dimension(frameWidth, frameHeight));
gameConsole.setTitle("Scrabble");
gameConsole.setLayout(new GridBagLayout());
gameConsole.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.ipadx = 810;
c.ipady = 950;
// Create center console panel and add to gameConsole
centerConsole = new JPanel();
centerConsole.setLayout(new BorderLayout());
gameConsole.add(centerConsole,c);
// Create layered pane that holds the board and playerbox
gameContainer = new JLayeredPane();
gameContainer.setBounds(0,0,810,950);
gameContainer.addMouseListener(new MouseInput(gameContainer));
gameContainer.addMouseMotionListener(new MouseInput(gameContainer));
centerConsole.add(gameContainer, BorderLayout.CENTER);
// Create board image label and add to JPanel
BufferedImage scrabbleImage = ImageIO.read(Console.class.getResource("/board.jpg"));
JLabel background = new JLabel(new ImageIcon(scrabbleImage));
boardImage = new JPanel();
boardImage.setBounds(0, 0, 810, 810);
boardImage.add(background);
boardImage.setOpaque(true);
// create JPanel with gridBagLayout
boardGrid = new JPanel();
boardGrid.setBounds(0, 3, 810, 810);
boardGrid.setLayout(new GridBagLayout());
boardGrid.setOpaque(false);
// Create panels to add to boardGrid
spaces = new BoardSpace [15][15];
BoardSpace.setBoardSpaces(spaces);
// Set grid constraints
GridBagConstraints cGrid = new GridBagConstraints();
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
// panel constraints
cGrid.gridx = i; // grid x location
cGrid.gridy = j; // grid y location
cGrid.gridheight = 1; // spans 1 row
cGrid.gridwidth = 1; // spans 1 column
cGrid.weightx = 0.0;
cGrid.weighty = 0.0;
cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally
// Set size of board space and add to grid
spaces[i][j].setOpaque(false);
spaces[i][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
boardGrid.add(spaces[i][j], cGrid);
}
}
// Add to layeredPane
gameContainer.add(boardImage, new Integer(0),0);
gameContainer.add(boardGrid, new Integer(1),0);
// Create player box panel
playerPanel = new JPanel();
playerPanel.setLayout(new GridBagLayout());
playerBox = new JPanel();
playerBox.setLayout(new GridLayout(1,7, 10, 0));
// Create player box constraints
GridBagConstraints cp = new GridBagConstraints();
cp.ipadx = 50;
cp.ipady = 50;
// Create playerBox spaces
playerSpaces = new BoardSpace [1][7];
BoardSpace.setPlayerSpaces(playerSpaces);
// Add playerSpaces to playerBox
for (int j = 0; j < 7; j++) {
// panel constraints
cGrid.gridx = 0; // grid x location
cGrid.gridy = j; // grid y location
cGrid.gridheight = 1; // spans 1 row
cGrid.gridwidth = 1; // spans 1 column
cGrid.weightx = 0.0;
cGrid.weighty = 0.0;
cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally
// Set size of board space and add to grid
playerSpaces[0][j].setOpaque(false);
playerSpaces[0][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
playerBox.add(playerSpaces[0][j], cGrid);
}
// Add player box to south panel
playerPanel.add(playerBox, cp);
// Add player box to bottom of layeredPane
playerPanel.setBounds(0,825,810,75);
gameContainer.add(playerPanel, new Integer(0),0);
gameConsole.pack();
// Make gameConsole visible
gameConsole.setVisible(true);
}
鼠标适配器:
public class MouseInput extends MouseAdapter {
/**
*
*/
private Component mouseArea;
private boolean dragging;
private Tile draggingTile;
private BoardSpace currentSpace;
private BoardSpace startingSpace;
private Component selectedObject;
Component [] panelObjects;
private JLayeredPane dragLayer;
private Point dragPoint;
private int dragWidth;
private int dragHeight;
public MouseInput(Component mouseArea) {
// TODO Auto-generated constructor stub
super();
mouseArea = this.mouseArea;
}
void eventOutput(String eventDescription, MouseEvent e) {
Point p = e.getPoint();
System.out.println(eventDescription
+ " (" + p.getX() + "," + p.getY() + ")"
+ " detected on "
+ e.getComponent().getClass().getName()
+ "\n");
}
public void mouseMoved(MouseEvent e) {
//eventOutput("Mouse moved", e);
}
public void mouseDragged(MouseEvent e) {
if (dragging) {
System.out.println("Dragging");
}
if (!dragging) {
return;
} else {
System.out.println("Dragging " + Tile.getLetter(draggingTile));
int x = e.getPoint().x - dragWidth;
int y = e.getPoint().y - dragHeight;
draggingTile.setLocation(x, y);
draggingTile.repaint();
}
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
//eventOutput("Mouse Clicked", e);
}
@Override
public void mouseEntered(MouseEvent e) {
/*
dragPoint = e.getPoint();
selectedObject = e.getComponent().getComponentAt(dragPoint);
// Get the current space
while (!selectedObject.getClass().getSimpleName().equals("BoardSpace")) {
try {
dragPoint = selectedObject.getMousePosition();
selectedObject = selectedObject.getComponentAt(dragPoint);
} catch (NullPointerException illegalSpace){
currentSpace = startingSpace;
break;
}
}
if (selectedObject.getClass().getSimpleName().equals("BoardSpace")) {
currentSpace = (BoardSpace) selectedObject;
System.out.println(BoardSpace.getID(currentSpace));
} */
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
//eventOutput("Mouse Exited", e);
}
@Override
public void mousePressed(MouseEvent e) {
dragLayer = (JLayeredPane) e.getSource();
dragPoint = e.getPoint();
selectedObject = e.getComponent().getComponentAt(dragPoint);
// Get the current space
while (!selectedObject.getClass().getSimpleName().equals("BoardSpace")) {
try {
dragPoint = selectedObject.getMousePosition();
selectedObject = selectedObject.getComponentAt(dragPoint);
} catch (NullPointerException illegalSpace){
return;
}
}
currentSpace = (BoardSpace) selectedObject;
startingSpace = currentSpace;
// If the boardspace has a tile, remove Tile from boardspace and add to dragging layer
if (BoardSpace.Taken(currentSpace)) {
// get dragging tile
draggingTile = BoardSpace.getTile(currentSpace);
dragging = true;
// remove tile and repaint space
BoardSpace.removeTile(currentSpace, draggingTile);
currentSpace.revalidate();
currentSpace.repaint();
// Add tile to dragging layer
dragWidth = draggingTile.getWidth() / 2;
dragHeight = draggingTile.getHeight() / 2;
int x = e.getPoint().x - dragWidth;
int y = e.getPoint().y - dragHeight;
draggingTile.setLocation(x, y);
dragLayer.add(draggingTile, JLayeredPane.DRAG_LAYER);
draggingTile.revalidate();
draggingTile.repaint();
System.out.println("Selected Tile " + Tile.getLetter(draggingTile));
} else {
return;
}
}
@Override
public void mouseReleased(MouseEvent e) {
/*
// TODO Auto-generated method stub
if (!BoardSpace.Taken(currentSpace)) {
return;
} else {
dragging = false;
BoardSpace.setTile(currentSpace, draggingTile);
draggingTile = null;
currentSpace.repaint();
currentSpace.revalidate();
} */
}
}
中提取完整代码
答案 0 :(得分:0)
所以在玩了一些之后,我发现每次调用一个新的鼠标操作(鼠标按下,鼠标拖动等)时,它都会实例化私有类变量的新实例,所以变量不是&#39 ; t持有他们的设定值。为了解决这个问题,我使用这些附加变量创建了一个新类作为JLayeredPane的扩展,并使用我的新类作为分层游戏控制台。当一个tile在边界之外或在一个无效空间中释放时,仍在设计一些错误处理,但下面的代码至少让我在有效空间中移动tile。以下帖子有助于解决这个问题:MouseListener in separate class not working。同样,可以从上面列出的git repo中提取完整代码。
BoardPane课程:
package objects;
import java.awt.Component;
import java.awt.Point;
import javax.swing.JLayeredPane;
public class BoardPane extends JLayeredPane {
/**
*
*/
private static final long serialVersionUID = 1L;
private boolean dragging;
private Tile draggingTile;
private BoardSpace currentSpace;
private BoardSpace startingSpace;
private Component selectedObject;
Component [] panelObjects;
private BoardPane dragLayer;
private Point dragPoint;
private int dragWidth;
private int dragHeight;
public BoardPane() {
this.dragging = false;
this.draggingTile = null;
this.currentSpace = null;
this.startingSpace = null;
this.selectedObject = null;
this.panelObjects = null;
this.dragLayer = null;
this.dragPoint = null;
this.dragWidth = 51/2;
this.dragHeight = 51/2;
}
public static void resetPane(BoardPane board) {
board.dragging = false;
board.draggingTile = null;
board.currentSpace = null;
board.startingSpace = null;
board.selectedObject = null;
board.panelObjects = null;
board.dragLayer = null;
board.dragPoint = null;
}
public static Boolean getDragStatus(BoardPane board) {
return board.dragging;
}
public static void setDragStatus(BoardPane board, Boolean status) {
board.dragging = status;
}
public static Tile getDragTile(BoardPane board) {
return board.draggingTile;
}
public static void setDragTile(BoardPane board, Tile t) {
board.draggingTile = t;
}
public static BoardSpace getCurrentSpace(BoardPane board) {
return board.currentSpace;
}
public static void setCurrentSpace(BoardPane board, BoardSpace bs) {
board.currentSpace = bs;
}
public static BoardSpace getStartingSpace(BoardPane board) {
return board.startingSpace;
}
public static void setStartingSpace(BoardPane board, BoardSpace bs) {
board.startingSpace = bs;
}
public static Component getSelectedObj(BoardPane board) {
return board.selectedObject;
}
public static void setSelectedObj(BoardPane board, Component obj) {
board.selectedObject = obj;
}
public static Component [] getPanelObjects(BoardPane board) {
return board.panelObjects;
}
public static BoardPane getDragLayer(BoardPane board) {
return board.dragLayer;
}
public static void setDragLayer(BoardPane board) {
board.dragLayer = board;
}
public static void setPanelObjects(BoardPane board, Component [] obj) {
board.panelObjects = obj;
}
public static Point getDragPoint (BoardPane board) {
return board.dragPoint;
}
public static void setDragPoint(BoardPane board, Point p) {
board.dragPoint = p;
}
public static int getDragWidth(BoardPane board) {
return board.dragWidth;
}
public static int getDragHeight(BoardPane board) {
return board.dragHeight;
}
}
控制台:
package Main;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import objects.BoardPane;
import objects.BoardSpace;
import javax.imageio.ImageIO;
public class Console {
private JFrame gameConsole;
private JPanel centerConsole;
private BoardPane gameContainer;
private JPanel playerPanel;
private JPanel gamePanel;
private JPanel north;
private JPanel south;
private JPanel east;
private JPanel west;
private JLayeredPane center;
private JPanel splash;
private JPanel playerBox;
private JPanel boardGrid;
private JPanel boardImage;
private JButton start;
private BoardSpace [][] spaces;
private BoardSpace [][] playerSpaces;
public Console () throws IOException{
// Create gameConsole
gameConsole = new JFrame();
final int frameWidth = 850;
final int frameHeight = 950;
gameConsole.setPreferredSize(new Dimension(frameWidth, frameHeight));
gameConsole.setTitle("Scrabble");
gameConsole.setLayout(new GridBagLayout());
gameConsole.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.ipadx = 810;
c.ipady = 950;
// Create center console panel and add to gameConsole
centerConsole = new JPanel();
centerConsole.setLayout(new BorderLayout());
gameConsole.add(centerConsole,c);
// Create layered pane that holds the board and playerbox
gameContainer = new BoardPane();
gameContainer.setBounds(0,0,810,950);
MouseInput mouseActions = new MouseInput();
gameContainer.addMouseMotionListener(mouseActions);
gameContainer.addMouseListener(mouseActions);
centerConsole.add(gameContainer, BorderLayout.CENTER);
// Create board image label and add to JPanel
BufferedImage scrabbleImage = ImageIO.read(Console.class.getResource("/board.jpg"));
JLabel background = new JLabel(new ImageIcon(scrabbleImage));
boardImage = new JPanel();
boardImage.setBounds(0, 0, 810, 815);
boardImage.add(background);
boardImage.setOpaque(true);
// create JPanel with gridBagLayout
boardGrid = new JPanel();
boardGrid.setBounds(0, 3, 810, 810);
boardGrid.setLayout(new GridBagLayout());
boardGrid.setOpaque(false);
// Create panels to add to boardGrid
spaces = new BoardSpace [15][15];
BoardSpace.setBoardSpaces(spaces);
// Set grid constraints
GridBagConstraints cGrid = new GridBagConstraints();
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
// panel constraints
cGrid.gridx = i; // grid x location
cGrid.gridy = j; // grid y location
cGrid.gridheight = 1; // spans 1 row
cGrid.gridwidth = 1; // spans 1 column
cGrid.weightx = 0.0;
cGrid.weighty = 0.0;
cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally
// Set size of board space and add to grid
spaces[i][j].setOpaque(false);
spaces[i][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
boardGrid.add(spaces[i][j], cGrid);
}
}
// Add to layeredPane
gameContainer.add(boardImage, new Integer(0),0);
gameContainer.add(boardGrid, new Integer(1),0);
// Create player box panel
playerPanel = new JPanel();
playerPanel.setLayout(new GridBagLayout());
playerBox = new JPanel();
playerBox.setLayout(new GridLayout(1,7, 10, 0));
// Create player box constraints
GridBagConstraints cp = new GridBagConstraints();
cp.ipadx = 50;
cp.ipady = 50;
// Create playerBox spaces
playerSpaces = new BoardSpace [1][7];
BoardSpace.setPlayerSpaces(playerSpaces);
// Add playerSpaces to playerBox
for (int j = 0; j < 7; j++) {
// panel constraints
cGrid.gridx = 0; // grid x location
cGrid.gridy = j; // grid y location
cGrid.gridheight = 1; // spans 1 row
cGrid.gridwidth = 1; // spans 1 column
cGrid.weightx = 0.0;
cGrid.weighty = 0.0;
cGrid.fill = GridBagConstraints.BOTH; // Resize veritically & horizontally
// Set size of board space and add to grid
playerSpaces[0][j].setOpaque(false);
playerSpaces[0][j].setPreferredSize(new Dimension((int) Info.GRIDSIZE,(int) Info.GRIDSIZE));
playerBox.add(playerSpaces[0][j], cGrid);
}
// Add player box to south panel
playerPanel.add(playerBox, cp);
// Add player box to bottom of layeredPane
playerPanel.setBounds(0,825,810,75);
gameContainer.add(playerPanel, new Integer(0),0);
gameConsole.pack();
// Make gameConsole visible
gameConsole.setVisible(true);
}
}
鼠标侦听器:
package Main;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JLayeredPane;
import objects.BoardSpace;
import objects.Tile;
import objects.BoardPane;
public class MouseInput implements MouseMotionListener, MouseListener {
/**
*
*/
private BoardPane dragLayer;
void eventOutput(String eventDescription, MouseEvent e) {
Point p = e.getPoint();
System.out.println(eventDescription
+ " (" + p.getX() + "," + p.getY() + ")"
+ " detected on "
+ e.getComponent().getClass().getName()
+ "\n");
}
@Override
public void mouseMoved(MouseEvent e) {
//eventOutput("Mouse moved", e);
}
@Override
public void mouseDragged(MouseEvent e) {
// Set dragLayer
dragLayer = BoardPane.getDragLayer((BoardPane) e.getSource());
// Drag tile across board
if (BoardPane.getDragStatus(dragLayer)) {
int x = e.getPoint().x - BoardPane.getDragWidth(dragLayer);
int y = e.getPoint().y - BoardPane.getDragHeight(dragLayer);
BoardPane.getDragTile(dragLayer).setLocation(x, y);
BoardPane.getDragTile(dragLayer).repaint();
System.out.println("Dragging Tile " + Tile.getLetter(BoardPane.getDragTile(dragLayer)));
}
}
@Override
public void mouseClicked(MouseEvent e) {
//eventOutput("Mouse Clicked", e);
}
@Override
public void mouseEntered(MouseEvent e) {
eventOutput("Mouse entered", e);
}
@Override
public void mouseExited(MouseEvent e) {
eventOutput("Mouse Exited", e);
}
@Override
public void mousePressed(MouseEvent e) {
eventOutput("Mouse Pressed", e);
// Set dragLayer, dragPoint, and selectedObject
BoardPane.setDragLayer((BoardPane) e.getSource());
dragLayer = (BoardPane) e.getSource();
BoardPane.setDragPoint(dragLayer, e.getPoint());
BoardPane.setSelectedObj(dragLayer, e.getComponent().getComponentAt(BoardPane.getDragPoint(dragLayer)));
// Find the current board space
try {
while (!BoardPane.getSelectedObj(dragLayer).getClass().getSimpleName().equals("BoardSpace")) {
BoardPane.setDragPoint(dragLayer, BoardPane.getSelectedObj(dragLayer).getMousePosition());
BoardPane.setSelectedObj(dragLayer, BoardPane.getSelectedObj(dragLayer).getComponentAt(BoardPane.getDragPoint(dragLayer)));
}
} catch (NullPointerException illegalSpace) {
return;
}
// Set the current board space & starting space
BoardPane.setCurrentSpace(dragLayer, (BoardSpace) BoardPane.getSelectedObj(dragLayer));
BoardPane.setStartingSpace(dragLayer, BoardPane.getCurrentSpace(dragLayer));
// If the board space has a tile, remove Tile from board space then add to dragging layer
if (BoardSpace.Taken(BoardPane.getCurrentSpace(dragLayer))) {
// get dragging tile
BoardPane.setDragTile(dragLayer, BoardSpace.getTile(BoardPane.getCurrentSpace(dragLayer)));
BoardPane.setDragStatus(dragLayer, true);
// remove tile and repaint space
BoardSpace.removeTile(BoardPane.getCurrentSpace(dragLayer), BoardPane.getDragTile(dragLayer));
BoardPane.getCurrentSpace(dragLayer).revalidate();
BoardPane.getCurrentSpace(dragLayer).repaint();
// Add tile to dragging layer at specified location
int x = e.getPoint().x - BoardPane.getDragWidth(dragLayer);
int y = e.getPoint().y - BoardPane.getDragHeight(dragLayer);
BoardPane.getDragTile(dragLayer).setLocation(x, y);
dragLayer.add(BoardPane.getDragTile(dragLayer), JLayeredPane.DRAG_LAYER);
BoardPane.getDragTile(dragLayer).revalidate();
BoardPane.getDragTile(dragLayer).repaint();
System.out.println("Selected Tile " + Tile.getLetter(BoardPane.getDragTile(dragLayer)));
} else {
return;
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (BoardPane.getDragStatus(dragLayer) == true) {
// Change drag status to false
BoardPane.setDragStatus(dragLayer, false);
// Set dragLayer & remove tile
dragLayer = BoardPane.getDragLayer((BoardPane) e.getSource());
dragLayer.remove(BoardPane.getDragTile(dragLayer));
dragLayer.revalidate();
dragLayer.repaint();
//get selected object at given point
BoardPane.setDragPoint(dragLayer, e.getPoint());
BoardPane.setSelectedObj(dragLayer, e.getComponent().getComponentAt(BoardPane.getDragPoint(dragLayer)));
// Find the current board space
try {
while(!BoardPane.getSelectedObj(dragLayer).getClass().getSimpleName().equals("BoardSpace")) {
BoardPane.setDragPoint(dragLayer, BoardPane.getSelectedObj(dragLayer).getMousePosition());
BoardPane.setSelectedObj(dragLayer, BoardPane.getSelectedObj(dragLayer).getComponentAt(BoardPane.getDragPoint(dragLayer)));
}
} catch (NullPointerException illegalSpace) {
// if released on an invalid space, put tile back in starting space
BoardPane.getStartingSpace(dragLayer).add(BoardPane.getDragTile(dragLayer));
BoardPane.getStartingSpace(dragLayer).revalidate();
BoardPane.getStartingSpace(dragLayer).repaint();
BoardPane.resetPane(dragLayer);
return;
}
// Set the current board space & starting space
BoardPane.setCurrentSpace(dragLayer, (BoardSpace) BoardPane.getSelectedObj(dragLayer));
// If space is not taken, add tile to space, otherwise put back in starting space
if (!BoardSpace.Taken(BoardPane.getCurrentSpace(dragLayer))) {
BoardSpace.setTile(BoardPane.getCurrentSpace(dragLayer), BoardPane.getDragTile(dragLayer));
BoardPane.getCurrentSpace(dragLayer).revalidate();
BoardPane.getCurrentSpace(dragLayer).repaint();
//BoardPane.setDragTile(dragLayer, null);
} else {
BoardPane.getStartingSpace(dragLayer).add(BoardPane.getDragTile(dragLayer));
BoardPane.getStartingSpace(dragLayer).revalidate();
BoardPane.getStartingSpace(dragLayer).repaint();
}
BoardPane.resetPane(dragLayer);
}
}
}