【问题标题】:How to pass an int from one class to another and specify 2 lists with that, without getting a NullPointerException? [duplicate]如何将一个 int 从一个类传递到另一个类并指定 2 个列表,而不会得到 NullPointerException? [复制]
【发布时间】:2015-05-18 22:04:12
【问题描述】:

[编辑]:我现在将把我所有的代码插入其中,因为我越来越绝望,我不知道如何解决我的问题。不仅如此,在我看来(从早期的 cmets 来看),查看整个代码可能对那些试图帮助我解决这个问题的优秀人士有所帮助。

[原帖开始]: 我目前正在 Eclipse 中制作一个游戏来为学校练习。但是,我有 2 个我似乎无法弄清楚的问题(至少其中一个),我真的可以使用一些帮助。

我有一个包含 3 个类的项目; main 创建了一个框架,仅此而已。第二个类创建一个带有组件的面板并使用 JTextField 从用户那里获取一个数字;这个数字在 1 到 20 之间,据我所知,我可以捕捉到任何异常。那里没有问题。 第三类是第二个面板,其中包含通过单击“继续”打开的组件。我现在需要做的是两件事——这些也是我的问题。 1:我需要将指定的数字(它已经转换为 int)从类 2 传递到类 3。 2:我需要添加 2 个列表,大小由数字指定。

我相信我在尝试了 5 个小时后解决了问题 1,但我没有看到快速的检查方法,所以我继续处理问题 2,在单击“继续”后,我的第三堂课导致程序崩溃并抛出 NullPointerException。我知道这与列表有关,但我无法终生找出问题所在!

下面是一些代码:

第 1 类:

package gedigitaliseerd;

import javax.swing.JFrame; //javax = java extra
public class StartFrame extends JFrame //zeg dat het een systeemklasse is.

{ 
public StartFrame() //constructor
{
    setSize(400, 250);  //bepaal de grootte
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //met dit is afsluiten van een progje nooit een probleem
    setTitle("Game 2-cousins"); //geef een titel mee in de titelbalk
    setResizable(false); //nu kan de gebruiker het venster niet vergroten of verkleinen

    //centreer het frame op je monitor
    setLocationRelativeTo(null);

    //hoe laadt je het paneel in het frame?
    //maak een paneelklasse om dat te doen
    //dit is dus om een koppeling te maken tussen frame en paneel
    add(new StartFramePaneel(this /* deze this is nodig voor het paneel en het sluiten van dit frame. this is de class waar hij op dit moment in zit*/)); //waarom ook alweer al die haken?

    setVisible(true);
}

public static void main(String[] args) //main method
{
    new StartFrame(); //maak nieuw object. je hoeft niet te zeggen frame pietje is new frame. je hoeft geen naam te gebruiken

}

}
// header, constructor, de rest. is makkelijker voor het oog

