首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确使用MouseMotionListener按JButtons?

如何正确使用MouseMotionListener按JButtons?
EN

Stack Overflow用户
提问于 2014-05-02 06:45:01
回答 1查看 1.1K关注 0票数 4

我做了一个小康威生命游戏计划。我已经完成了80%。我使用了一个JButtons网格作为单元。现在,我在每个按钮上都有一个ButtonListener,所以你必须一个一个地画出你想要的模式,点击个别的按钮。我想要能够点击和拖动鼠标和选择按钮快速。我使用了MotionListener类,实现了MouseMotionListener,并以与MouseMotionListener类中的actionPerformed方法相同的方式编写了mouseDragged方法。

我认为逻辑应该是一样的,但我肯定遗漏了一些东西。我玩了一会儿,认为它只是选择和取消选择,一遍又一遍,比我能说的更快。我增加了一个检查,以确保它没有试图改变相同的按钮背对背,但这没有帮助。这是我的MotionListener课程:

代码语言:javascript
复制
    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[][]是当前所选内容的布尔映射,我在计算下一步时使用该映射。

对如何纠正我的MotionListener有什么想法吗?对于如何正确实现这个类,我不太了解。我发现的所有简单示例都涉及绘图,但它们似乎都跟踪游标被拖动的Points,并随后更新像素。这是不是我必须用我的纽扣做的事?

*这是MCVE,至少我可以压缩它。*****

代码语言:javascript
复制
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。我另一个在这个问题上挂断我的问题回答说。

代码语言:javascript
复制
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);
}
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-05 14:39:05

我认为您遇到的问题是,您试图使用JButton来做一些设计上不适合做的事情。我将使用一个更简单的控件,比如JLabel,这样您就不会拥有JButton所拥有的所有额外功能。

其次,litSquares数组显然是一个数据簇。您绝对应该创建您自己的自定义控件(可以是extend JComponent控件,也可以是extend JLabel控件),这取决于JLabel是否满足您的需要,其中包含应该与控件本身配对的其他信息。

第三,您可能不希望按钮的状态是boolean,您可能希望它是一个enum.喜欢

代码语言:javascript
复制
public enum State {
    UNLIT, LIT, CURRENTLY_SELECTED;
}

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

最后,正如注释中提到的,使用public Component getComponentAt(int x, int y)可以知道MouseMotionListener被拖到了什么位置,并使用它来更改颜色。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23422313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档