Установка цвета фона на JPanel с помощью MouseListener

Я пытаюсь создать симулятор игры жизни:

Мой код в основном состоит из JFrame, содержащего сетку JPanels, и двумерного логического массива соответствующего размера, где каждая JPanel является экземпляром класса, который расширяет JPanel.

Этот класс: инициализирует JPAnel заданным размером, делает его непрозрачным, устанавливает цвет фона (все это работает) и добавляет к нему mouseListener, который изменяет цвет JPanel на основе значения 2d логического массива в соответствующем месте перед переключение значения массива.

Я также передаю логический массив в качестве ссылки, чтобы каждая плитка содержала один и тот же логический массив, и все они могли переворачивать его значения.

По какой-то причине единственный цвет фона, который содержит JPanel, — это тот, который я установил во время инициализации. После этого JPanel не меняет цвет фона, несмотря на то, что mouseListener регистрирует нажатие, и, более того, несмотря на успешный вызов метода repaint(). Может кто-нибудь объяснить, что, черт возьми, происходит? У меня нет ничего для отладки, так как все вроде бы на месте.

(индивидуальная плитка Конвея)

package conweezy;


import java.awt.Color;
import java.awt.event.*;
import javax.swing.*;

public class TheTile extends JPanel implements MouseListener
{
    boolean[][] thearray;
    int xindex;
    int yindex;
    public TheTile(double width, double height, int xloc, int yloc, boolean[][] inputworld, int i, int j)
    {
        super();
        setSize((int)width, (int)height); setLocation(xloc, yloc); 
        thearray = inputworld; xindex = i; yindex = j; setLayout(null); 
        setOpaque(true);
        if(!thearray[xindex][yindex])
        {               
            setBackground(Color.BLACK);
        }
        if(thearray[xindex][yindex])
        {                
            setBackground(Color.WHITE);
        }
        setVisible(true);
        //addMouseListener(this);       
    }        

    public void mousePressed(MouseEvent e)
    {
        if(!thearray[xindex][yindex])
        {                
            setBackground(Color.WHITE);
            System.out.println(xindex + " " + yindex);
            repaint();                
        }
        if(!thearray[xindex][yindex])
        {
            setBackground(Color.BLACK);
            repaint();                
        }
        thearray[xindex][yindex] = !thearray[xindex][yindex];
        repaint();            
    }

    public void mouseClicked(MouseEvent e)
    {            
    }

    public void mouseReleased(MouseEvent e)
    {            
    }

    public void mouseEntered(MouseEvent e)
    {            
    }
    public void mouseExited(MouseEvent e)
    {            
    }
}

.

(The Conway Grid):


package conweezy;
import java.awt.Event.*;
import java.awt.event.*;
import javax.swing.*;
public class TheUniverseFrame extends JFrame implements ActionListener
{
    public static boolean[][] universalframe;
    public TheTile[][] universaltiles;
    boolean threadstate = false;
    TheUniverseFrame(double xsize, double ysize, int tilexcount, int tileycount)
    {
        //set constants
        setTitle("Welcome to the Game of Life: Datatronic Existence");
        universalframe = new boolean[tilexcount][tileycount];
        universaltiles = new TheTile[tilexcount][tileycount];
        setSize((int)xsize+100, (int)ysize);
        setLayout(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);            
        //initialize tiles and boolean array
        int i = 0;
        int j;
        setVisible(true);
        while(i < tilexcount)
        {
            j = 0;
            while(j < tileycount)
            {
                universalframe[i][j] = false;
                universaltiles[i][j] = new TheTile(xsize/((double)tilexcount), //tile width
                                                   ysize/((double)tileycount), //tile height
                                                   (int)(xsize/((double)tilexcount))*i, //tile x position
                                                    (int)(ysize/((double)tileycount))*j, //tile y position
                                                    universalframe, //boolean array
                                                     i, j); //tile position on array
                try
                {
                    Thread.sleep(0);
                }
                catch(InterruptedException e)
                {

                }
                //universaltiles[i][j].addMouseListener(universaltiles[i][j]);

                add(universaltiles[i][j]);
                repaint();
                j++;
            }
            i++;
        }            
        setVisible(true);
    }

    public void actionPerformed(ActionEvent e)
    {

    }
}

Основной класс:

package conweezy;


public class Conweezy 
{


    public static void main(String[] args) 
    {
        TheUniverseFrame theGame = new TheUniverseFrame(500,500,20,20);
    }

}

person frogeyedpeas    schedule 15.01.2014    source источник


Ответы (1)


Вот рабочий вариант вашего примера, который переключает цвет фона пикселя при нажатии. Примечание,

  • Используйте invokeLater() для запуска в EDT.

  • Не забудьте pack() закрывающую рамку.

  • Позвоните setVisible() один раз.

  • Переопределите getPreferredSize(), чтобы установить размер плитки.

изображение

Как проверено:

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 javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JPanel;

public class Conweezy {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                TheUniverseFrame theGame = new TheUniverseFrame(500, 500, 20, 20);
            }
        });
    }

    private static class TheUniverseFrame extends JFrame {

        public static boolean[][] universalframe;
        public TheTile[][] universaltiles;
        boolean threadstate = false;

        TheUniverseFrame(double xsize, double ysize, int tilexcount, int tileycount) {
            //set constants
            setTitle("Welcome to the Game of Life: Datatronic Existence");
            universalframe = new boolean[tilexcount][tileycount];
            universaltiles = new TheTile[tilexcount][tileycount];
            setLayout(new GridLayout(tilexcount, tileycount));
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            //initialize tiles and boolean array
            int i = 0;
            int j;
            while (i < tilexcount) {
                j = 0;
                while (j < tileycount) {
                    universalframe[i][j] = false;
                    universaltiles[i][j] = new TheTile(xsize / ((double) tilexcount), //tile width
                        ysize / ((double) tileycount), //tile height
                        (int) (xsize / ((double) tilexcount)) * i, //tile x position
                        (int) (ysize / ((double) tileycount)) * j, //tile y position
                        universalframe, //boolean array
                        i, j); //tile position on array
                    add(universaltiles[i][j]);
                    j++;
                }
                i++;
            }
            pack();
            setVisible(true);
        }
    }

    private static class TheTile extends JPanel {

        boolean[][] thearray;
        int xindex;
        int yindex;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(25, 25);
        }

        public TheTile(double width, double height, int xloc, int yloc, boolean[][] inputworld, int i, int j) {
            thearray = inputworld;
            xindex = i;
            yindex = j;
            setOpaque(true);
            setBackground(Color.BLACK);
            addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    thearray[xindex][yindex] = !thearray[xindex][yindex];
                    if (thearray[xindex][yindex]) {
                        setBackground(Color.WHITE);
                    } else {
                        setBackground(Color.BLACK);
                    }
                    repaint();
                    System.out.println(xindex + " " + yindex);
                }
            });
        }
    }
}
person trashgod    schedule 15.01.2014
comment
Удаление лишних параметров xsize и ysize, оставленных в качестве упражнения по рефакторингу. - person trashgod; 16.01.2014