[英]How to get the live location of mouse in java swing?
我正在嘗試創建一個簡單的井字游戲,我想在鼠標所在的正方形上顯示高亮。 我在java.awt.Canvas
上繪制游戲,目前,我嘗試了這些失敗的方法:
MouseAdapter
添加到我的 Canvas 並覆蓋其mouseEnter
方法,但它僅在 cursor 進入畫布時起作用(正如它應該的那樣)。JPanel
(每個正方形一個)並為每個添加了一個MouseAdapter
。 但它也沒有奏效。 我搜索了原因,發現我應該requestFocus()
來啟用監聽器。順便說一句,這是我的代碼:
Class 用於覆蓋MouseAdaper
的方法:
public class MouseInput extends MouseAdapter {
private final Game game;
private final int i;
private final int j;
public MouseInput(Game game, JPanel panel){
this.game = game;
i = panel.getY() / 64;
j = panel.getX() / 64;
}
@Override
public void mouseEntered(MouseEvent e) {
game.mouseEntered(i, j);
}
@Override
public void mouseExited(MouseEvent e) {
game.mouseExited(i, j);
}
@Override
public void mouseClicked(MouseEvent e){
game.mouseClicked(i, j);
}
}
游戲中的JPanel
並向其中添加MouseListener
:
public class Game extends Canvas implements Runnable {
private boolean isRunning = false;
private Thread thread;
private final JPanel[][] panels = new JPanel[3][3];
public static void main(String[] args) {
Game game = new Game();
game.setPreferredSize(new Dimension(192, 192));
JFrame frame = new JFrame();
frame.add(game);
frame.setResizable(false);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
}
private void start(){
if(isRunning){
return;
}
isRunning = true;
thread = new Thread(this);
thread.start();
}
private void stop(){
if(!isRunning){
return;
}
isRunning = false;
try {
thread.join();
} catch (InterruptedException ignored) {}
System.exit(0);
}
@Override
public void run(){
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
JPanel p = new JPanel();
p.setPreferredSize(new Dimension(64, 64));
p.setLocation(j * 64, i * 64);
p.addMouseListener(new MouseInput(this, p));
panels[i][j] = p;
}
}
}
}
Swing 不是線程安全的,是單線程的。 您不應該從事件調度線程的上下文之外更新 UI 或更新 UI 依賴的東西。
在您的情況下,面板實際上並未附加到任何東西(即添加到容器中),因此無法響應任何事件。
您還應該花時間學習一些布局管理基礎知識。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
JPanel board = new JPanel(new GridLayout(3, 3));
for (int index = 0; index < 9; index++) {
board.add(new GridPane());
}
frame.add(board);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GridPane extends JPanel {
private MouseListener mouseHandler;
public GridPane() {
setBorder(new LineBorder(Color.BLACK));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
@Override
public void addNotify() {
super.addNotify();
if (mouseHandler != null) {
removeMouseListener(mouseHandler);
}
mouseHandler = new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
setBackground(Color.RED);
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(null);
}
};
addMouseListener(mouseHandler);
}
@Override
public void removeNotify() {
super.removeNotify();
if (mouseHandler != null) {
removeMouseListener(mouseHandler);
}
}
}
}
而不是試圖讓一個聽眾嘗試更新游戲 model。 將游戲參考傳遞給每個面板並讓它完成這項工作。 這樣,您可以將“標識符”傳遞給每個可以傳遞回游戲的單元格,以便它可以做出一些需要的決定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.