我目前正在嘗試爲一款名爲Carcassone的遊戲創建應用程序,但我在使用JLayeredPane和MouseAdapters時遇到了問題。JLayeredPane和MouseAdapter問題
目前我有一個JLayeredPane,它包含一個帶GridLayout的JPanel作爲遊戲板。 GridLayout的每個單元格都包含一個JPanel,其中包含一個JLabel,用於表示貼圖中的貼圖。 (一個空的瓦片只是一個帶黑色方塊的JLabel作爲圖像)。
我向JLayeredPane添加了一個自定義鼠標適配器(TileMouseAdapter),它允許用戶在遊戲板周圍移動瓷磚(鼠標按下 - 拖拽 - 釋放)或旋轉瓷磚(鼠標點擊)。 (要測試點擊下一個平鋪按鈕並在顯示的平鋪中移動,點擊提交按鈕後,如果平鋪是有效移動,平鋪將不再可拖動)。這一切都完美,因爲它應該直到我添加下一部分。
現在我想添加一個單獨的JPanel到屏幕頂部的JLayeredPane。本部分應該包含玩家可以放在瓷磚上的遊戲片段。我也希望JPanel能夠保留遊戲棋子,以便玩家可以將棋子拖動到棋子上。但是,當我創建此面板並將其添加到JLayeredPane時,上一節中的鼠標適配器不再正常工作。例如,如果您單擊平鋪的底部部分,則不再識別您正在點擊平鋪。如果你點擊每個瓦片的上半部分,它將只會選擇瓦片。此外,如果你點擊一個瓷磚的底部,有時它會選擇下面的瓷磚。即看起來好像選擇平鋪的機制似乎向上移動大約一半的平鋪。 任何人都可以找出解決這個問題/一個可能的解決辦法嗎? 謝謝!
下面的代碼,是我用於創建包含JPanel中的板(myBoardPanel)以及爲遊戲片面板JLayeredPane的代碼(makeMeeplePanel())
private JLayeredPane makeBoardPanel() {
JLayeredPane layeredPane = new JLayeredPane();
layeredPane.setLayout(new BorderLayout());
myBoardPanel = new CarcassoneBoardPanel(layeredPane);
layeredPane.add(makeMeeplePanel(), BorderLayout.NORTH, JLayeredPane.DEFAULT_LAYER);
layeredPane.add(myBoardPanel, BorderLayout.CENTER, JLayeredPane.DEFAULT_LAYER);
TileMouseAdapter tileMouseAdapter = new TileMouseAdapter(layeredPane);
//MeepleMouseAdapter meepleMouseAdapter = new MeepleMouseAdapter(layeredPane);
layeredPane.addMouseListener(tileMouseAdapter);
layeredPane.addMouseMotionListener(tileMouseAdapter);
//layeredPane.addMouseListener(meepleMouseAdapter);
//layeredPane.addMouseMotionListener(meepleMouseAdapter);
return layeredPane;
}
這是我的自定義鼠標適配器的遊戲板:
package gui;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import tiles.*;
public class TileMouseAdapter extends MouseAdapter {
private JLayeredPane myLayeredPane;
private CarcassoneBoardPanel myBoard;
private Tile dragLabel;
private JPanel clickedPanel;
public TileMouseAdapter(JLayeredPane layeredPane) {
myLayeredPane = layeredPane;
myBoard = (CarcassoneBoardPanel) layeredPane.getComponents()[1];
}
private void reset() {
if (dragLabel != null) {
myLayeredPane.remove(dragLabel);
myLayeredPane.revalidate();
myLayeredPane.repaint();
}
dragLabel = null;
clickedPanel = null;
}
@Override
public void mouseClicked(MouseEvent event) {
clickedPanel = (JPanel) myBoard.getComponentAt(event.getPoint());
if (clickedPanel == null) {
reset();
return;
}
Component[] components = clickedPanel.getComponents();
if (!(components[0] instanceof Tile) || components[0] instanceof EmptyTile || !((Tile) components[0]).isDraggable()) {
return;
}
dragLabel = (Tile) components[0];
dragLabel.rotate();
clickedPanel.revalidate();
clickedPanel.repaint();
reset();
}
@Override
public void mousePressed(MouseEvent event) {
clickedPanel = (JPanel) myBoard.getComponentAt(event.getPoint());
System.out.println(event.getPoint());
if (clickedPanel == null) {
reset();
return;
}
Component[] components = clickedPanel.getComponents();
if (!(components[0] instanceof Tile) || (components[0] instanceof EmptyTile) || !((Tile) components[0]).isDraggable()) {
return;
}
dragLabel = (Tile) components[0];
clickedPanel.remove(dragLabel);
clickedPanel.add(new EmptyTile(dragLabel.getRow(), dragLabel.getCol()));
clickedPanel.revalidate();
clickedPanel.repaint();
int x = event.getPoint().x - dragLabel.getWidth()/2;
int y = event.getPoint().y - dragLabel.getHeight()/2;
dragLabel.setLocation(x, y);
try {
myLayeredPane.add(dragLabel, JLayeredPane.DRAG_LAYER);
myLayeredPane.repaint();
} catch (IllegalArgumentException e) {
//TODO: deal with this?
//gives error for some unknown reason, but doesnt effect anything? ignore...dumb error cus jswing sucks
}
}
@Override
public void mouseDragged(MouseEvent event) {
if (dragLabel == null) {
return;
}
int x = event.getPoint().x - dragLabel.getWidth()/2;
int y = event.getPoint().y - dragLabel.getHeight()/2;
dragLabel.setLocation(x, y);
myLayeredPane.revalidate();
}
@Override
public void mouseReleased(MouseEvent event) {
//TODO: make sure cannot place tile on already occupied panel...
if (dragLabel == null || !dragLabel.isDraggable()) {
return;
}
myLayeredPane.remove(dragLabel);
myLayeredPane.revalidate();
myLayeredPane.repaint();
JPanel droppedPanel = (JPanel) myBoard.getComponentAt(event.getPoint());
if (droppedPanel == null) {
clickedPanel.removeAll();
clickedPanel.add(dragLabel);
clickedPanel.revalidate();
reset();
return;
}
dragLabel.setPosition(((Tile) droppedPanel.getComponents()[0]).getRow(), ((Tile) droppedPanel.getComponents()[0]).getCol());
droppedPanel.removeAll();
droppedPanel.add(dragLabel);
droppedPanel.revalidate();
reset();
}
}
請讓我知道如果你需要的信息了/代碼。這是我第一次使用這個網站,很抱歉,如果我沒有提供足夠的解釋,等等...... 謝謝!
太棒了!那很簡單......你修好了。謝謝你爲我節省了很多時間! – nothingness