Toon posts:

[JAVA] NPE in simpel programma

Pagina: 1
Acties:

Onderwerpen


  • battler
  • Registratie: november 2004
  • Laatst online: 00:11
Veel wijzer geworden uit mijn vorige thread. Helaas loop ik nu al 2 dagen tegen een probleem aan waarvan ik niet snap waarom en hoe dit komt. Ik kan een methode runnen vanuit de constructor maar als ik diezelfde methode aanroep vanuit een andere methode in die zelfde klasse als die consturctor krijg ik een NPE.

Klasse die de pointers aanmaakt
code:
1
2
3
4
5
6
public class Main {
    public static void main(String[] args) {

        Moves moves = new Moves();
        Table table = new Table(moves);
        Wallet wallet = new Wallet(moves);


Klasse met constructor en methode die wel werkt
code:
1
2
3
4
5
6
7
8
public class Wallet implements ActionListener {

    Moves m;

    Wallet(Moves moves) {
       m = moves;
       m.setDeal(Boolean.TRUE); //<-- methode wordt goed uitgevoerd.
    }


In de klasse Wallet staat ook de volgende methode
Als deze wordt aangeroepen krijg ik standaard een NPE.
code:
1
2
3
    private void deal() {
        m.setDeal(Boolean.TRUE);
    }


De code die wordt uitgevoerd in de klasse Moves
code:
1
2
3
4
5
    public void setDeal(Boolean b)
    {
       System.out.println("Ik doe wel wat");
      deal.setEnabled(b);
    }


Als ik deal.SetEnabled weg haal uit de methode dan draait het wel. Ik krijg dus alleen een NPE als ik een variabele uit een andere klasse probeer aan te roepen (en dan ook nog eens alleen als ik het buiten de constructor doe). Kan iemand mij verklaren waarom dit zo is?


Voor de volledigheid is alle code hier beschikbaar:
*snip* Het is hier niet de bedoeling 500+ regels code te dumpen en ons te laten debuggen :X

[Voor 7% gewijzigd door RobIII op 26-09-2010 13:25]

Spelfout gezien, let me know! dm, tel, e-mail of per post.


  • Snake
  • Registratie: juli 2005
  • Laatst online: 23:07

Snake

Los Angeles, CA, USA

Check met een debugger de inhoud van m als je setDeal aanroept. En waarom in godsnaam 'Boolean.TRUE' en niet gewoon true? :P

Going for adventure, lots of sun and a convertible! | GMT-8


  • CodeCaster
  • Registratie: juni 2003
  • Niet online

CodeCaster

👌👀 good shit ✔💯

battler schreef op zondag 26 september 2010 @ 12:57:
Als ik deal.SetEnabled weg haal uit de methode dan draait het wel.
Is deal een membervariabele van je Moves-klasse, en instantieer je die toevallig pas in een methode van die klasse?

Zit er geen debugger in je editor? Ik zou Eclipse aanraden, die geeft hier wel netjes warnings op.

[Voor 14% gewijzigd door RobIII op 26-09-2010 13:26. Reden: url naar code verwijderd]

As always, we are nailed to a cross of our own construction.


  • Herko_ter_Horst
  • Registratie: november 2002
  • Niet online
In Moves: het field "deal" krijgt pas een waarde als ooit een keer de methode deal() is aangeroepen. Voor die tijd krijg je een NPE.

Ik zo sowieso eens kijken naar een betere splitsing tussen je logica en de GUI, het zit nu allemaal wel heel erg door elkaar. Probeer het eens te implementeren via het MVC pattern.

"Any sufficiently advanced technology is indistinguishable from magic."


  • Cobalt
  • Registratie: januari 2004
  • Laatst online: 23:56
Het veld deal in de klasse Moves is en blijft altijd null. In de methode Panel31() roep je de deal() aan en het resultaat stop je in panel.add(). De methode deal() maakt een instantie JButton en returned deze instantie. Waarna die wordt toegevoegd aan panel. Panel31() moet overigens lower case zijn, het is immers geen constructor.
Daarnaast wordt de instantie van JButton nooit in het veld deal gestopt. Met als gevolg dat je een NullPointerException krijgt wanneer je een methode aan wilt roepen op deal. (Ik was even aan het denken wat je bedoelde met NPE)

[Voor 19% gewijzigd door Cobalt op 26-09-2010 13:19]


  • battler
  • Registratie: november 2004
  • Laatst online: 00:11
Snake schreef op zondag 26 september 2010 @ 13:00:
Check met een debugger de inhoud van m als je setDeal aanroept. En waarom in godsnaam 'Boolean.TRUE' en niet gewoon true? :P
Ik zal even kijken naar de debugger, ik gebruik NetBeans dus dat zal er wel inzitten. Gelijk ook even veranderd dat TRUE in true.
CodeCaster schreef op zondag 26 september 2010 @ 13:04:
[...]

Is deal een membervariabele van je Moves-klasse, en instantieer je die toevallig pas in een methode van die klasse?

Zit er geen debugger in je editor? Ik zou Eclipse aanraden, die geeft hier wel netjes warnings op.
Misschien dat ik een beetje in de problemen kom met mijn terminologie hier maar volgens mij declareer ik hem als eerste " JButton deal;" en instantieer ik hem later in een methode:
code:
1
2
3
4
5
6
7
8
9
    public JButton deal() {
        System.out.println("kom ik bij deal?");
        deal = new JButton("Deal");
        deal.setVerticalTextPosition(SwingConstants.CENTER);
        deal.setHorizontalTextPosition(SwingConstants.CENTER);
        deal.setFont(new Font("Serif", Font.BOLD, 16));
        deal.setEnabled(false);
        return deal;
    }

Als ik hem gelijk instantieer blijft het probleem bestaan. NetBeans heeft vast een debugger daar ga ik nu naar zoeken.
Herko_ter_Horst schreef op zondag 26 september 2010 @ 13:06:
In Moves: het field "deal" krijgt pas een waarde als ooit een keer de methode deal() is aangeroepen. Voor die tijd krijg je een NPE.

Ik zo sowieso eens kijken naar een betere splitsing tussen je logica en de GUI, het zit nu allemaal wel heel erg door elkaar. Probeer het eens te implementeren via het MVC pattern.
De methode deal() wordt aangeroepen bij het maken van de GUI.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
public JPanel Panel31() {
        JPanel panel = new JPanel();
        panel.setMinimumSize(new Dimension(266, 266));
        panel.setPreferredSize(new Dimension(266, 255));
        panel.setBackground(new Color(18, 92, 33));
[b]        panel.add(deal());[/b]
        panel.add(hit());
        panel.add(pass());
        panel.add(split());
        panel.add(dubble());
        panel.add(test());
        return panel;
    }


Ik zal me ook even gaan verdiepen in het MVC pattern.

[Voor 0% gewijzigd door RobIII op 26-09-2010 13:26. Reden: url naar code verwijderd]

Spelfout gezien, let me know! dm, tel, e-mail of per post.


  • Cobalt
  • Registratie: januari 2004
  • Laatst online: 23:56
Zie volgende post van mij.

[Voor 255% gewijzigd door Cobalt op 26-09-2010 13:29]


  • Herko_ter_Horst
  • Registratie: november 2002
  • Niet online
battler schreef op zondag 26 september 2010 @ 13:19:
[...]
De methode deal() wordt aangeroepen bij het maken van de GUI.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
public JPanel Panel31() {
        JPanel panel = new JPanel();
        panel.setMinimumSize(new Dimension(266, 266));
        panel.setPreferredSize(new Dimension(266, 255));
        panel.setBackground(new Color(18, 92, 33));
[b]        panel.add(deal());[/b]
        panel.add(hit());
        panel.add(pass());
        panel.add(split());
        panel.add(dubble());
        panel.add(test());
        return panel;
    }


Ik zal me ook even gaan verdiepen in het MVC pattern.
Ja, en waar/wanneer wordt die methode aangeroepen? Waarom niet in de constructor van Moves?

Ow wacht... zitten we soms naar automatisch gegenereerde code uit een GUI-builder te kijken?

[Voor 5% gewijzigd door Herko_ter_Horst op 26-09-2010 13:23]

"Any sufficiently advanced technology is indistinguishable from magic."


  • battler
  • Registratie: november 2004
  • Laatst online: 00:11
Herko_ter_Horst schreef op zondag 26 september 2010 @ 13:22:
[...]

Ja, en waar/wanneer wordt die methode aangeroepen? Waarom niet in de constructor van Moves?

Ow wacht... zitten we soms naar automatisch gegenereerde code uit een GUI-builder te kijken?
Nee alles is gewoon eigen code. Misschien door mijn gebrek aan programmeerervaring dat het een beetje rommelig lijkt.

Hier wordt die methode aangeroepen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 Table(Moves moves) {
        m = moves;
        setFrame(); <--- Roept frame
    }

    void setFrame() {
        JFrame frame = new JFrame("Blackjack Table");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(800, 800));
        frame.getContentPane().add(mainPanel()); <---- roept mainPanel
        frame.pack();
        frame.setVisible(true);
    }

    public JPanel mainPanel() {
        g = new GridBagConstraints();
        g.fill = GridBagConstraints.HORIZONTAL;
        JPanel panel = new JPanel();
        panel.setBackground(Color.red);
        panel.setLayout(new GridBagLayout());
        panel.add(Panel11(1, 1), g);
        panel.add(Panel12(1, 2), g);
        panel.add(Panel13(1, 3), g);
        panel.add(Panel21(2, 1), g);
        panel.add(Panel22(2, 2), g);
        panel.add(Panel23(2, 3), g);
        panel.add(Panel31(3, 1), g);
        panel.add(Panel32(3, 2), g);
        panel.add(Panel33(3, 3), g); <--- roept methode Panel33
        return panel;
    }


De constructor van Table maakt het frame hierin wordt de panel aangemaakt. De methode Panel33 maakt de pointers aan.
code:
1
2
3
4
5
6
    private JPanel Panel33(int y, int x) {
        Wallet wallet = new Wallet();
        g.gridx = x;   //Set Colom
        g.gridy = y;   //Set Row
        return wallet.Panel33();
    }

Spelfout gezien, let me know! dm, tel, e-mail of per post.


  • Cobalt
  • Registratie: januari 2004
  • Laatst online: 23:56
-

[Voor 110% gewijzigd door Cobalt op 26-09-2010 13:38]


  • battler
  • Registratie: november 2004
  • Laatst online: 00:11
Maar de methode die constructor van Wallet aanroept werkt wel. Daarentegen diezelfde methode wordt aangeroepen als je op een knopje drukt en dan werkt hij ineens niet.

Zelfde methode in klasse Wallet maar werkt hier niet.
code:
1
2
3
  private void deal() {
        m.setDeal(Boolean.TRUE);
    }

Spelfout gezien, let me know! dm, tel, e-mail of per post.


  • Cobalt
  • Registratie: januari 2004
  • Laatst online: 23:56
Moet in JButton deal() niet ook deal.addActionListener(this); staan?

  • battler
  • Registratie: november 2004
  • Laatst online: 00:11
Klopt maar de ActionListeners in de methode Moves zijn nog niet aangemaakt. Alleen voor het knopje test. Die voert ook de methode setDeal(true) uit. Ik wou kijken of het misschien aan de methode lag maar daar werkt het wel gewoon.

Spelfout gezien, let me know! dm, tel, e-mail of per post.


  • Herko_ter_Horst
  • Registratie: november 2002
  • Niet online
battler schreef op zondag 26 september 2010 @ 13:26:
[...]


Nee alles is gewoon eigen code. Misschien door mijn gebrek aan programmeerervaring dat het een beetje rommelig lijkt.

Hier wordt die methode aangeroepen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 Table(Moves moves) {
        m = moves;
        setFrame(); <--- Roept frame
    }

    void setFrame() {
        JFrame frame = new JFrame("Blackjack Table");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(800, 800));
        frame.getContentPane().add(mainPanel()); <---- roept mainPanel
        frame.pack();
        frame.setVisible(true);
    }

    public JPanel mainPanel() {
        g = new GridBagConstraints();
        g.fill = GridBagConstraints.HORIZONTAL;
        JPanel panel = new JPanel();
        panel.setBackground(Color.red);
        panel.setLayout(new GridBagLayout());
        panel.add(Panel11(1, 1), g);
        panel.add(Panel12(1, 2), g);
        panel.add(Panel13(1, 3), g);
        panel.add(Panel21(2, 1), g);
        panel.add(Panel22(2, 2), g);
        panel.add(Panel23(2, 3), g);
        panel.add(Panel31(3, 1), g);
        panel.add(Panel32(3, 2), g);
        panel.add(Panel33(3, 3), g); <--- roept methode Panel33
        return panel;
    }


De constructor van Table maakt het frame hierin wordt de panel aangemaakt. De methode Panel33 maakt de pointers aan.
code:
1
2
3
4
5
6
    private JPanel Panel33(int y, int x) {
        Wallet wallet = new Wallet();
        g.gridx = x;   //Set Colom
        g.gridy = y;   //Set Row
        return wallet.Panel33();
    }
Hoe meer ik er naar kijk, hoe minder ik van je code snap. Probeer je hier nu uit te leggen waar Moves.Panel13() wordt aangeroepen, waar die deal() methode wordt aangeroepen?

Ik denk dat we er zo niet gaan komen. Je kunt beter even opnieuw beginnen met een duidelijke scheiding tussen logica en UI én met fatsoenlijke namen voor initialisatiemethoden (dus geen Panel33, want dat snapt niemand. createWalletPanel() zou al beter zijn).

Denk in elk geval goed na over waar verantwoordelijkheden liggen. Maak classes zo veel mogelijk self-contained (d.w.z. zelfstandig verantwoordelijk voor één taak). Verberg zoveel mogelijk de interne state van je classes. Zorg ervoor dat objecten na afloop van de constructor direct al in een bruikbare staat zijn, laat dat niet over aan het "toevallig" aanroepen van andere methoden van buitenaf.

@Mod: niet handig om nu nog die links naar z'n code te verwijderen, maakt communiceren wel erg lastig. De TS heeft geprobeerd relevante code te posten en daarbij de rest van z'n code als referentiemateriaal achter een link. Niks mis mee, lijkt me.

[Voor 21% gewijzigd door Herko_ter_Horst op 26-09-2010 13:50]

"Any sufficiently advanced technology is indistinguishable from magic."


  • Cobalt
  • Registratie: januari 2004
  • Laatst online: 23:56
Java:
1
2
3
4
5
6
7
8
9
public class Table {
...
    private JPanel Panel33(int y, int x) {
        Wallet wallet = new Wallet(); // misschien zou je ook moves moeten meegeven
        g.gridx = x;   //Set Colom
        g.gridy = y;   //Set Row
        return wallet.Panel33();
    }
}


edit: Herko ik ben het met je eens.

[Voor 25% gewijzigd door Cobalt op 26-09-2010 22:42]


  • Herko_ter_Horst
  • Registratie: november 2002
  • Niet online
Cobalt schreef op zondag 26 september 2010 @ 13:49:
Java:
1
2
3
4
5
6
7
8
9
public class Table {
...
    private JPanel Panel33(int y, int x) {
        Wallet wallet = new Wallet(); // misschien zou je ook moves moeten meegeven
        g.gridx = x;   //Set Colom
        g.gridy = y;   //Set Row
        return wallet.Panel33();
    }
}
Sowieso is het verdacht dat hier nog een Wallet instantie wordt aangemaakt, terwijl dat in de Main ook al gebeurt...

offtopic:
Niet meer met me eens? ;)

"Any sufficiently advanced technology is indistinguishable from magic."


  • battler
  • Registratie: november 2004
  • Laatst online: 00:11
Ik denk dat die onduidelijkheid zich voordoet doordat ik van te voren niet heb vaststaan wat een aparte klasse wordt. Panel33 staat bv. voor de positie (3e row, 3e Colom) Dit was eerst een methode waarnaar ik dacht dat het beter was om hier een aparte Klasse voor te maken. De reden dat ik (nog) niet overal een aparte klasse voor maak is bv het probleem waar ik nu tegen aan loop. Ik snap het gewoon nog niet genoeg en als problemen zich voordoen heb ik geen idee waardoor dat komt. Daarentegen kan het ook zo zijn dat problemen zich op dit moment juist voordoen omdat er een gebrek is aan klasses.
Herko_ter_Horst schreef op zondag 26 september 2010 @ 13:56:
[...]

Sowieso is het verdacht dat hier nog een Wallet instantie wordt aangemaakt, terwijl dat in de Main ook al gebeurt...

offtopic:
Niet meer met me eens? ;)
!!! :D Zoals je aangaf in de code heb ik moves meegeven aan wallet. Nu werkt de methode in de constructor niet meer maar wel de methode die hij aanroept.
code:
1
2
3
4
5
6
 private JPanel Panel33(int y, int x) {
        Wallet wallet = new Wallet(m);
        g.gridx = x;   //Set Colom
        g.gridy = y;   //Set Row
        return wallet.Panel33();
    }


Ik ga mijn code aanpassen opschonen en zorgen dat ik 100% begrijp wat er gebeurd. Maar hij doet in ieder geval al wat hij moet doen!

