2012-01-25 180 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(); 
      } 
     }); 
    } 
} 

所以基本上我有JPanel的一個子類,其包含在細胞類型它大約500個對象(其是JLayeredPane的的子類)。

基本上,每當用戶點擊其中一個組件時,該組件就會重新組織其圖層並重新繪製自己。

問題是,它有點慢,我不明白爲什麼。在大約50%的情況下,用戶必須多次點擊以使其工作。

也許重繪有問題,或者getComponentAt可能在50%的情況下失敗。我不知道...我不知道如何解決它...請幫助。

+3

*「對不起,這不是實際的代碼,但內容實際的代碼太多,無法舒適地閱讀。「*爲了更快地獲得更好的幫助,請發佈[SSCCE](http://sscce.org/)。 (並給這些班級明智的名字。) –

+1

開始時你可能會開始解釋爲什麼你需要在每次點擊時重新繪製500個對象?我認爲這個問題不在代碼中。 – medopal

+0

@medopal它不重繪所有500個對象。它只重新繪製其中的一個(用戶點擊的那個)。 –

回答

1

如果您閱讀javadoc,repaint()函數會安排重繪發生儘快顯然不是立即的。修改後

立即單元格的內容寫這個功能,如下所示:

cell.paintComponent(cell.getGraphics()); 

這應該立即繪製細胞:)

+0

非常感謝,現在運行速度更快:)。我認爲,如果我可以編寫一個功能完善的自定義方法來替換'getComponentAt',那麼一切都將是完美的。 –

+0

不,這不是如何Swing繪畫應該被觸發... – kleopatra

+0

@kleopatra如果你有更好的解決方案,請張貼:)。 –