[整个类现在]底部的类2(StartFramePaneel)方法,aantalCharacters是需要传递的。发生在ActionEvent 中的解析不包含在我下面粘贴的内容中,因为它解析没有问题。我什至可以弹出一个窗口,询问您是否希望继续使用指定数量的字符;如果您单击继续按钮。如果您然后单击“是”,没有我所有的传递和列出的东西,它会很好地显示下一个面板,但是如果我添加我在下面粘贴的所有东西,它会在继续后崩溃->是 包gedigitaliseerd;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; //voor eventafhandeling

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class StartFramePaneel  extends JPanel implements ActionListener
{

private JTextField invoerVeld; //goede naamgeving is heel belangrijk
private JLabel vraagVeld1;
private JLabel vraagVeld2;
private JButton rulesButton;
private JButton stopButton;
private JButton continueButton;
private JPanel gridPanel1;
private JPanel gridPanel2;
private JFrame errorFrame;
private JFrame areUSureFrame;
private JFrame main; //nieuw JFrame met de naam main. voor het sluiten van de main OpstartFrame
private JFrame selectionFrame;
private int continueVraag;
private int stopVraag;
public static int aantalCharacters = 0;

//constructor
public StartFramePaneel(JFrame main)
{
    setLayout(new GridLayout(2,1)); //verander de layoutmanager naar GridLayout, van 3x3 even grote cellen
    //setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); //laat de Grid opvullen van 1,1 naar 1,2 naar 1,3 naar 2,1 etc

    //initialiseren (stappenplan punt 2)
    this.main = main; //de mainframe wordt nu toegekend aan de thispanel in de hoofdklasse.

    stopButton = new JButton ("Stop");
    stopButton.addActionListener(this); //(stappenplan punten 3 en 4; this geeft aan dat dit kopieerpaneel hem afhandeld.)

    rulesButton = new JButton ("Rules");
    rulesButton.addActionListener(this);

    continueButton = new JButton ("Continue");
    continueButton.addActionListener(this); //"this" betekent dat dit paneel de zaken afhandeld

    //initialisatie
    invoerVeld = new JTextField(5); //13 is maximale aantal karakters... meestal werkt dat zo. het is in kolommen. een tekst in quites kun je er ook in neerzetten.
    invoerVeld.setHorizontalAlignment(JTextField.CENTER); //centreer de text in het invoerveld

    vraagVeld1 = new JLabel("How many characters between 1 and 20 should each player have?");
    vraagVeld1.setHorizontalAlignment(JLabel.CENTER); //centreer de JLabel in de layout
    vraagVeld2 = new JLabel("(If you don't specify a number, 1 will be the default value)");
    vraagVeld2.setHorizontalAlignment(JLabel.CENTER); 

    gridPanel1 = new JPanel(new GridLayout(3,1)); //object gridPanel1 aanmaken, met dezelfde GridLayout als het hoofdpaneel
    gridPanel2 = new JPanel(new GridLayout(1,3));

    //zichtbaar maken op het eerste (hoofd)paneel .. een paneel heeft een default en een FlowLayout, nu een GridLayout
    add (gridPanel1); //in grid rij 1
    add (gridPanel2); //in grid rij 2

    //voeg Label en TextField toe aan gridPanel1
    gridPanel1.add(vraagVeld1);
    gridPanel1.add(vraagVeld2);
    gridPanel1.add(invoerVeld);

    //voeg de knoppen toe aan gridPanel2
    gridPanel2.add (stopButton);
    gridPanel2.add (rulesButton);
    gridPanel2.add (continueButton);
}

//Deze methode MOET opgenomen worden, omdat er gebruik wordt gemaakt van een ActionListener
public void actionPerformed (ActionEvent ae)
{
    if (ae.getSource() == continueButton)
    {

        try //maak een 'try' blokje aan om ongeldige invoeren tegen te gaan. 
        {
            aantalCharacters = Integer.parseInt(invoerVeld.getText()); //het aantal karakters wordt in aantalCharacters opgeslagen, 
            //wanneer op continue wordt geklikt. Ook wordt de text eerst in een nummer omgezet
        }
        catch (NumberFormatException ongeldigeInvoer) //specificeer de exception voor ongeldige invoer
        {
            //JOptionPane.showMessageDialog(errorFrame, "You must use numbers"); //maak een error aan, zodat het progje niet crasht
            invoerVeld.setText("");
            aantalCharacters = 1;
        }
        if (invoerVeld.getText() == "0" || aantalCharacters == 0)
        {
            JOptionPane.showMessageDialog(errorFrame, "You must use numbers between 1 and 20");
            invoerVeld.setText("");
        }
        else if (invoerVeld.getText() == "" || aantalCharacters == 0)//hier zit het probleem
        {
            invoerVeld.setText("");
            aantalCharacters = 0;
            //JOptionPane.showMessageDialog(errorFrame, "You must use numbers between 1 and 20");
        }
        else if (aantalCharacters < 1 || aantalCharacters > 20)
        {
            JOptionPane.showMessageDialog(errorFrame, "You must use numbers between 1 and 20"); //maak een error aan, zodat het progje niet crasht
            invoerVeld.setText("");
            aantalCharacters = 0;
        }
        else 
        {//hier wordt er een are you sure neergezet, met een actie die volgt op een ja-optie
            continueVraag = JOptionPane.showConfirmDialog(areUSureFrame, "Are you sure you want to continue? You selected "+ aantalCharacters + " character(s)");
            if (continueVraag == JOptionPane.YES_OPTION)
            {
                main.setVisible(false); //main is de thispanel in de hoofdklasse en beide worden ze onzichtbaar... geloof ik
                selectionFrame = new JFrame();
                selectionFrame.setSize(1000, 600);
                selectionFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                selectionFrame.setLocationRelativeTo(null);
                selectionFrame.setTitle("Game 2-cousins");

                selectionFrame.add(new SelectionFramePaneel());

                selectionFrame.setVisible(true);
            }
            if (continueVraag == JOptionPane.NO_OPTION)
            {
                invoerVeld.setText("");
            }
            if (continueVraag == JOptionPane.CANCEL_OPTION)
            {
                invoerVeld.setText("");
            }
        }           

        //lege vakjes moeten natuurlijk ingevuld zijn!
        //nu moet StartFrame sluiten
        //nu moet SelectionFrame opstarten
    }

    if (ae.getSource() == rulesButton)
    {
        //hier moet iets met de regelknop worden gedaan. Een nieuw frame met regels moet toevoorschijn komen. Die heb ik nog niet gemaakt.
    }

    if (ae.getSource() == stopButton)
    {
        /*stopVraag = JOptionPane.showConfirmDialog(areUSureFrame, "Are you sure you want to exit?");
        if (stopVraag == JOptionPane.YES_OPTION)
        {
            */System.exit(0); //het programma sluit af door op 'Stop' the drukken
        /*}
        if (continueVraag == JOptionPane.NO_OPTION)
        {
            invoerVeld.setText("");
        }
        if (continueVraag == JOptionPane.CANCEL_OPTION)
        {
            invoerVeld.setText("");
        }*/
    }

}
public static void passCharacters(int aantalCharacters) //maak passCharacters aan, zodat deze aangeroepen kan worden in de 3e class
{
    int passCharacters = 0;
    passCharacters = aantalCharacters;
}

}

