2012-04-29 13 views
5

मैं यह कहकर शुरू करना चाहता हूं कि यह एक असाइनमेंट है। मैं नहीं चाहता कि उत्तर चम्मच मुझे खिलाए लेकिन मैं जानना चाहता हूं कि मेरी समस्याएं क्या हो रही हैं।जावा: एक ग्रिड पर एक आयताकार भरना

मैं वर्तमान में Conway's Game of Life को कार्यान्वित कर रहा हूं। सेल को क्लिक करने से रंग बदलना चाहिए, यह दर्शाता है कि उस सेल को जीवित राज्य में स्विच किया जा रहा है। यदि फिर से क्लिक किया गया है, तो इसे डिफ़ॉल्ट रंग में वापस जाना चाहिए।

जब मैं खिड़की में कहीं भी क्लिक करता हूं, तो प्रोग्राम लाइन 56 पर एक नल पॉइंटर अपवाद फेंकता है। आखिरी दिन या उससे भी इस पर अटक गया है, इसलिए किसी भी मदद की सराहना की जाती है। धन्यवाद!

यहाँ कोड:

import java.awt.*; 
import javax.swing.*; 
import java.awt.event.*; 

public class VisibleGrid extends JPanel implements MouseListener, KeyListener{ 

    CellGrid cellGrid; 
    Graphics rect; 

    public VisibleGrid(){ 
    addMouseListener(this); 
    cellGrid = new CellGrid(); 
    } 

    //Draw the grid of cells, 7px wide, 75 times to create 75x75 grid 
    public void paint(Graphics g){ 
    for(int i=0; i<525;i=i+7){ 
     for(int j = 0; j<525; j=j+7){ 
     g.drawRect(i ,j,7,7);  
     } 
    } 
    } 

    //auxillary method called to fill in rectangles 
    public void paint(Graphics g, int x, int y){ 
    g.fillRect(x, y, 7, 7); 
    repaint(); 

    } 

    //main method, adds this JPanel to a JFrame and sets up the GUI 
    public static void main(String[] args){ 
    JFrame j = new JFrame("Conway's Game of Life"); 
    j.setLayout(new BorderLayout()); 
    j.add(new VisibleGrid(), BorderLayout.CENTER); 
    JTextArea info = new JTextArea("Press S to Start, E to End"); 
    info.setEditable(false); 
    j.add(info, BorderLayout.SOUTH); 
    j.setSize(530,565); 
    j.setVisible(true); 
    } 

    //these methods are to satisfy the compiler/interface 
    //Begin Mouse Events 
    public void mouseExited(MouseEvent e){} 
    public void mouseEntered(MouseEvent e){} 
    public void mouseReleased(MouseEvent e){} 
    public void mousePressed(MouseEvent e){} 
    public void mouseClicked(MouseEvent e){ 
    //fill the selected rectangle 
    rect.fillRect(e.getX(), e.getY(), 7,7); 
    repaint(); 

    //set the corresponding cell in the grid to alive 
    int row = e.getY() /7; 
    int column = e.getX() /7; 
    cellGrid.getCell(row, column).setAlive(true); 
    } 
    //End Mouse Events 

//These methods are to satisfy the compiler/interface 
//Begin KeyEvents 
    public void keyReleased(KeyEvent e){} 
    public void keyPressed(KeyEvent e){} 
    public void keyTyped(KeyEvent e){} 



} 
+1

कौन सी लाइन लाइन 56 है? जब मैं कोड कॉपी/चिपकाता हूं, तो यह int कॉलम = e.getX()/7 था; जो सही नहीं दिखता –

+0

मैं शर्त रेखा 56 है _rect.fillRect (e.getX(), e.getY(), 7,7); _ –

+0

जैसा कि @guido कहते हैं, सुनिश्चित करें कि ग्राफिक्स ऑब्जेक्ट, 'rect' इसे एक्सेस करने से पहले प्रारंभ या वैध संदर्भ है। – Rupak

उत्तर

3

समस्या यह है कि आपका rect फ़ील्ड कभी भी कुछ भी सेट नहीं है, इसलिए यह null के रूप में रहता है। कॉलिंग rect.drawRect आपके द्वारा देखे जा रहे NullPointerException का कारण बन जाएगा।

