2016-06-11 2 views
-1

최근 JLabel 행렬을 포함하는 JPanel과 관련된 프로젝트를 마쳤습니다. 각 행에는 사용자가 원하는대로 활성/비활성 상태가되기 위해 자체 MouseListener가 추가되었습니다. 프로젝트가 진행되었지만 프로젝트가 구형 컴퓨터에서 매우 느리다는 불만을 받았다. 나는 그렇게했던 방식이 쉽지 만 무섭게 비효율적이라는 것을 알고있다. 여기에 내가 쓴 코드의 단순화 된 버전입니다 :JLabel 행렬을 그래픽 디스플레이로 변환

import java.awt.*; 
import javax.swing.*; 
import java.awt.event.*; 
public class LifeDriver { 
    public static void main(String[] args) { 
     JFrame frame = new JFrame("Test"); 
     frame.setSize(950, 850); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setContentPane(new LifePanel(40, 50)); 
     frame.setVisible(true); 
    } 
} 
class LifePanel extends JPanel { 
    private Cell[][] grid; 
    private static int nR, nC; 
    public LifePanel(int row, int column) { 
     nR = row; 
     nC = column; 
     grid = new Cell[row][column]; 
     setLayout(new GridLayout(row, column, 1, 1)); 
     for (int r = 0; r < row; r++) 
     for (int c = 0; c < column; c++) 
     { 
      grid[r][c] = new Cell(); 
      add(grid[r][c]); 
     } 
    } 
} 
class Cell extends JLabel 
{ 
    private boolean alive; 
    private static boolean mouseDown; 
    public Cell() { 
     setOpaque(true); 
     addMouseListener(new Mouse()); 
     kill(); 
    } 
    public void revive() { 
     setAlive(true); 
    } 
    public void kill() { 
     setAlive(false); 
    } 
    public void setAlive(boolean arg) { 
     alive = arg; 
     if (arg) 
     setBackground(Color.RED); 
     else 
     setBackground(Color.WHITE); 
    } 
    private class Mouse extends MouseAdapter { 
     public void mousePressed(MouseEvent e) { 
     mouseDown = true; 
     if (alive) 
      kill(); 
     else 
      revive(); 
     } 

     public void mouseReleased(MouseEvent e) { 
     mouseDown = false; 
     } 

     public void mouseEntered(MouseEvent e) { 
     if (mouseDown) 
      if (alive) 
       kill(); 
      else 
       revive(); 
     } 
    } 
} 

것은 내가 getX()getY()를 사용하여 돌아가서 내가 LifePanel 하나의 MouseListener을 가지고 있으므로이를 변경하려면이 클릭 된 "셀"결정 (더 이상 JLabel을 확장하지 않음) 셀의 색상을 변경 한 다음 패널에 페인트합니다. 같은 뭔가 :

class LifePanel extends JPanel { 
    BufferedImage myImage; 
    Graphics g; 
    ... 
    class Mouse extends MouseAdapter { 
     public void mousePressed(MouseEvent e) { 
     grid[someRow][someColumn].draw(g) //use e.getX() and e.getY() 
     } 
     public void mouseEntered(MouseEvent e) { 
     //similar to above 
     } 
    } 
} 

class Cell { 
    //other methods 
    public void draw(Graphics g) { 
     g.setColor(myColor); 
     g.fillRect(someX, someY, someWidth, someHeight); 
    } 
} 

어떻게 그 마우스 클릭은 원래의 코드와 같은 결과를 초래하므로 적절한 값이 두 상황에서 사용하는 결정 것인가?

답변

2

2D 배열이 필요하지 않습니다.

대신 Cell 개체가 포함 된 ArrayList을 사용합니다. 셀이

  • 셀의 색상이 그려진 색칠 할 위치의 크기/위치를 나타 내기 위해

    1. Rectangle 객체 다음 Cell 객체는 두 가지 속성을 포함 할 수 있습니다.

    그러면 패널의 사용자 정의 페인팅 코드가 단순히 ArrayList를 반복하고 각 셀을 페인트합니다.

    MouseListener의 경우 마우스 클릭 포인트를 얻고 ArrayList를 반복하고 Rectangle.contains (...) 메서드를 사용하여 셀에 마우스 포인트가 있는지 확인합니다. 적절한 셀을 발견하면 처리합니다.

    Draw On Component 예 : Custom Painting Approaches을 확인하십시오. 이 방법을 사용하여 그림을 그리는 개념을 보여줍니다. 마우스 처리를위한 고유 한 코드를 추가해야합니다.

  • +0

    멋진 아이디어! 나는 이것을 확실히 살펴볼 것입니다. – RobotKarel314

    +0

    오! 나는 무엇이 잘못되었는지 알아 냈다. 내가 패널에서 그린 것처럼 BufferedImage의 크기를 조정하고있었습니다. 내가 요청한 이유는 지난 번 시도한 getX() 및 getY()가 꺼져 있었기 때문입니다. 나는 왜 지금 당장 지 알 수있다. 그러나 Rectangle suggestion- 내 코드를 정리하는 데 도움이된다고 생각합니다. 게다가, 그것은'getRect()'를 말할 이유를 주었다. – RobotKarel314