Lanike71 Δημοσ. 4 Ιανουαρίου 2013 Δημοσ. 4 Ιανουαρίου 2013 Καλησπέρα, Προσπαθώ να υλοποιήσω μία κρεμάλα,αλλά βγάζει σφάλμα το netbeans. Κλάση Word και κλάση Gui. public class Gui extends javax.swing.JFrame { private char[] letters; private Word word1; public Gui() { Word word1=new Word(); char[] letts=word1.getLexi().toCharArray(); // αποθηκεύει τη λέξη σε πίνακα χαρακτήρων public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new Gui().setVisible(true); } }); } Το θέμα ξεκινά όταν θέλω να αναφερθώ στον πίνακα χαρακτήρων letters πατώντας ένα κουμπί(που ελέγχει αν υπάρχει ο χ χαρακτήρας εκεί),τότε μου πετά NullPointerException,που αν δεν κάνω λάθος,σημαίνει αναφέρομαι σε αντικείμενο που δεν υπάρχει. Κάποια βοήθεια;
MeTaXaS4 Δημοσ. 4 Ιανουαρίου 2013 Δημοσ. 4 Ιανουαρίου 2013 Αν και δεν έχεις βάλει ούτε το σφάλμα ούτε την κλάση word, θα έλεγα ότι το πρόβλημα στο βγάζει στην 10. γραμμή "char[] letts=word1.getLexi().toCharArray(); // αποθηκεύει τη λέξη σε πίνακα χαρακτήρων" εκεί λες στο letts να πάρει δεδομένα από το word1 που όμως πάνω το έχεις δημιουργήσει με κενό δημιουργό, στον κενό δημιουργό της κλάσης word δίνεις τίποτα στο Lexi ώστε να μπορείς να κάνεις το getLexi() ?
nilosgr Δημοσ. 4 Ιανουαρίου 2013 Δημοσ. 4 Ιανουαρίου 2013 Το προβλημα ειναι (μαλλον) στη γραμμη 8 word1=new Word(); ωστε να αρχικοποιηθει η instance variable κι οχι η τοπικη
Lanike71 Δημοσ. 4 Ιανουαρίου 2013 Μέλος Δημοσ. 4 Ιανουαρίου 2013 To Word είναι ΟΚ.Παίρνει όρισμα string και επιλέγει τυχαία από πίνακα με strings.,απλά δεν ήθελα να βάλω πρόσθετες και ίσως άχρηστες πληροφορίες. public class Word { private String lexi; private int letterNum; private char startWith; private char endTo; public Word(String lexi){ this.lexi=lexi; this.letterNum=lexi.length(); this.startWith=lexi.charAt(0); this.endTo=lexi.charAt(letterNum-1); } public String getLexi(){ return this.lexi; } public int getLetterNum(){ return this.letterNum; } public char getFirstLetter(){ return this.startWith; } public char getLastLetter(){ return this.endTo; } } Και το υπόλοιπο του δημιουργού gui Random generator=new Random(); int pick=generator.nextInt(17); String[] words={"ΓΑΤΑ","ΣΚΥΛΟΣ","ΠΟΝΤΙΚΟΣ","ΕΛΕΦΑΝΤΑΣ","ΦΙΔΙ","ΛΙΟΝΤΑΡΙ","ΠΑΝΤΑ","ΑΓΕΛΑΔΑ","ΑΚΡΙΔΑ", "ΚΑΤΣΑΡΙΔΑ","ΑΡΑΧΝΗ","ΣΚΙΟΥΡΟΣ","ΕΛΑΦΙ","ΑΡΚΟΥΔΑ","ΤΙΓΡΗ","ΝΥΧΤΕΡΙΔΑ","ΧΕΛΙΔΟΝΙ"}; Word word1=new Word(words[pick]); Βλέπεις κάπου λάθος; Ενώ το gui ανοίγει κανονικά,εμφανίζεται η λέξη με εμφανισμένα μόνο πρώτο και τελευταίο γράμμα,μόλις πατήσω κάποιο button-γράμμα, τότε πετάει το σφάλμα Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException Στη γραμμή: private void btn_alphaActionPerformed(java.awt.event.ActionEvent evt) { for(int j=1;j<letts.length-1;j++){ letters[j]=word1.getLexi().charAt(j); }
nilosgr Δημοσ. 5 Ιανουαρίου 2013 Δημοσ. 5 Ιανουαρίου 2013 Για βάλε μια printf στην action_performed Δηλαδή πριν τη for γράψε System.out.println("word is: " + word1);Τι γράφει στη κονσόλα; (μήπως γράφει word is null αν ναι, τότε κάνε αυτό που έγραψα πιο πάνω)
Lanike71 Δημοσ. 5 Ιανουαρίου 2013 Μέλος Δημοσ. 5 Ιανουαρίου 2013 Για βάλε μια printf στην action_performed Δηλαδή πριν τη for γράψε System.out.println("word is: " + word1);Τι γράφει στη κονσόλα; (μήπως γράφει word is null αν ναι, τότε κάνε αυτό που έγραψα πιο πάνω) Έχεις δίκιο.Πετάει εκεί το σφάλμα null τώρα. Πού θα πρέπει να το αρχικοποιήσω όμως;Το έκανα ήδη στο δημιουργό του gui. Edit. After 15 mins: ΟΚ το έλυσα αυτό το θέμα όπως είπες.Μετά όμως πέταξε πάλι null εκεί που έλεγα,στον πίνακα χαρακτήρων..Άλλαξα και εκείνο με τον τρόπο που είπες και δούλεψε πάλι. Ευχαριστώ για τη βοήθεια! Και μία άλλη ερώτηση: Επειδή όλα τα κουμπιά-γράμματα υλοποιούν κάποιες κοινές εργασίες,πώς μπορώ να το γλιτώσω όλο αυτό; Πού θα γραφτεί το κοινό κομμάτι; Τελικά το gui είναι πιο περίπλοκο από την κονσόλα... 1
nilosgr Δημοσ. 5 Ιανουαρίου 2013 Δημοσ. 5 Ιανουαρίου 2013 Θα κανείς μια κλάση (πχ ButtonClickHandler) η οποία θα κάνει implement το ActionListener. Μέσα στην κλάση θα έχεις μια instance variable (πχ repr) η οποία θα είναι ο "αντιπρόσωπος" χαρακτήρας του κουμπιού και θα αρχικοποιηται μέσα από ένα κατασκευαστή (που θα έχει τον χαρακτήρα ως όρισμα). Ναι, σίγουρα είναι πιο δύσκολο το GUI αφού ο κώδικας είναι event driven κι όχι "γραμμικός". Δηλαδή σε ένα τυπικό πρόγραμμα κονσόλας ο κώδικας αρχίζει απ τη main() και ανάλογα τα if/else και τα loop ξέρεις ποιες εντολές θα τρέξουν και μάλιστα και με ποια σειρά θα τρέξουν. Εννοώ στο GUI δεν ξέρεις τη σειρά με την οποία θα τρέξουν οι εντολές. Κάθε κουμπί (και γενικότερα κάθε event) είναι μια μέθοδος που δεν είναι σίγουρος εάν/και πότε θα τρέξει.
ZAKKWYLDE Δημοσ. 5 Ιανουαρίου 2013 Δημοσ. 5 Ιανουαρίου 2013 Αν μετά θες να κάνεις και MVC το GUI μπλέκεις ακόμα περισσότερο .
Lanike71 Δημοσ. 5 Ιανουαρίου 2013 Μέλος Δημοσ. 5 Ιανουαρίου 2013 Understood! Ευχαριστώ πάλι για τη βοήθεια.
Lanike71 Δημοσ. 5 Ιανουαρίου 2013 Μέλος Δημοσ. 5 Ιανουαρίου 2013 Nilos and friends τη βοήθειά σας: Έφτιαξα την κλάση,όπως και το δημιουργό.Αλλά δε μπορώ να στείλω την πληροφορία του κάθε κουμπιού,για το χαρακτήρα μιλάω. Σε τι διαφέρει το πάτημα του Α από αυτό του Β; Αφού πλέον όλα τα κουμπιά κάνουν Implement την ίδια κλάση... Επιπλέον έφτιαξα και ένα πίνακα τύπου JButton για να χειρίζομαι εύκολα τα κουμπιά. Edited quickly: Κάτι που μου ήρθε τώρα,εκτός και αν με μία if για τα 24 κουμπιά,επιλέγεται ποιός θα είναι ο χαρακτήρας,αλλά μου φαίνεται μπελαλίδικη λύση... Ο κώδικας: private class CheckLetterButtonHandler implements ActionListener { private char character; public CheckLetterButtonHandler(String str){ this.character=str.charAt(0); } @Override public void actionPerformed(ActionEvent e) { char c=this.character; } }
ZAKKWYLDE Δημοσ. 5 Ιανουαρίου 2013 Δημοσ. 5 Ιανουαρίου 2013 Δεν συμφωνώ και τόσο με τη συγκεκριμένη προσέγγιση. Για μένα το καλύτερο είναι σε κάθε JButton αφού τα έχεις βάλει και σε array να τους κάνεις addActionListener(listener). O constructor θεωρώ ότι δεν υπάρχει λόγος να παίρνει κάποιο argument. Απλά στη μέθοδο θα κάνεις this.character = e.getsource(). μια μέθοδος που σου δίνει τον χαρακτήρα του JButton...ψαξτες δεν τη θυμάμαι. Επίσης η θα κάνεις το character public η θα φτιάξεις έναν getter για να μπορείς να τον πάρεις χρησιμοποιώντας το reference του CheckButtonListener.
Lanike71 Δημοσ. 5 Ιανουαρίου 2013 Μέλος Δημοσ. 5 Ιανουαρίου 2013 Δεν συμφωνώ και τόσο με τη συγκεκριμένη προσέγγιση. Για μένα το καλύτερο είναι σε κάθε JButton αφού τα έχεις βάλει και σε array να τους κάνεις addActionListener(listener). Αυτό έκανα. O constructor θεωρώ ότι δεν υπάρχει λόγος να παίρνει κάποιο argument. Απλά στη μέθοδο θα κάνεις this.character = e.getsource(). μια μέθοδος που σου δίνει τον χαρακτήρα του JButton...ψαξτες δεν τη θυμάμαι. Επίσης η θα κάνεις το character public η θα φτιάξεις έναν getter για να μπορείς να τον πάρεις χρησιμοποιώντας το reference του CheckButtonListener. Με βοήθησες αρκετά με τη μέθοδο ..........this.character=e.getSource().toString().charAt(0); Μήπως το σωστό θα ήταν να έχω μία setChar που θα εκτελείται μέσα στo event και λογικά να έχω μόνο ένα στιγμιότυπο της κλάσης που ανάλογα με το κουμπί να αλλάζει char; Sorry αλλά είμαι αρχάριος οπότε...
ZAKKWYLDE Δημοσ. 6 Ιανουαρίου 2013 Δημοσ. 6 Ιανουαρίου 2013 Αυτό ήδη επιτυγχάνεται με τον τρόπο που σου έδειξα, δεν είναι απαραίτητο να χρησιμοποιήσεις τη μέθοδο που λες. Πάντα ένα instance της κλάσης του CheckLetterButtonHandler θα έχεις και κάθε φορά που γίνεται trigger το event (δηλαδή κάθε φορά που πατάς κουμπί) το instance variable του θα αλλάζει. Ένα getChar το θέλεις όμως, για να μπορείς να "τραβήξεις" το value του instance variable εκτός της κλάσης.
Lanike71 Δημοσ. 6 Ιανουαρίου 2013 Μέλος Δημοσ. 6 Ιανουαρίου 2013 Τελικά το κατάφερα,ευχαριστώ για τη βοήθεια! Και για να μην ανοίγω άλλο θέμα,γνωρίζει κανείς πώς μπορώ να τοποθετήσω ένα JLabel πάνω από άλλο JLabel; Και αν ρωτάει κάποιος γιατί να το κάνω αυτό θέλω να προσομοιώσω την εμφάνιση κάποιου αντικειμένου πάνω σε κάποιο άλλο το οποίο θα φανεί σαν κίνηση,για παράδειγμα κίνηση πιονιού σε κάποιο σημείο σε σκακιέρα (αν υποθέσουμε ότι το ένα Jlabel είναι το τετράγωνο και το άλλο το πιόνι) κλπ. Εκτός και αν υπάρχει κάποια άλλη πιο εύκολη λύση.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα