gpt4 book ai didi

java - 如何正确使用 MouseMotionListener 来按下 JButtons?

转载 作者:搜寻专家 更新时间:2023-11-01 03:38:11 25 4
gpt4 key购买 nike

我制作了一个康威生命游戏小程序。我大约完成了 80%。我使用了 JButtons 网格作为单元格。现在我在每个按钮上都有一个 ButtonListener,因此您必须通过单击各个按钮来一个接一个地绘制您想要的图案。我希望能够单击并拖动鼠标并快速选择按钮。我使用了 MotionListener 类,实现了 MouseMotionListener 并以与我的 actionPerformed 方法相同的方式对 mouseDragged 方法进行了编码在我的 ButtonListener 类中。

我认为逻辑应该是相同的,但我肯定遗漏了一些东西。我玩了一下,认为它只是一遍又一遍地选择和取消选择,速度比我想象的要快。我添加了一个检查以确保它不会尝试连续更改相同的按钮,但这没有帮助。这是我的 MotionListener 类:

    class MotionListener implements MouseMotionListener {

@Override
public void mouseDragged(MouseEvent e) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (e.getSource() == squares[i][j]) {
if (litSquares[i][j] == false) {
squares[i][j].setBackground(selected);
litSquares[i][j] = true;
} else {
squares[i][j].setBackground(backGround);
litSquares[i][j] = false;
}
}
}
}
}

@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub

}

}

我的 JButton 数组是 squares[][]litSquares[][] 是当前选择的 boolean 映射,我在计算下一个时使用步骤。

关于如何更正我的 MotionListener 有什么想法吗?我不了解如何正确实现此类。我找到的所有简单示例都与绘图有关,但它们似乎都跟踪拖动光标的,然后更新像素。这是我必须以某种方式用我的按钮做的事情吗?

***** 这是 MCVE,或者至少尽可能小。 *****

package extraCredit;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.*;
import javax.swing.border.Border;

public class MCVE extends JPanel {

private static final long serialVersionUID = -8031881678612431401L;

static JFrame frame;
static JPanel grid;
static JButton[][] squares;
static boolean[][] litSquares, boardCopy;
static int size, boardSize, tick = 1, goal = 100, rateIncrease = 10;
ButtonListener listener = new ButtonListener();
MotionListener mListerner = new MotionListener();
Border noBorder = BorderFactory.createEmptyBorder();
Color backGround = Color.BLUE;
Color selected = Color.PINK;

public MCVE(int size) {
MCVE.size = size;
squares = new JButton[size][size];
litSquares = new boolean[size][size];
grid = new JPanel(new GridLayout(size, size));
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
squares[i][j] = new JButton();
squares[i][j].addActionListener(listener);
// squares[i][j].addMouseMotionListener(mListerner);
squares[i][j].setBackground(backGround);
squares[i][j].setBorder(noBorder);
grid.add(squares[i][j]);
}
}

frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(grid, BorderLayout.CENTER);
frame.setTitle("Life");
if (25 * size < 525) {
boardSize = 525;
} else {
boardSize = 25 * size;
}
frame.setSize(boardSize, boardSize);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}

class ButtonListener implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (e.getSource() == squares[i][j]) {
if (litSquares[i][j] == false) {
squares[i][j].setBackground(selected);
litSquares[i][j] = true;
} else {
squares[i][j].setBackground(backGround);
litSquares[i][j] = false;
}
}
}
}
}
}

class MotionListener implements MouseMotionListener {

@Override
public void mouseDragged(MouseEvent e) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (e.getSource() == squares[i][j]) {
if (litSquares[i][j] == false) {
squares[i][j].setBackground(selected);
litSquares[i][j] = true;
} else {
squares[i][j].setBackground(backGround);
litSquares[i][j] = false;
}
}
}
}
}

@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
}

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

下面的解决方案,感谢@MadProgrammer 和@durron597。狂回答我的其他question这让我无法解决这个问题。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.HashSet;
import java.util.Set;