अगर मुझे सही याद है, तो Graphics ऑब्जेक्ट्स स्विंग करना वास्तव में आपको पसंद नहीं करते हैं जब वे आपको कोई चित्रकारी करने की उम्मीद नहीं कर रहे हैं। इसलिए जैसे फ़ील्ड में paint() पर कॉल के दौरान आपको मिलने वाली Graphics ऑब्जेक्ट को छेड़छाड़ करने की सलाह दी जाएगी। यदि आप खिड़की के हिस्से को दोबारा पेंट करना चाहते हैं, तो स्विंग को यह बताने के लिए बेहतर है कि खिड़की के किस हिस्से को पुनर्निर्मित करने की आवश्यकता है और फिर इसे अपने paint() विधि पर कॉल करें।

आपके mouseClicked() विधि के भीतर, मैंने rect.fillRect() पर कॉल हटा दिया और विधि को repaint() पर विधि के अंत में स्थानांतरित कर दिया। यदि सेल जीवित था और अन्यथा एक निर्बाध व्यक्ति था तो मैंने एक भरे आयत को आकर्षित करने के लिए paint() विधि को भी संशोधित किया। ऐसा करने के बाद, आपका कोड काम पर दिखाई दिया, जिसमें मैं कुछ कोशिकाओं पर क्लिक कर सकता था और वे काला हो जाएंगे।

मेरे पास आपके कोड में सुधार के लिए कुछ सुझाव हैं। मैं तुम्हारे लिए पिछले दो अभ्यास के रूप में छोड़ देंगे:

  • मैं main() करने के लिए लाइन j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); जोड़ने की सलाह देते हैं। जब आप विंडो बंद करते हैं तो यह लाइन एप्लिकेशन को ठीक से छोड़ देती है।
  • फिलहाल, आपका कोड हर बार एक सेल में परिवर्तन होने पर पूरे 75 × 75 ग्रिड को पुनर्निर्मित कर रहा है। अपने कोड को बदलना संभव होना चाहिए ताकि यह केवल बदले गए सेल को पश्चाताप कर सके। आप pass a Rectangle to the repaint() method कर सकते हैं, जो स्विंग को बताता है 'केवल मेरे घटक के इस हिस्से को पुनर्निर्मित करने की आवश्यकता है'। paint विधि में, आप the getClipBounds() method of the Graphics class का उपयोग करके इस आयत को पकड़ सकते हैं और यह निर्धारित करने के लिए उपयोग कर सकते हैं कि कौन से सेल या सेल को पुनर्निर्मित करना है।
  • drawRect केवल आयताकार की रूपरेखा तैयार करता है। यदि कोई सेल मर जाता है, तो आपकी paint विधि ग्रिड से मौजूदा काले आयताकार को साफ़ नहीं करेगी। आप मृत कोशिकाओं को एक सफेद रूपरेखा आयत के रूप में शीर्ष पर एक काले रूपरेखा आयताकार के साथ खींचकर इसे ठीक कर सकते हैं।
+0

बहुत उपयोगी उत्तर के लिए बहुत बहुत धन्यवाद! अब मेरे पास गेम का लगभग पूरा कार्यान्वयन है, मुझे वास्तविक गेम के लिए एल्गोरिदम को खत्म करने की आवश्यकता है, लेकिन जीयूआई भाग किया जाता है। फिर से धन्यवाद, आदमी। – NickD720

0

क्या आप वाकई CellGrid वस्तुओं कोशिकाओं से भर दिया गया है कर रहे हैं? मैं कोई जावा विशेषज्ञ नहीं हूं लेकिन मुझे आपके कोड में यह प्रारंभिकरण नहीं दिख रहा है ...

+0

हां, सेलग्रिड ऑब्जेक्ट इसके कन्स्ट्रक्टर में सेल ऑब्जेक्ट्स से भरा हुआ है। मुझे इस कार्यक्रम के जीयूआई हिस्से को अभी पता चला है। धन्यवाद! – NickD720

संबंधित मुद्दे