2012-01-25 14 views
1

私は、次があります。再描画が遅すぎますか?

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

だから、基本的に、私はそれで(のJLayeredPaneのサブクラスである)型セルの約500のオブジェクトが含まれているのJPanelのサブクラスを持っています。

基本的に、ユーザーがこれらのコンポーネントの1つをクリックするたびに、そのコンポーネントはレイヤーを再構成し、それ自体を再描画します。

問題は、それが遅いと私は理由を理解できないということです。約50%のケースでは、ユーザはそれを動作させるために2回以上クリックしなければならない。

おそらく、再ペイントに問題があるか、または50%のケースでgetComponentAtが失敗する可能性があります。私は知らない...そして私はそれを解決する方法を知らない...助けてください。

+3

*「私はそれが実際のコードではありません申し訳ありませんが、しかし、実際のコードはあまりにも読みにくいです。」*より良いヘルプを早急に入手するには、[SSCCE](http://sscce.org/)を投稿してください。 (そしてクラスに分かりやすい名前を付けてください) –

+1

最初に、クリックごとに500個のオブジェクトを再描画する必要がある理由を説明することから始めます。私は問題がここにコード内にないと思う。 – medopal

+0

@medopalすべての500個のオブジェクトを再ペイントしません。それらのうちの1つ(ユーザーがクリックするもの)のみを再描画します。 –

答えて

1

javadocを読んだら、repaint()関数は、できるだけ早くとなるように再描画をスケジューリングします。これは明らかに即時ではないです。

すぐに示すように、セルの内容は、この関数を記述変更した後:

cell.paintComponent(cell.getGraphics()); 

これはすぐに、セルの内容をペイントする必要があり:)

+0

ありがとう、それは少し速い今実行:)。私は、 'getComponentAt'に取って代わる完全に機能的なカスタムメソッドを書くことができれば、すべてが完璧だと思います。 –

+0

いいえ、それはスイングペインティングが誘発されるべきではありません... – kleopatra

+0

@kleopatraもしあなたがより良い解決策を持っていたら、それを投稿してください:)。 –

関連する問題