سؤال

Java- مرحبا، أنا أكتب برنامجا للألغام (أول biggie) وأنا عالق حقا. يتألف البرنامج نفسه من فئتين (واحد من المنطق، واحد للوجه الوطني) وفقا للمواصفات التي أقوم بها. لقد فعلت بعض الشيء في كلا الفئتين ولكنني لم تنته أيضا. ومع ذلك، أحاول اختبار تنفيذ طرق المكالمات من فئة واحدة إلى أخرى، وهذا هو المكان الذي أشعر به. من فئة واجهة المستخدم الرسومية، أحاول استدعاء الطريقة OpenCell (Int X، Int y) في فئة المنطق في كل مرة ينقر عليها المستخدم في مربع. ستحقق طريقة فئة المنطق هذه بدورها لمعرفة ما إذا كان هناك منجم أو رقم 0 أو رقم في المربع واتصل بالطريقة المناسبة من فئة واجهة المستخدم الرسومية. الأساليب التي تشارك في الخطأ هي كما يلي:

GUI CLASS
public void mouseClicked(MouseEvent e) {
    for (int x = 0 ; x < width ; x++) {
       for (int y = 0 ; y < height ; y++) {
           if (e.getSource() == table[x][y]) {    
                if(e.getButton() == e.BUTTON1) {
                   MinesweeperLogic logicClass = new MinesweeperLogic();
                   logicClass.isOpen(x, y); // <--------------------------- ERROR
                 }}}}}

LOGIC CLASS
boolean openCell(int x, int y) {
isClicked[x][y] = true;
    if(mine[x][y] == true && flag[x][y]==false) {
        return false;
    } else if(neighborBombs(x, y) > 0 && flag[x][y]==false) {
        return true;
    }else {
            marked = true;
            return marked;
    }}

فيما يلي تقرير الخطأ الذي أتلقاه بمجرد النقر فوق المستخدم في المربع في اللعبة (يفعل ذلك للقبض عليه عند تجميع التعليمات البرمجية):

 Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
 at MinesweeperLogic.isOpen(MinesweeperLogic.java:117)
 at MineSweeperGUI.mouseClicked(MineSweeperGUI.java:126)
 at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253)
 at java.awt.Component.processMouseEvent(Component.java:6266)
 at javax.swing.JComponent.processMouseEvent(JComponent.java:3255)
 at java.awt.Component.processEvent(Component.java:6028)
 at java.awt.Container.processEvent(Container.java:2041)
 at java.awt.Component.dispatchEventImpl(Component.java:4630)
 at java.awt.Container.dispatchEventImpl(Container.java:2099)
 at java.awt.Component.dispatchEvent(Component.java:4460)
 at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
 at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4247)
 at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
 at java.awt.Container.dispatchEventImpl(Container.java:2085)
 at java.awt.Window.dispatchEventImpl(Window.java:2475)
 at java.awt.Component.dispatchEvent(Component.java:4460)
 at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
 at  java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
 at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
 at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
 at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
 at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
 at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

أخيرا، كلها بالكامل (غير مكتملة في هذه المرحلة) لرمز فئتين حتى الآن إذا لزم الأمر. (يجب أن تكون الأساليب الموجودة في الفئة المنطقية لتنفيذ إجراءات محددة وفقا لتعليمات المشروع ولا يجب أن لا يكون لديك تفاعل مستخدم في فئة المنطق). لا أستطيع معرفة ما يسبب بالضبط الخطأ. أي ارشاد سوف يكون مشكورا. (نأمل أن الأمر ليس شيئا واضحا حقا كوز قضيته في الساعات الماضية في محاولة لمعرفة ذلك على الرغم من أن إيف حصلت على الأنفلونزا! لول).

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

public class MineSweeperGUI extends JFrame implements ActionListener, MouseListener {  
int width = 10;
int height = 10;
JPanel p = new JPanel();
JButton[][] table = new JButton[width][height];

public void MineSweeper() {
    MinesweeperLogic logicClass = new MinesweeperLogic();
    logicClass.startNewGame(width, height);
    JButton[] button = new JButton[width*height];
    GridLayout layout = new GridLayout (width, height) ;
    p.setLayout(layout);
    for(int x = 0 ; x < width ; x++) {
        for(int y = 0 ; y < height ; y++) {
            table[x][y] = new JButton();
            table[x][y].setPreferredSize(new Dimension(25,25));
            table[x][y].addMouseListener (this);
            p.add(table [x] [y]);
        }
    }       
    this.add(p);
    this.pack();
    this.setVisible(true);
}


public void mouseClicked(MouseEvent e) {
    for (int x = 0 ; x < width ; x++) {
       for (int y = 0 ; y < height ; y++) {
           if (e.getSource() == table[x][y]) {    
                if(e.getButton() == e.BUTTON1) {
                   MinesweeperLogic logicClass = new MinesweeperLogic();
                   logicClass.isOpen(x, y); //<--------------------------------------
               }
           }
       }
   }
 }
public void gameover(int x, int y) {
   table[x][y].setText("*");
}

public static void main(String[]args) {
    MineSweeperGUI guiClass = new MineSweeperGUI();
    guiClass.MineSweeper();
}}    


public void actionPerformed(ActionEvent e) {
}

public void mouseEntered(MouseEvent e) {
}

public void mousePressed(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}

public void mouseReleased(MouseEvent e) {
}




public class MinesweeperLogic {

private int w, h, maxBombs, bombsremaining;
public int width, height;
private boolean mine[][];
private boolean flag[][];
private boolean isClicked[][];
private boolean isZero[][];
private boolean marked;



public void startNewGame(int width, int height) {
    w = width;
    h = height;
    flag = new boolean[w][h];
    isZero = new boolean[w][h];
    isClicked = new boolean[w][h];
    mine = new boolean[w][h];
    maxBombs =(int) Math.floor (width*height*0.15);
    bombsremaining = maxBombs;
    for(int i = 0; i < maxBombs; i++) {
        int x = (int) (Math.random() * (w));
        int y = (int) (Math.random() * (h));
        if (mine[x][y] == false) {
            mine[x][y] = true;
            isClicked[x][y] = false;
            flag[x][y] = false;
        }
    } 
}


int getWidth() {
    return w;
}


int getHeight() {
    return h;
}


boolean openCell(int x, int y) { // <---------------------------------------------
    //MineSweeperGUI guiClass = new MineSweeperGUI();
    isClicked[x][y] = true;
    if(mine[x][y] == true && flag[x][y]==false) {
        //guiClass.gameover(x, y);
        return false;
    } else if(neighborBombs(x, y) > 0 && flag[x][y]==false) {
        return true;
    } else {
            marked = true;
            return marked;
    }}


 boolean markCell(int x, int y) {
     if(flag[x][y] == true) {
            flag[x][y] = false;
            isClicked[x][y] = false;
            bombsremaining++;
            marked = false;
            return marked;
        } else {
            flag[x][y] = true;
            isClicked[x][y] = true;
            bombsremaining--;
                if(mine[x][y]==true) {
                    return true;
                } else {
                    return false;
                }
            }
        }


 boolean isOpen(int x, int y) {
     if(isClicked[x][y] == false) {
         return false;
        } else {
            return true;
        }
}


 boolean isMarked(int x, int y) {
     if(flag[x][y] == true) {
         return true;
        } else {
            return false;
        }
    }


  int getValue(int x, int y) {
      if(mine[x][y] == true) {
          return -1;
        } else {
            return neighborBombs(x, y);
        }
    }


    private int neighborBombs(int x, int y) {  // checks surrounding 8 squares for number of bombs 
        int surBombs = 0;
            for (int q = x - 1 ; q <= x + 1 ; q++) {
                for (int w = y - 1 ; w <= y + 1 ; w++) {
                    while (true) {
                        if (q < 0 || w < 0 || q >= w || w >= h) { 
                            break;
                        }
                        if (mine[q][w] == true) {
                            surBombs++;
                            break;
                        }
                    }   
                }
            }
         return surBombs;
        }
    }
هل كانت مفيدة؟

المحلول

