2014-09-24 6 views
1

JPanel을 사용하여 사각형을 페인트하려고합니다. 문제는 메뉴 항목을 클릭 할 때 새 사각형을 그립니다. 그러나 이것을 할 때 그 부분 만 칠해집니다.버튼에 직사각형 페인트하기 JPanel을 사용하여 클릭하기

rectangleMenuItem.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent event) { 
      squares.addSquare(10, 10, 100, 100); 
     } 
    }); 

이 수행합니다 : 여기가 무슨 뜻입니다

not

을하지만 난의 ActionListener의 squares.addSquare(...) 바깥 둘 때, 그것은 올바른 모양 제공 (그냥 내가하지 그것에)

:

squares.addSquare(10, 10, 100, 100); 
    rectangleMenuItem.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent event) { 
      //nothing on click... 
     } 
    }); 

여기에 올바른 직사각형

enter image description here

내가 ActionListener에 넣을 때 올바르게 그려지지 않는 이유는 무엇입니까? 감사. 그것이 업데이트/당신이 그것을 말할하지 않는 구성 요소를 다시 칠해야 할 때 모르는, 그래서

전체 코드

class UMLWindow extends JFrame { 
Squares squares = new Squares(); 

private static final long serialVersionUID = 1L; 

public UMLWindow() { 
    addMenus(); 
} 

public void addMenus() { 

    getContentPane().add(squares); 
    //squares.addSquare(10, 10, 100, 100); 

    JMenuBar menubar = new JMenuBar(); 

    JMenu file = new JMenu("File"); 
    file.setMnemonic(KeyEvent.VK_F); 

    JMenu shapes = new JMenu("Shapes"); 
    file.setMnemonic(KeyEvent.VK_F); 

    JMenuItem rectangleMenuItem = new JMenuItem("New Rectangle"); 
    rectangleMenuItem.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent event) { 
      squares.addSquare(10, 10, 100, 100); 
     } 
    }); 

    shapes.add(rectangleMenuItem); 

    menubar.add(shapes); 

    setJMenuBar(menubar); 

    setTitle("UML Editior"); 
    setSize(300, 200); 
    setLocationRelativeTo(null); 
} 


} 

class Squares extends JPanel { 
private static final long serialVersionUID = 1L; 

private List<Rectangle> squares = new ArrayList<Rectangle>(); 

public void addSquare(int x, int y, int width, int height) { 
    Rectangle rect = new Rectangle(x, y, width, height); 
    squares.add(rect); 
} 

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    this.setOpaque(true); 
    this.setBackground(Color.WHITE); 
    Graphics2D g2 = (Graphics2D) g; 
    for (Rectangle rect : squares) { 
     g2.draw(rect); 
    } 
} 

} 
+0

@Bene : 답변을 작성하십시오. 베네? 어디 갔니? –

+0

그래, 그게 효과가있어. 그것이 대답이된다면 받아 들일 것입니다 – Harry

+0

@ 해리 베네가 돌아 오지 않는다면, 스스로 대답 해주십시오. –

답변

3

스윙은 수동 렌더링 엔진을 사용합니다. 이것은 그것을 현재의 구성 요소를 알리는 재 페인트 매니저에 요청을하게됩니다

public void addSquare(int x, int y, int width, int height) { 
    Rectangle rect = new Rectangle(x, y, width, height); 
    squares.add(rect); 
    repaint(); 
} 

당신의 addSquare 메소드 내에서 repaint를 호출하여

시작 ... 다시 칠해야합니다.

또한 구성 요소에 대한 크기 힌트를 제공해야하므로 레이아웃 관리자는 크기를 0x0으로 설정해야합니다.

이것은 또한 메인 창에서 pack를 호출 할 수

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

을 의미하고 그것은 것 "팩"자신의 주위에 ... Squares 클래스의 getPreferredSize 메서드를 재정의 고려하고 적절한 기본 크기를 반환 내용, 아주 청초한.

또한 구성 요소 또는 다른 구성 요소의 상태를 변경하거나 추가 repaint 요청을 예약하는 메소드를 호출하지 마십시오. 그러면 리소스 PC를 소진시킬 수있는 무한 루프를 설정할 수 있습니다.

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    // This is bad... 
    //this.setOpaque(true); 
    // This is bad... 
    //this.setBackground(Color.WHITE); 
    Graphics2D g2 = (Graphics2D) g; 
    for (Rectangle rect : squares) { 
     g2.draw(rect); 
    } 
} 

불투명도 및 색상과 같은 것은 페인트 사이클 외부에서 정의되어야합니다. 또한 JPanel에서 확장되는 구성 요소는 기본적으로 불투명합니다.)

+0

도움 주셔서 감사합니다 :) – Harry

+0

@ 해리 걱정하지 마, 유용했기 때문에 기쁘다. – MadProgrammer