Перекраска выполняется слишком медленно? - PullRequest
1 голос
/ 25 января 2012

У меня есть следующее:

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JLayeredPane;
import javax.swing.JFrame;
import javax.swing.BorderFactory;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import java.awt.GridLayout;
import java.awt.Dimension;
import java.awt.Color;
import java.util.Random;

class Cell extends JLayeredPane
{
    private JLabel image1;
    private JLabel image2;
    private JLabel image3;

    private Random rand;

    public static int CELLHEIGHT = 22;
    public static int CELLWIDTH = 22;

    public Cell ()
    {
        setPreferredSize (new Dimension (CELLWIDTH, CELLHEIGHT));
        setOpaque (true);
        setBackground (Color.LIGHT_GRAY);
        setBorder (BorderFactory.createLineBorder (Color.BLACK, 1));
        setBounds (0, 0, CELLWIDTH, CELLHEIGHT);

        image1 = new JLabel (new ImageIcon (getClass ().getResource ("image1.png")));   //size is 20 x 20 pixels
        image2 = new JLabel (new ImageIcon (getClass ().getResource ("image2.jpg")));   //size is 20 x 20 pixels
        image3 = new JLabel (new ImageIcon (getClass ().getResource ("image3.jpg")));   //size is 20 x 20 pixels

        image1.setBounds (0, 0, 20, 20);
        image2.setBounds (0, 0, 20, 20);
        image3.setBounds (0, 0, 20, 20);

        add (image1, new Integer (0));
        add (image2, new Integer (1));
        add (image3, new Integer (2));
    }

    public void updateLayers ()
    {
        removeAll ();   //method from JLayeredPane

        add (image1, new Integer (2));
        add (image2, new Integer (1));
        add (image3, new Integer (0));

        repaint ();
    }
}

class MyPanel extends JPanel
{
    private Cell[][] cells;

    public MyPanel (int cellcount_rows, int cellcount_columns)
    {
        super ();

        setLayout (new GridLayout (cellcount_rows, cellcount_columns, 0, 0));

        cells = new Cell[cellcount_rows][cellcount_columns];    //results in about 500 Cell objects

        for (int i = 0; i < cellcount_rows; i++)
        {
            for (int j = 0; j < cellcount_columns; j++)
            {
                cells[i][j] = new Cell ();

                add (cells[i][j]);
            }
        }
    }
}

class MouseHandler implements MouseListener
{
    private MyPanel panel;

    public MouseHandler (MyPanel panel)
    {
        this.panel = panel;
    }

    public void mouseClicked (MouseEvent e)
    {
        Cell cell = (Cell) panel.getComponentAt (e.getX (), e.getY ());

        if (e.getButton () == MouseEvent.BUTTON1)
        {//some very fast (and irrelevant) cell modification goes here
            cell.updateLayers ();
        }
        else if (e.getButton () == MouseEvent.BUTTON3)
        {//some very fast (and irrelevant) cell modification goes here
            cell.updateLayers ();
        }
    }

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

public class GUI
{
    private JFrame mainframe;
    private MyPanel panel;

    private static final int ROWS = 20;
    private static final int COLS = 25;

    public GUI ()
    {
        mainframe = new JFrame ();
        mainframe.setSize (Cell.CELLWIDTH * COLS + 100, Cell.CELLHEIGHT * ROWS + 100);
        mainframe.setResizable (false);
        mainframe.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
        panel = new MyPanel (ROWS, COLS);

        panel.addMouseListener (new MouseHandler (panel));

        mainframe.setLayout (null);
        panel.setBounds (20, 20, Cell.CELLWIDTH * COLS, Cell.CELLHEIGHT * ROWS);

        mainframe.add (panel);

        mainframe.setVisible (true);    
    }

    public static void main (String[] args)
    {
        javax.swing.SwingUtilities.invokeLater (new Runnable ()
        {
            public void run ()
            {
                GUI t = new GUI ();
            }
        });
    }
}

Так что в основном у меня есть подкласс JPanel, который содержит в себе около 500 объектов типа Cell (который является подклассом JLayeredPane).

В основномкаждый раз, когда пользователь нажимает на один из этих компонентов, этот компонент реорганизует свои слои и перерисовывает сам себя.

Проблема в том, что он довольно медленный, и я не могу понять, почему.Примерно в 50% случаев пользователь должен щелкнуть более одного раза, чтобы он заработал.

Возможно, возникла проблема с перерисовкой или, возможно, сбой getComponentAt в 50% случаев.Я не знаю ... И я не знаю, как ее решить ... Пожалуйста, помогите.

1 Ответ

1 голос
/ 25 января 2012

Если вы читаете javadoc, функция repaint () планирует перерисовку как можно скорее , что, очевидно, не является немедленным.

Сразу после изменения содержимого ячейки напишите эту функцию какпоказано:

cell.paintComponent(cell.getGraphics());

Это должно немедленно нарисовать содержимое ячейки:)

...