Bedankt allemaal voor jullie input en tips! _/-\o_

[Voor 37% gewijzigd door battler op 26-09-2010 14:33]

Spelfout gezien, let me know! dm, tel, e-mail of per post.


  • Herko_ter_Horst
  • Registratie: november 2002
  • Niet online
Nog een paar tips.

1. Bedenk eerst hoe het moet gaan worden *zonder* enige UI. Als je je programma zonder UI wilt draaien om te weten of het goed gaat, gebruik dan de debugger als "UI", of werk desnoods met System.out.println().

2. Analyseer eens welke zaken je tegenkomt als je Blackjack aan het spelen bent en leidt daaruit af welke classes je nodig hebt. Je hebt bijvoorbeeld een Blackjacktafel, aan die tafel zitten een Deler en Spelers. De Deler heeft een Dek Kaarten (dat geschud moet kunnen worden), de Spelers kunnen geld inzetten en krijgen dan een aantal Kaarten uit het Dek. Bedenk ook welke acties er kunnen worden uitgevoerd zoals inzetten, delen, schudden.

3. Leidt hieruit af welke informatie je in een class moet bijhouden om die class z'n werk te kunnen laten doen (fields). Bedenk welke voorwaarden er aan die informatie zitten (bijv: een Speler kan nooit minder dan 0 geld hebben). Bedenk welke modificaties er op die informatie kunnen worden uitgevoerd en welke informatie daar weer voor nodig is (methods en parameters) en welke voorwaarden daar weer aan zitten (bijv. een speler kan alleen inzetten als hij nog minstens de minimum inzet aan geld heeft).

4. Als je uiteindelijk gaat programmeren, let dan even op de naamgevingsconventies (classnames met CamelCase, overige namen met lowerCamelCase) en geef alles zinnige namen: geef aan wat een methode doet, niet wat er met het resultaat van de methode gaat gebeuren. Probeer ook te vermijden dat je bijv. het returntype gaat herhalen in de naam. en liefst niet het return type en zeker geen informatie die niet in de methode tot uitdrukking komt. Dus bijv. "JPanel createWalletUI()" en niet "JPanel Panel33()" (dat het panel uiteindelijk op positie 3,3 terecht komt is voor de methode totaal niet van belang).

Vuistregels voor naamgeving:
A. de naam van een class is een zelfstandig naamwoord (een ding, enkelvoud). Als je denkt dat het meervoud moet zijn, moet je nog eens goed kijken of je niet eigenlijk een Collection (Set, List of Map) nodig hebt (bijv. List<Move> i.p.v. Moves).

B. de naam van een methode moet een werkwoord bevatten (een actie).

[Voor 38% gewijzigd door Herko_ter_Horst op 26-09-2010 15:51]

"Any sufficiently advanced technology is indistinguishable from magic."


  • Killemov
  • Registratie: januari 2000
  • Laatst online: 22-09 16:22

Killemov

Ik zoek nog een mooi icooi =)

Herko_ter_Horst schreef op zondag 26 september 2010 @ 15:34:
Nog een paar tips.

...

B. de naam van een methode moet een werkwoord bevatten (een actie).
> 90% = getXXX, setXXX of isXXX (dat laatste als een field een boolean betreft.)

Hey ... maar dan heb je ook wat!

Pagina: 1


Nintendo Switch (OLED model) Apple iPhone 13 LG G1 Google Pixel 6 Call of Duty: Vanguard Samsung Galaxy S21 5G Apple iPad Pro (2021) 11" Wi-Fi, 8GB ram Nintendo Switch Lite

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2021 Hosting door True

Tweakers maakt gebruik van cookies

Bij het bezoeken van het forum plaatst Tweakers alleen functionele en analytische cookies voor optimalisatie en analyse om de website-ervaring te verbeteren. Op het forum worden geen trackingcookies geplaatst. Voor het bekijken van video's en grafieken van derden vragen we je toestemming, we gebruiken daarvoor externe tooling die mogelijk cookies kunnen plaatsen.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Forum cookie-instellingen

Bekijk de onderstaande instellingen en maak je keuze. Meer informatie vind je in ons cookiebeleid.

Functionele en analytische cookies

Deze cookies helpen de website zijn functies uit te voeren en zijn verplicht. Meer details

janee

    Cookies van derden

    Deze cookies kunnen geplaatst worden door derde partijen via ingesloten content en om de gebruikerservaring van de website te verbeteren. Meer details

    janee