import javax.swing.*;

public class ChangesAttempt extends JPanel {
private static final long serialVersionUID = -8031881678612431401L;

static JFrame frame;
static JPanel grid;
static JLabel[][] squares;
static boolean[][] litSquares;
static int size, boardSize;
static boolean startDrag, origin;
static Set<Component> compList = new HashSet<Component>();
MouseEvent listener = new MouseEvent();
MotionListener mListerner = new MotionListener();
Color backGround = Color.BLUE;
Color selected = Color.PINK;

public ChangesAttempt(int size) {
ChangesAttempt.size = size;
squares = new JLabel[size][size];
litSquares = new boolean[size][size];
grid = new JPanel(new GridLayout(size, size));
grid.addMouseMotionListener(mListerner);
grid.addMouseListener(listener);
setBoard();

frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(grid, BorderLayout.CENTER);
frame.setTitle("ChangedLife");
if (25 * size < 525)
boardSize = 525;
else
boardSize = 25 * size;
frame.setSize(boardSize, boardSize);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}

class MouseEvent implements MouseListener {

@Override
public void mousePressed(java.awt.event.MouseEvent e) {
startDrag = true;
}

@Override
public void mouseClicked(java.awt.event.MouseEvent e) {
Component source = e.getComponent().getComponentAt(e.getPoint());
System.out.println("X = " +source.getX() + ", Y = " + source.getY());
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (source == squares[i][j]) {
if (litSquares[i][j] == false) {
squares[i][j].setBackground(selected);
litSquares[i][j] = true;
} else {
squares[i][j].setBackground(backGround);
litSquares[i][j] = false;
}
}
}
}
}

@Override
public void mouseEntered(java.awt.event.MouseEvent e) {
}

@Override
public void mouseExited(java.awt.event.MouseEvent e) {
}

@Override
public void mouseReleased(java.awt.event.MouseEvent e) {
compList.clear();
}
}

class MotionListener implements MouseMotionListener {
@Override
public void mouseDragged(java.awt.event.MouseEvent e) {
compList.add(e.getComponent().getComponentAt(e.getPoint()));
updateBoard();
}

@Override
public void mouseMoved(java.awt.event.MouseEvent e) {

}
}

public void setBoard() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
squares[i][j] = new JLabel();
squares[i][j].setOpaque(true);
squares[i][j].setBackground(backGround);
grid.add(squares[i][j]);
}
}
}

public void updateBoard(){
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (compList.contains(squares[i][j])) {
if(startDrag){
startDrag = false;
origin = litSquares[i][j];
}
if (litSquares[i][j] == origin) {
if(origin)
squares[i][j].setBackground(backGround);
else
squares[i][j].setBackground(selected);
litSquares[i][j] = !litSquares[i][j];
}
}
}
}
}

class MyLabel extends JLabel {
private static final long serialVersionUID = -1414933339546989142L;

}

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

最佳答案

我认为您遇到的问题是您正试图将 JButton 用于其设计目的之外的事情。我会选择一个更简单的控件,例如 JLabel,这样您就不会拥有 JButton 所具有的所有额外功能。

其次,您的 litSquares 数组显然是 Data Clump .您绝对应该创建自己的自定义控件(可以 extend JComponentextend JLabel),具体取决于 JLabel 是否满足您的需求,即包含应与控件本身配对的其他信息。

第三,你可能不希望按钮的状态是一个boolean,你可能希望它是一个enum...比如

public enum State {
UNLIT, LIT, CURRENTLY_SELECTED;
}

这样您就可以看到哪些组件正在被新颜色翻转。

最后,正如评论中提到的,使用 public Component getComponentAt(int x, int y) 能够弄清楚 MouseMotionListener 被拖过来的是什么,并用它来改变颜色。

关于java - 如何正确使用 MouseMotionListener 来按下 JButtons?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23422313/

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