ماذا عن ذلك:

  1. إلقاء نظرة على السطر الأول من استثناءك StackTrace، ومعرفة الفئة والأي خط تحدث المشكلة
  2. انتقل إلى هذا الخط، وأرى الكائنات التي يمكن أن تكون "NULL" في هذا الموقع
  3. تعرف على السبب في أن الكائن الذي لا يحتوي على قيمة ممنوحة
  4. إذا كان هناك أكثر من كائنات واحدة قد تكون فارغة، فيمكنك ذلك System.out.println() لهم، لرؤية whchi واحد هو.

نصائح أخرى

يخبرك StackTrace هذا:

استثناء في الخيط "AWT-EventQueue-0" Java.lang.nullpointerException في Minesweeperlogic.isopen (Minesweeperlogic.java: 117)

حتى تتمكن من الذهاب إلى السطر 117 وتحديد المراجع التي قد تكون فارغة. (يبدو أنك أضفت خطا عند 117 عاما بعد اتخاذ StackTrace، ثم علقت على الخط الجديد، لذلك سأذهب إلى أحد أطرافها هنا وأقول أن StackTrace كان يشير في الواقع إلى ما يسمى الآن الخط 118 في isClicked[x][y] = true;) الشيء الوحيد الذي يمكن أن يكون فارغا، في هذه الحالة، هو isClicked[][].

حفر أعمق قليلا، يمكننا أن نرى أنك تقوم بتهيئة exclicked في startnewgame ()، ولكن من الواضح أن هذه الحالة تضيع. يحدث هذا لسببين: أولا، فإن Logicclass من منشئك يخرج من نطاق لأنه ليس عضوا في الفصل. ثانيا (وهذه ربما كانت محاولة فاشلة لإصلاح المشكلة الأولى)، في mouseClicked, ، يمكنك إنشاء جديد MinesweeperLogic (جنبا إلى جنب مع orclicked nullyed تم إنشاؤها حديثا) بدلا من استخدام الشخص الذي قمت بإنشائه مسبقا MineSweeper() البناء.

هناك العديد من عمليات إعادة الأمواد الأخرى التي يجب عليك القيام بها لتنظيف التعليمات البرمجية الخاصة بك، ولكن جعل Logicclass عضوا وإزالة مثيل النسخ يجب إصلاح المشكلة العاجلة.

قد يكون من المفيد لك استخدام المصحح والخطوة من خلال المشكلة بنفسك لفهم ما يحدث بالضبط.

لا تتم تهيئة المصفوفات (العلم، Iszero، ISClicked) وهي لاغية عند محاولة استخدامها. تحتاج إلى فئة واجهة المستخدم الرسومية لاحتواء مثيل من فئة المنطق وتستخدم دائما نفس المثيل. خلاف ذلك، سيعقد كل عمل واجهة المستخدم الرسومية في لعبة مختلفة!

سيكون من المفيد معرفة ما هو رقم السطر 117 في فئة المنطق. تخميني سيكون كذلك mine, mine[x], flagged أو flagged[x] باطل.

ومع ذلك، فإن أسلوبك من "حلقة" من خلال الجدول بأكمله لمعرفة أي واحد تم النقر عليه "لا تضربني أيضا مستوحاة بشكل خاص.

تحرير: في الواقع، المشكلة هي أن isOpen صفيف فارغة، لأنك قد قمت بمثابة مثيل للفصل فقط.

Edit2: حسنا، لذلك هو أحد تلك التي أدرجتها في البداية. تخميني سيكون كلهم, ، لأنك قد قمت بتنسيق الفئة فقط، وكنت تستخدم منشئ لا شيء افتراضي.

أنت تقول أن الخطأ يحدث في طريقة MouseClicked ()، ومع ذلك يظهر StackTrace بشكل مختلف:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
 at MinesweeperLogic.isOpen(MinesweeperLogic.java:117)
 at MineSweeperGUI.mouseClicked(MineSweeperGUI.java:126)

هذا يقول أن NPE حدث على الخط 117 من minesweeperlogic. استخدم إما المصحح الخاص بك على هذا السطر، أو إدراج عبارات الطباعة للعمل ما هو فارغ، من هناك، يمكنك العمل على السبب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top