[现在整个第 3 类] 第 3 类 (SelectionFramePaneel) 声明(不是全部)

package gedigitaliseerd;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; //voor eventafhandeling

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;

public class SelectionFramePaneel  extends JPanel implements ActionListener
{
//declareer de componenten (stappenplan punt 1)
private JButton rulesButton;
private JButton stopButton;
private JButton continueButton;
private JCheckBox evenTheFieldP1;
private JCheckBox evenTheFieldP2;
private JPanel northPanel;
private JPanel southPanel;
private JPanel centerPanel;
private JPanel eastPanel;
private JPanel westPanel;
private JLabel player1Label;
private JLabel player2Label;
private JButton player1DiceButton;
private JButton player2DiceButton;
private JLabel player1DiceLabel;
private JLabel player2DiceLabel;
private JLabel dummyLabel1;
private JLabel dummyLabel2;
private JLabel dummyLabel3;
private JList<String> player1List;
private JList<String> player2List;
private static String[] characterArray;
private JLabel kant;
private JLabel ras;
private JLabel basisCharacter;
private JLabel speciaalCharacter1;
private JLabel speciaalCharacter2;
private JLabel speciaalCharacter3;
private JLabel extraVeld1;
private JLabel extraVeld2;
private JLabel extraVeld3;
private JLabel extraVeld4;
private int stopVraag;
private int continueVraag;
public static int gekregenCharacters;
public static int index;

public static void newStartFramePaneel() //maak methode voor het startframepaneel, om passCharacters aan te roepen.
{
    StartFramePaneel.passCharacters(gekregenCharacters);
    //int gezetteCharacters = gekregenCharacters; //hopelijk krijgt gekregenCharacters hier de waarde van aantalCharacters mee
    characterArray = new String[gekregenCharacters];

    for (int fill = 0; fill < gekregenCharacters; fill++)
    {
        characterArray[index]="Character "+index+1;
        index++;
    }
}

//constructor
public SelectionFramePaneel()
{
    setLayout(new BorderLayout()); //verander de layoutmanager naar GridLayout, van 3x3 even grote cellen
    //setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); //laat de Grid opvullen van 1,1 naar 1,2 naar 1,3 naar 2,1 etc

    //initialiseren (stappenplan punt 2)    
    stopButton = new JButton ("Stop")
    {
        public Dimension getPreferredSize()
        {
            return new Dimension(200,100);
        }
    };
    stopButton.addActionListener(this); //(stappenplan punten 3 en 4; this geeft aan dat dit kopieerpaneel hem afhandeld.)

    rulesButton = new JButton ("Rules")
    {
        public Dimension getPreferredSize()
        {
            return new Dimension(200,100);
        }
    };
    rulesButton.addActionListener(this);

    continueButton = new JButton ("Continue")
    {
        public Dimension getPreferredSize()
        {
            return new Dimension(200,100);
        }
    };
    continueButton.addActionListener(this); //"this" betekent dat dit paneel de zaken afhandeld

    player1Label = new JLabel ("Player 1");
    player1Label.setHorizontalAlignment(JLabel.CENTER);

    player2Label = new JLabel ("Player 2");
    player2Label.setHorizontalAlignment(JLabel.CENTER);

    player1DiceLabel = new JLabel ("0");
    player1DiceLabel.setHorizontalAlignment(JLabel.CENTER);

    player2DiceLabel = new JLabel ("0");
    player2DiceLabel.setHorizontalAlignment(JLabel.CENTER);

    dummyLabel1 = new JLabel ("");
    dummyLabel2 = new JLabel ("");
    dummyLabel3 = new JLabel ("");

    player1DiceButton = new JButton ("P1 Roll Dice")
    {
        public Dimension getPreferredSize()
        {
            return new Dimension(100,50);
        }
    };
    player1DiceButton.addActionListener(this);

    player2DiceButton = new JButton ("P2 Roll Dice")
    {
        public Dimension getPreferredSize()
        {
            return new Dimension(100,50);
        }
    };
    player2DiceButton.addActionListener(this);

    evenTheFieldP1 = new JCheckBox ("Even the playing field P1");

    evenTheFieldP2 = new JCheckBox ("Even the playing field P2");
    evenTheFieldP2.setHorizontalTextPosition(SwingConstants.LEFT);
    evenTheFieldP2.setHorizontalAlignment(SwingConstants.RIGHT);

    player1List = new JList<String>(characterArray); //maak de lijsten aan met (hopelijk) de arrays van grootte aantalCharacters->gekregenCharacters
    player1List.setVisibleRowCount(10); //zorg dat er standaard 10 regels in del ijsten te zien zijn
    player1List.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //zorg dat altijd maar 1 element geselecteerd kan worden

    player2List = new JList<String>(characterArray);
    player2List.setVisibleRowCount(10);
    player2List.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

    extraVeld1 = new JLabel();
    extraVeld2 = new JLabel();
    extraVeld3 = new JLabel();
    extraVeld4 = new JLabel();

    kant = new JLabel("Side");
    kant.setHorizontalAlignment(JLabel.CENTER);

    ras = new JLabel("Category");
    ras.setHorizontalAlignment(JLabel.CENTER);

    basisCharacter = new JLabel("Character");
    basisCharacter.setHorizontalAlignment(JLabel.CENTER);

    speciaalCharacter1 = new JLabel("");
    speciaalCharacter1.setHorizontalAlignment(JLabel.CENTER);

    speciaalCharacter2 = new JLabel("");
    speciaalCharacter2.setHorizontalAlignment(JLabel.CENTER);

    speciaalCharacter3 = new JLabel("");
    speciaalCharacter3.setHorizontalAlignment(JLabel.CENTER);

    northPanel = new JPanel(new GridLayout(3,3));
    southPanel = new JPanel(new GridLayout(1,5));
    centerPanel = new JPanel(new GridLayout(6,1));
    eastPanel = new JPanel(new GridLayout(3,1));
    westPanel = new JPanel(new GridLayout(3,1));

    southPanel.setSize(999,150);
    northPanel.setSize(999,150); //deze grootte aanpassen als het scherm vergroot wordt.

    add (northPanel, BorderLayout.NORTH); //een grid met nieuwe panels, met daarin de dobbelsteenvakjes en player labels en Roll Dice knoppen gaan hierin
    add (southPanel, BorderLayout.SOUTH); //de knoppen gaan hierin
    add (centerPanel, BorderLayout.CENTER); //de selectionlabels gaan hierin
    add (eastPanel, BorderLayout.EAST); //het selectievak met aantal characters voor player 2 gaat hierin
    add (westPanel, BorderLayout.WEST); //het selectievak met aantal characters voor player 1 gaat hierin

    northPanel.add(player1Label);
    northPanel.add(dummyLabel1);
    northPanel.add(player2Label);
    northPanel.add(player1DiceLabel);
    northPanel.add(dummyLabel2);
    northPanel.add(player2DiceLabel);
    northPanel.add(player1DiceButton);
    northPanel.add(dummyLabel3);
    northPanel.add(player2DiceButton);

    southPanel.add(evenTheFieldP1);
    southPanel.add(stopButton);
    southPanel.add(rulesButton);
    southPanel.add(continueButton);
    southPanel.add(evenTheFieldP2);

    westPanel.add(player1List);
    westPanel.add(extraVeld1);
    westPanel.add(extraVeld2);
    eastPanel.add(player2List);
    eastPanel.add(extraVeld3);
    eastPanel.add(extraVeld4);

    centerPanel.add(kant);
    centerPanel.add(ras);
    centerPanel.add(basisCharacter);
    centerPanel.add(speciaalCharacter1);
    centerPanel.add(speciaalCharacter2);
    centerPanel.add(speciaalCharacter3);
}

//Deze methode MOET opgenomen worden, omdat er gebruik wordt gemaakt van een ActionListener
public void actionPerformed (ActionEvent ae)
{
    if (ae.getSource() == continueButton)
    {

    }

    if (ae.getSource() == rulesButton)
    {
        //hier moet iets met de regelknop worden gedaan. Een nieuw frame met regels moet toevoorschijn komen. Die heb ik nog niet gemaakt.
    }

    if (ae.getSource() == stopButton)
    {
        /*stopVraag = JOptionPane.showConfirmDialog(areUSureFrame, "Are you sure you want to exit?");
        if (stopVraag == JOptionPane.YES_OPTION)
        {
            */System.exit(0); //het programma sluit af door op 'Stop' the drukken
        /*}
        else
        {

        }*/
    }

}

}

