2014-09-06 45 views
1

我想編寫一個程序,它檢查選中哪個RadioButton(圓形,實心圓或矩形)。然後用戶單擊畫布字段上的某個地方。它應該識別用戶點擊的座標,然後在該位置繪製任何選定的單選按鈕。Java Canvas Class不繪畫

不幸的是,它不這樣做。事實上,我的代碼甚至沒有達到「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(); 
} 
} 
} 

Eclipse的告訴我,該代碼是好的,但每當我運行程序時,它會立即拋出異常。下面是轉儲:

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. 不要與Swing(JFrame的)成分混合AWT(Canvas)的部件。堅持所有的Swing組件。
  2. 而是按照Swing繪畫教程中描述的方式繪製 - 在JPanel的paintComponent重寫方法中。
  3. 不要忘記在你的覆蓋中調用超級方法。
  4. 大部分代碼甚至不應該在繪畫方法中,而應該放在MouseListener代碼中。您可能會獲得NPE,因爲在GUI初次繪製時尚未選擇JRadioButton。
  5. 在您的MouseListener中,獲取ButtonModel,檢查它是否爲空,然後獲取actionCommand,然後更改paintComponent方法使用的類字段的狀態,然後調用repaint()

編輯

而且它不是mousPressedmousePressed! 您必須在所有重寫的方法之前使用@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。你只能這樣做one JRadioButton - 仔細看看你的代碼。

+0

我見過人們經常在遊戲中使用'Canvas'和'JFrame'。你不應該在Swing中使用AWT,因爲一個是重量級的,一個是輕量級的,儘管我也聽說JFrames是重量級的。你能解釋一下嗎? – 2014-09-06 02:01:25

+0

你能不能在我的臉上狠狠地打我?非常感謝氣墊船充滿了鰻魚!有時我感覺遲鈍。我的代碼現在完美運行!一開始我很害怕它會讓我整個週末終於開始運行。我仍然是初學者。再次感謝! – Cappuccino90 2014-09-06 11:21:00