2014-09-06 2 views
1

어떤 RadioButton이 선택되어 있는지 (원형, 채워진 원 또는 사각형) 확인하는 프로그램을 작성하고 싶습니다. 그런 다음 사용자가 캔버스 필드를 클릭합니다. 사용자가 클릭 한 좌표를 인식하고 해당 위치에서 라디오 버튼으로 선택된 항목을 그려야합니다.Java 캔버스 클래스가 페인트하지 않습니다

슬프게도 그렇게하지 않습니다. 사실 내 코드는 "ActionListener"에 도달하지 않습니다. 나는 5 번처럼 이미 코드를 검사하고 테스트를했지만 여전히 그것을 파악할 수 없었다.

public class Optionen extends JFrame { 
MeinCanvas drawspace = new MeinCanvas(); 
ButtonGroup btngrp= new ButtonGroup(); 
int xpos, ypos; 

public Optionen(String titel) { 
    super(titel); 
    setLayout(new FlowLayout()); 
    JPanel panel = new JPanel(); 
    panel.setLayout(new GridLayout(3,1,20,20)); 
    JRadioButton opt1 = new JRadioButton(); 
    JRadioButton opt2 = new JRadioButton(); 
    JRadioButton opt3 = new JRadioButton(); 
    opt1.setActionCommand("Kreis"); //circle 
    opt1.setActionCommand("Scheibe"); // filled circle 
    opt1.setActionCommand("Rechteck"); //rectangle 
    opt1.setText("Kreis"); 
    opt2.setText("Scheibe"); 
    opt3.setText("Rechteck"); 
    btngrp.add(opt1); 
    btngrp.add(opt2); 
    btngrp.add(opt3); 
    panel.add(opt1); 
    panel.add(opt2); 
    panel.add(opt3); 


    add(drawspace); 
    add(panel); 
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

} 

public static void main(String[] args) { 
    Optionen fenster = new Optionen("Optionswindow"); 
    fenster.pack(); 
    fenster.setSize(450,500); 
    fenster.setResizable(true); 
    fenster.setVisible(true); 
} 

class MeinCanvas extends Canvas { 
class MeinMausAdapter extends MouseAdapter { 
    public void mousPressed(MouseEvent e) { 
     xpos = e.getX(); 
     ypos = e.getY(); 
     JOptionPane.showInputDialog(this); 
     repaint(); 
    } 
} 

public MeinCanvas() { 
    addMouseListener(new MeinMausAdapter()); 
    setBackground(Color.black); 
    setForeground(Color.orange); 
} 

public void paint(Graphics g) { 
    ButtonModel btnmdl= m_formauswahl.getSelection(); 
    String label = btnmdl.getActionCommand(); 
    int w = (int) (Math.random()*300); 
    int h = (int) (Math.random()*300); 
    if (label.equals("Kreis")) 
     g.drawOval(xpos, ypos, w, w); 
    if (label.equals("Scheibe")) 
     g.fillOval(xpos, ypos, w, h); 
    if (label.equals("Rechteck")) 
     g.drawRect(xpos, ypos, w, h); 
} 
public Dimension getMinimumSize() { 
    return new Dimension(300,300); 
} 
public Dimension getPreferredSize() { 
    return getMinimumSize(); 
} 
} 
} 

이클립스 코드는 괜찮 하더군요 도움이 될 수 있습니다 희망 그런데 프로그램을 실행 할 때마다, 그것은 즉시 예외가 발생합니다.

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
at kapitel10.Optionen$MeinCanvas.paint(Optionen.java:79) 
at sun.awt.RepaintArea.paintComponent(Unknown Source) 
at sun.awt.RepaintArea.paint(Unknown Source) 
at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source) 
at java.awt.Component.dispatchEventImpl(Unknown Source) 
at java.awt.Component.dispatchEvent(Unknown Source) 
at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
at java.awt.EventQueue.access$400(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue$4.run(Unknown Source) 
at java.awt.EventQueue$4.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue.dispatchEvent(Unknown Source) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.run(Unknown Source) 

답변

4

문제 :

  1. 이 (JFrame의) 구성 요소 스윙과 AWT (캔버스) 구성 요소를 혼합하지 마십시오 여기에 덤프입니다. 모든 스윙 구성 요소를 고수하십시오.
  2. 대신 JPanel의 paintComponent 재정의 메서드에서 Swing 그림 자습서에 설명 된대로 그립니다.
  3. 재정의 할 때 super 메소드를 반드시 호출해야합니다.
  4. 대부분의 코드는 페인트 방법이 아니어야 MouseListener 코드에 있어야합니다. GUI가 처음으로 그려지는 경우 JRadioButton이 아직 선택되지 않았으므로 NPE가 표시 될 수 있습니다.
  5. MouseListener에서 ButtonModel 이 null이 아니며인지 확인한 다음 actionCommand를 가져온 다음 paintComponent 메서드에서 사용하는 클래스 필드의 상태를 변경 한 다음 repaint()을 호출합니다.

편집

은 또한 그것은 mousPressed하지만 mousePressed 아니다! 이러한 종류의 오류를 방지하려면 오버라이드 된 모든 메서드 앞에 @Override 주석을 사용해야합니다.

class MeinMausAdapter extends MouseAdapter { 

    @Override // this will cause a compiler error 
    public void mousPressed(MouseEvent e) { // until you fix this spelling! 
     ButtonModel btnmdl = btngrp.getSelection(); 
     if (btnmdl == null) { 
      System.out.println("btn model is null"); 
      return; 
     } 
     actionCmd = btnmdl.getActionCommand(); 
     System.out.println(actionCmd); 
     xpos = e.getX(); 
     ypos = e.getY(); 
     // JOptionPane.showInputDialog(this); 
     repaint(); 
    } 
    } 

또한 : 당신은 명시 적으로 JRadioButton의의 actionCommands를 설정해야합니다. 하나만이 작업을 수행하고 있습니다 JRadioButton - 코드를주의 깊게보십시오.

+0

저는 사람들이 게임에서'JFrame'으로'Canvas'를 자주 사용하는 것을 보았습니다. Swing에서 AWT를 사용하면 안됩니다. 중량이 높고 중량이 각각 1이지만, JFrames가 중량급이라고 들었습니다. 설명해 주시겠습니까? –

+0

제 얼굴을 힘껏 쳐 주실 수 있습니까? 고마워요 호버 크라프트 뱀장어 가득! 때때로 나는 지체감을 느낀다. 내 코드가 완벽하게 작동합니다! 처음에는 무서워서 결국 주말 내내 돌아 다니게되었습니다. 나는 아직 초보자입니다. 다시 한번 고마워! – Cappuccino90