【问题讨论】:

  • 只保留堆栈跟踪的前三行,然后发布整个构造函数。
  • 我宁愿将堆栈跟踪的另外 3 行从它到达您的一个类的位置放置。仅显示 Java 核心类的堆栈跟踪并没有那么有用...无论如何,您在哪里初始化 characterArray 变量?,您没有在构造函数中执行它,并且您的声明 private static String[] characterArray; 意味着它是 null。跨度>
  • 你的意思是...at gedigitaliseerd.StartFramePaneel.actionPerformed(StartFramePaneel.java:132) at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)???

标签: java arrays list class


【解决方案1】:

您的 characterArray 变量是否可能从未初始化?

我们看到它声明了:

private static String[] characterArray;

但是在它被赋值之前它会是空的,并且要么你没有提供执行赋值的代码,要么没有赋值。

【讨论】:

  • 嗯...我相信我什至没有这样做!多么愚蠢!我是否认真地工作了几个小时来忽略这么简单的事情?我真的没有注意到它。谢谢,我会尝试改变它! :D
  • 显然不是那么简单...public static void newStartFramePaneel() { StartFramePaneel.passCharacters(gekregenCharacters); characterArray = new String[gekregenCharacters]; for (int fill = 0; fill &lt; gekregenCharacters; fill++) { characterArray[index]=""; index++; } }这仍然给我错误。
  • 您正在构建一个空字符串数组?
  • 问题是,我希望这些列表一开始是空的。我已经将其更改为将项目命名为字符 1、字符 2 等。但是,最终用户将通过掷骰子“选择”字符。每次玩家有一个新角色时,他/她的名字都应该被添加到列表中,因此也应该添加到数组中。
猜你喜欢
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 2013-03-16
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多