【问题标题】:Java MouseListener MouseClicked only works onceJava MouseListener MouseClicked 只工作一次
【发布时间】:2014-10-07 14:56:49
【问题描述】:

我使用 JPanel 为 Game Of Life 制作 GUI,我的类扩展了 JFrame 并实现了 MouseListener,但是当我点击 JLabel 时,MouseListener 只工作一次。

知道该怎么做吗?这在我的 GameOfLife 类的代码中不是问题,因为我也在尝试打印一些字符串,但它只能工作一次。

谢谢! 这是课程:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;

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


public class GameOfLifeWindow extends JFrame implements ActionListener, MouseListener
{
    private static final int DEF_ROWS = 16;
    private static final int DEF_COLS = 16;
    private JLabel[][] cells;
    GameOfLife gol;
    private JPanel panClear;
    private JPanel panCenter;
    private JPanel panNextGen;
    private JButton nextGen;
    private JButton clear;
    private JMenuBar menuBar;
    private JMenu file;
    private JMenuItem newGame;
    private JMenuItem loadFile;

    public GameOfLifeWindow()
    {
        super("Game Of Life");
        gol = new GameOfLife(DEF_ROWS, DEF_COLS);

        //sets layout and dimension
        this.getContentPane().setLayout(new BorderLayout());
        this.getContentPane().setPreferredSize(new Dimension(300,400));

        //Sets the panels
        panClear = new JPanel(new FlowLayout());
        panCenter = new JPanel(new GridLayout(gol.getRows(), gol.getCols()));
        panNextGen = new JPanel(new FlowLayout());

        //Adds the panel to the JFrame
        this.getContentPane().add(panClear, BorderLayout.NORTH);
        this.getContentPane().add(panCenter, BorderLayout.CENTER);
        this.getContentPane().add(panNextGen, BorderLayout.SOUTH);

        //Sets the next generation button
        this.nextGen = new JButton("Next Generation");
        panNextGen.add(this.nextGen);
        this.nextGen.addActionListener(this);
        //Sets the clear button
        ImageIcon btnIcon = new ImageIcon(getClass().getResource("images/clear.png"));
        Image tmpImg = btnIcon.getImage();
        BufferedImage bi = new BufferedImage(30, 30, BufferedImage.TYPE_INT_ARGB);
        Graphics g = bi.createGraphics();
        g.drawImage(tmpImg, 0, 0, 30, 30, null);
        this.clear = new JButton(new ImageIcon(bi));
        this.clear.addActionListener(this);
        panClear.add(clear);

        //Set the GridLayout
        this.updateGeneration();        

        //Set the mouse listener to each cell
        for(int i = 0 ; i < this.cells.length ; i++)
            for(int j = 0 ; j < this.cells[i].length ; j++)
                this.cells[i][j].addMouseListener(this);

        //Sets MenuBar
        this.menuBar = new JMenuBar();
        this.setJMenuBar(menuBar);

        //Sets the File menu
        this.file = new JMenu("File");
        menuBar.add(file);
        //Sets the New Game in the file
        this.newGame = new JMenuItem("New Game");
        this.newGame.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, InputEvent.CTRL_MASK));
        this.newGame.addActionListener(this);
        file.add(this.newGame);

        //Sets the Load File in the file
        this.loadFile = new JMenuItem("Load File");
        this.loadFile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F2, InputEvent.CTRL_MASK));
        this.loadFile.addActionListener(this);
        file.add(this.loadFile);
    }

    public void updateGeneration()
    //updates the JLabels according to the Game Of Life Screen
    {
        Border border = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
        this.getContentPane().remove(this.panCenter);
        this.panCenter = new JPanel(new GridLayout(gol.getRows(), gol.getCols()));
        this.cells = new JLabel[gol.getRows()][gol.getCols()];
        this.panCenter.removeAll();
        for(int i = 0 ; i < cells.length ; i++)
            for(int j = 0 ; j < cells[i].length ; j++)
            {
                this.cells[i][j] = new JLabel();
                this.cells[i][j] .setOpaque(true); // make the color visible
                this.cells[i][j].setBorder(border);// sets borders
                if(gol.isAlive(i, j))
                    this.cells[i][j].setBackground(Color.BLACK);
                else
                    this.cells[i][j].setBackground(Color.white);
                panCenter.add(this.cells[i][j]);
            }

        this.getContentPane().add(this.panCenter);
        this.setVisible(true);      
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        if(e.getSource() == this.nextGen)
        {
            this.gol.nexGeneration();
            this.updateGeneration();
        }
        else if(e.getSource() == this.clear)
        {
                this.gol = new GameOfLife(DEF_ROWS, DEF_COLS);
                this.updateGeneration();
        }
        else if(e.getSource() == this.newGame)
        {
            this.gol = new GameOfLife(DEF_ROWS, DEF_COLS);
            this.updateGeneration();
        }
        else if(e.getSource() == this.loadFile)
        {
            String fileName = JOptionPane.showInputDialog("Please Enter A File Name");
            this.gol = new GameOfLife(fileName);
            System.out.println(gol.toString());
            this.updateGeneration();
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) 
    {
        boolean found = false;
        for(int i = 0 ; i < cells.length && !found ; i++)
            for(int j = 0 ; j < cells[i].length && !found; j++)
                if(e.getSource() == this.cells[i][j])
                {
                    this.gol.setForGUI(i, j);
                    found = true;
                }
        this.updateGeneration();
        System.out.println("asdsad");
    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }
}

【问题讨论】:

  • 最好使用括号{},即使您不需要它们。
  • 好的,感谢您的建议,您知道代码中可能有什么问题吗?
  • 不知道。你的代码不会编译。它缺少一个类
  • ...还缺少一个主要方法请参阅:sscce.org

标签: java swing mouselistener


【解决方案1】:

在您的构造函数中,您将鼠标侦听器分配给您在JLabel 的多维数组中拥有的所有单元格。但是,然后在您的 updateGeneration() 中创建另一个 JLabel[][] 数组,但不要再次将鼠标侦听器分配给单元格。

要解决此问题,您需要再次为 updateGeneration() 中的所有单元格添加鼠标侦听器。或者不创建新的JLabel[][],只需更新现有数组中JLabel 的状态即可。

【讨论】:

  • 谢谢伙计,祝您度过愉快的一周!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-19
  • 2017-01-06
相关资源
最近更新 更多