如何正确使用的MouseMotionListener至preSS Jbutton中? [英] How to properly use the MouseMotionListener to press JButtons?

查看:138
本文介绍了如何正确使用的MouseMotionListener至preSS Jbutton中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经做人生计划的一小康威游戏。我对80%了。我已经使用 Jbutton将网​​格为单元。现在我有一个 ButtonListener 上的每个按钮,让你有一个接一个通过点击各个按钮画出你想要的图案。我希望能够点击并拖动鼠标,快速地选择按钮。我使用了 MotionListener 类,实施的MouseMotionListener 和codeD上的的mouseDragged 以同样的方式在我的 ButtonListener 类我的的actionPerformed 方法的方法。

我觉得逻辑应该是相同的,但我确实失去了一些东西。我与它起到了一下周围,认为它只是选择和取消选择一遍又一遍,比我可以告诉更快。我添加了一个检查,以确保它没有尝试改变同一按钮背到后面,但没有帮助。这里是我的 MotionListener 类:

 类MotionListener实现的MouseMotionListener {    @覆盖
    公共无效的mouseDragged(的MouseEvent E){
        的for(int i = 0; I<大小;我++){
            对于(INT J = 0; J<大小; J ++){
                如果(e.getSource()==广场[I] [J]){
                    如果(litSquares [I] [J] == FALSE){
                        广场[I] [J] .setBackground(选择);
                        litSquares [I] [J] =真;
                    }其他{
                        广场[I] [J] .setBackground(背景);
                        litSquares [I] [J] = FALSE;
                    }
                }
            }
        }
    }    @覆盖
    公共无效的mouseMoved(的MouseEvent E){
        // TODO自动生成方法存根    }}

我的JButton阵列广场[] [] litSquares [] [] 是一个布尔地图什么是当前选择,我计算了下一个步骤时使用。

如何纠正任何想法,我 MotionListener ?我不理解一些关于如何正确实现这个类。我所有简单的例子找到对付图纸,但他们似乎都事后跟踪分数其中光标拖动和更新像素。那是什么我将不得不与我的按钮莫名其妙地办?

这里是MCVE,或至少小,因为我可以凝结了。

 包extraCredit;
进口java.awt.BorderLayout中;
进口java.awt.Color中;
进口java.awt.GridLayout中;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口java.awt.event.MouseEvent中;
进口java.awt.event.MouseMotionListener;进口的javax.swing *。
进口javax.swing.border.Border;公共类MCVE继承JPanel {    私有静态最后的serialVersionUID长= -8031881678612431401L;    静态的JFrame框架;
    静态的JPanel网格;
    静态的JButton [] []正方形;
    静态布尔[] [] litSquares,boardCopy;
    静态INT大小,boardSize,剔= 1,目标= 100,rateIncrease = 10;
    ButtonListener监听器=新ButtonListener();
    MotionListener mListerner =新MotionListener();
    边境noBorder = BorderFactory.createEmptyBorder();
    彩色背景= Color.BLUE;
    选择= Color.PINK颜色;    公共MCVE(INT大小){
        MCVE.size =大小;
        广场=的新的JButton [大小] [SIZE]
        litSquares =新的布尔[大小] [SIZE]
        格=新JPanel(新网格布局(尺寸,大小));
        的for(int i = 0; I<大小;我++){
            对于(INT J = 0; J<大小; J ++){
                广场[I] [J] =的新的JButton();
                广场[I] [J] .addActionListener(监听);
                //广场[I] [J] .addMouseMotionListener(mListerner);
                广场[I] [J] .setBackground(背景);
                广场[I] [J] .setBorder(noBorder);
                grid.add(方块[I] [J]);
            }
        }        帧=新的JFrame();
        frame.setLayout(新的BorderLayout());
        frame.add(网格,BorderLayout.CENTER);
        frame.setTitle(生活);
        如果(25 *尺寸和LT; 525){
            boardSize = 525;
        }其他{
            boardSize = 25 *的大小;
        }
        frame.setSize(boardSize,boardSize);
        frame.setLocationRelativeTo(NULL);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(真);
    }    类ButtonListener实现的ActionListener {        @覆盖
        公共无效的actionPerformed(ActionEvent的五){
            的for(int i = 0; I<大小;我++){
                对于(INT J = 0; J<大小; J ++){
                    如果(e.getSource()==广场[I] [J]){
                        如果(litSquares [I] [J] == FALSE){
                            广场[I] [J] .setBackground(选择);
                            litSquares [I] [J] =真;
                        }其他{
                            广场[I] [J] .setBackground(背景);
                            litSquares [I] [J] = FALSE;
                        }
                    }
                }
            }
        }
    }    类MotionListener实现的MouseMotionListener {        @覆盖
        公共无效的mouseDragged(的MouseEvent E){
            的for(int i = 0; I<大小;我++){
                对于(INT J = 0; J<大小; J ++){
                    如果(e.getSource()==广场[I] [J]){
                        如果(litSquares [I] [J] == FALSE){
                            广场[I] [J] .setBackground(选择);
                            litSquares [I] [J] =真;
                        }其他{
                            广场[I] [J] .setBackground(背景);
                            litSquares [I] [J] = FALSE;
                        }
                    }
                }
            }
        }        @覆盖
        公共无效的mouseMoved(的MouseEvent E){
            // TODO自动生成方法存根
        }
    }    公共静态无效的主要(字符串ARGS []){
        新MCVE(20);
    }
}

解决方案在,感谢@MadProgrammer和@ durron597。疯狂的回答我的其他<一个href=\"http://stackoverflow.com/questions/23422313/how-to-properly-use-the-mousemotionlistener-to-$p$pss-jbuttons\">question这是挂了我这个问题。

 进口java.awt.BorderLayout中;
进口java.awt.Color中;
进口java.awt.Component中;
进口java.awt.GridLayout中;
进口java.awt.event.MouseListener;
进口java.awt.event.MouseMotionListener;
进口java.util.HashSet中;
进口java.util.Set中;进口的javax.swing *。公共类ChangesAttempt继承JPanel {
私有静态最后的serialVersionUID长= -8031881678612431401L;静态的JFrame框架;
静态的JPanel网格;
静态的JLabel [] []正方形;
静态布尔[] [] litSquares;
静态INT大小,boardSize;
静态布尔的startDrag,产地;
静态设置&lt;成分&GT; compList =新的HashSet&lt;成分&GT;();
听众的MouseEvent =新的MouseEvent();
MotionListener mListerner =新MotionListener();
彩色背景= Color.BLUE;
选择= Color.PINK颜色;公共ChangesAttempt(INT大小){
    ChangesAttempt.size =大小;
    广场=新的JLabel [大小] [SIZE]
    litSquares =新的布尔[大小] [SIZE]
    格=新JPanel(新网格布局(尺寸,大小));
    grid.addMouseMotionListener(mListerner);
    grid.addMouseListener(监听);
    setBoard();    帧=新的JFrame();
    frame.setLayout(新的BorderLayout());
    frame.add(网格,BorderLayout.CENTER);
    frame.setTitle(ChangedLife);
    如果(25 *尺寸和LT; 525)
        boardSize = 525;
    其他
        boardSize = 25 *的大小;
    frame.setSize(boardSize,boardSize);
    frame.setLocationRelativeTo(NULL);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(真);
}一流的MouseEvent实现的MouseListener {    @覆盖
    公共无效鼠标pressed(java.awt.event.MouseEvent中的E){
        的startDrag = TRUE;
    }    @覆盖
    公共无效的mouseClicked(java.awt.event.MouseEvent中的E){
        组件源= e.getComponent()的getComponentAt(e.getPoint());
        的System.out.println(X =+ source.getX()+,Y =+ source.getY());
        的for(int i = 0; I&LT;大小;我++){
            对于(INT J = 0; J&LT;大小; J ++){
                如果(来源==广场[I] [J]){
                    如果(litSquares [I] [J] == FALSE){
                        广场[I] [J] .setBackground(选择);
                        litSquares [I] [J] =真;
                    }其他{
                        广场[I] [J] .setBackground(背景);
                        litSquares [I] [J] = FALSE;
                    }
                }
            }
        }
    }    @覆盖
    公共无效的mouseEntered(java.awt.event.MouseEvent中的E){
    }    @覆盖
    公共无效的mouseExited(java.awt.event.MouseEvent中的E){
    }    @覆盖
    公共无效的mouseReleased(java.awt.event.MouseEvent中的E){
        compList.clear();
    }
}类MotionListener实现的MouseMotionListener {
    @覆盖
    公共无效的mouseDragged(java.awt.event.MouseEvent中的E){
        compList.add(e.getComponent()的getComponentAt(e.getPoint())。);
        updateBoard();
    }    @覆盖
    公共无效的mouseMoved(java.awt.event.MouseEvent中的E){    }
}公共无效setBoard(){
    的for(int i = 0; I&LT;大小;我++){
        对于(INT J = 0; J&LT;大小; J ++){
            广场[I] [J] =新的JLabel();
            广场[I] [J] .setOpaque(真);
            广场[I] [J] .setBackground(背景);
            grid.add(方块[I] [J]);
        }
    }
}公共无效updateBoard(){
    的for(int i = 0; I&LT;大小;我++){
        对于(INT J = 0; J&LT;大小; J ++){
            如果(compList.contains(方块[I] [J])){
                如果(的startDrag){
                    的startDrag = FALSE;
                    起源= litSquares [I] [J]。
                }
                如果(litSquares [I] [J] ==原点){
                    如果(来源)
                        广场[I] [J] .setBackground(背景);
                    其他
                        广场[I] [J] .setBackground(选择);
                    litSquares [I] [J] = litSquares [I] [J]!;
                }
            }
        }
    }
}类MyLabel扩展JLabel {
    私有静态最后的serialVersionUID长= -1414933339546989142L;}公共静态无效的主要(字符串ARGS []){
    新ChangesAttempt(20);
}
}


解决方案

我觉得您遇到的问题是,你正在尝试使用的JButton 的东西它的设计中不具有。我会去一个更简单的控制,如的JLabel ,让你不会有所有的额外功能,的JButton 了。

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

第三,你可能不希望在按钮的状态是一个布尔,你可能希望它是一个枚举 ...像

 公共枚举国家{
    熄灭,点燃,CURRENTLY_SELECTED;
}

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

最后,在评论中所提到的,使用公共组件的getComponentAt(INT X,int y)对要能找出什么的MouseMotionListener 被拖了过来,并用它来改变颜色。

I have made a small Conway Game of Life program. I'm about 80% done. I have used a grid of JButtons as the cells. Right now I have a ButtonListener on every button so you have to one-by-one draw the pattern you want by clicking on individual buttons. I want to be able to click and drag the mouse and select buttons quickly. I used the MotionListener class, implementing the MouseMotionListener and coded the mouseDragged method in an identical fashion as my actionPerformed method in my ButtonListener class.

I thought the logic should be the same but I'm definitely missing something. I played around with it a bit, thinking that it was just selecting and de-selecting over and over faster than I could tell. I added a check to make sure that it did not try and change the same button back-to-back but that did not help. Here is my MotionListener class:

    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

    }

}

My JButton array is squares[][] and the litSquares[][] is a boolean map of what is selected currently, that I use when calculating the next step.

Any ideas on how to correct my MotionListener? I'm not understanding something about how to properly implement this class. All simple examples I find deal with drawing, but they all seem to track the Points where the cursor is dragged and update the pixels afterward. Is that something I will have to do somehow with my buttons?

Here is the MCVE, or at least as small as I could condense it.

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);
    }
}

SOLUTION BELOW, Thanks to @MadProgrammer and @durron597 . Mad answered my other question that was hanging me up on this problem.

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);
}
}

解决方案

I think the problem you're having is that you're trying to use JButton for something it's not designed to do. I would go with a much simpler control, like JLabel, so that you won't have all the extra functionality that JButton has.

Secondly, your litSquares array is clearly a Data Clump. You absolutely should be creating your own custom control (which can either extend JComponent or extend JLabel), depending on whether JLabel meets your needs, that contains the other information that should be paired with the control itself.

Thirdly, you might not want the state of the button to be a boolean, you probably want it to be an enum... like

public enum State {
    UNLIT, LIT, CURRENTLY_SELECTED;
}

so that you can see which components are being newly color-flipped.

Finally, as was mentioned in the comments, use public Component getComponentAt(int x, int y) to be able to figure out what the MouseMotionListener was dragged over, and use that to change the color.

这篇关于如何正确使用的MouseMotionListener至preSS Jbutton中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