The idea is to load an array of objects onto a JComboBox. I have a Class Tournament, which contains an array of Teams. I have serialized an intance 'a' of the Tournament class into a .dat file.

try{
      ObjectOutputStream oTourn = new ObjectOutputStream(new FileOutputStream(jTextField1.getText()+".dat"));
      oTourn.writeObject(a);
}
catch(Exception e){
      JOptionPane.showMessageDialog(this, e.toString(), "ERROR", JOptionPane.ERROR_MESSAGE);
}

This .dat file is then loaded from another JFrame, and read into another instance "t" of Tournament. "t.Teams" is sent to the constructor of a new JFrame, TeamStats, which contains the ComboBox:

Tourn t;
try{
    ObjectInputStream inTeam = new ObjectInputStream(new FileInputStream(jTextField2.getText()+".dat")); 
    t = (Tourn) inTeam.readObject();
    switch(jComboBox1.getSelectedIndex()){
        case 0:
            TeamStats tsw = new TeamStats(t.Teams);
            tsw.setVisible(true);
            break;
   }
}
catch(Exception e){
   JOptionPane.showMessageDialog(this, e.toString(), "ERROR", JOptionPane.ERROR_MESSAGE);
}

In the Team Stats form, I have declared the ComboBoxModel, and the constructor takes an array of Teams. I have attempted to create the ComboBox in the following way:

ComboBoxModel teamBox;
    public TeamStats(Team [] theTeams) {
        initComponents();
        try{
            teamBox = new DefaultComboBoxModel(theTeams);
            jComboBox1.setModel(teamBox);
        }
        catch(Exception e){
            System.out.println(e.toString());
        }
    }

When i run the program however, the Combobox is completely blank. No items in it. The list drops down, but there is nothing in it. Help would be appreciated

Recommended Answers

All 25 Replies

There's too much missing code there to be able to diagnose this (just one eg is there a second declaration of jComboBox1 somewhere?). Have you tried the obvious debugging steps, eg print theTeams at various points in the code to check that it has the data you expect?

I too am pretty sure the problem is with theTeams, and i am trying to debug it. The comboBox did display other items when i checked. I'll just share how the serialization process takes place. I have a Jframe "initTeam" which has a table (Which you helped me out with) in which a user enters details for teams participating in a tournament. The contents of the table are then fed into an array of Team objects through their constructor.

//t1 is an instance field of initTeams of type Team[]
for(int i=0; i<jTable1.getRowCount(); i++){
   t1[i] = new Team((String)jTable1.getValueAt(i, 0), (String)jTable1.getValueAt(i,1));
 }

The instance field t1 is then returned using a get function

public Team[] getTeam(){
        /*Team [] temp = new Team[t1.length];
        for(int i=0; i<t1.length; i++){
            temp[i] = new Team();
        }
        for(int i=0; i<t1.length; i++){
            temp[i] = t1[i];
        }*/
        return t1;
    }

The class that creates an object of type "Tourn" recieves the contents of getTeam() just before serializing the Tourn object into a .dat file

t.Teams = initTeam.getTeam();   //this line is currently giving a non-static to static error. It //was working a while back
try{
           ObjectOutputStream oTourn = new ObjectOutputStream(new FileOutputStream(jTextField1.getText()+".dat"));
               oTourn.writeObject(t);
       }
       catch(Exception e){
           JOptionPane.showMessageDialog(this, e.toString(), "ERROR", JOptionPane.ERROR_MESSAGE);
       }

Then, on a seperate JFrame called "ViewTournamentDetails", we load the contents of the same .dat file into an instance of Tourn as shown in the second code segment of my first post. The .Teams attribute of this instance of Tourn is sent to the constructor of the TeamStats jFrame, which tries to load it onto the combobox

DefaultComboBoxModel teamBox;
    public TeamStats(Team [] theTeams) {
        initComponents();
        String [] names = new String[theTeams.length];
        for(int i=0; i<names.length; i++){
            names[i] = theTeams[i].getName();
        }
        try{
           teamBox = new DefaultComboBoxModel(names);
           jComboBox1.setModel(teamBox);
        }
        catch(Exception e){
            System.out.println(e.toString());
        }
    }

However like i said, the combobox is blank. If i click the dropdown button, then there are 4 empty objects to click (given that there were 4 teams). They are there, but the text (name) isnt showing up.

I don't understand this code

String [] names = new String[theTeams.length];
for(int i=0; i<names.length; i++){
    names[i] = theTeams[i].getName();
}

You create that variable, but then let it go out of scope without using it at all, and so the array you created will be garbage collected.

 teamBox = new DefaultComboBoxModel();
jComboBox1.setModel(teamBox);

that will give you an empty combo box - you haven't put any data in the model.

If Team has a sensible toString method, then why not just
jComboBox1.setModel(new DefaultComboBoxModel(theTeams));
or maybe
jComboBox1.setModel(new DefaultComboBoxModel(names));
?

Sorry, i had temporarily erased "names" from the DefaultComboBoxModel to check something. Its back in now. The names array is also just another try at this. First i was directly sending theTeams[i].getName() in the DefaultComboBoxModel.

Nonetheless, i do not understand why you say the array would be garbage collected. It is recieving input from another array isnt it?

Line 1 creates a local variable "names", creates a new array of Strings, and sets names to refer to that array. 2-4 store info in the array. Then, at the end of the method, the variable "names" goes out of scope and ceases to exist. That was the only reference to the String array, so that now has no references, so it will be garbage collected.

I made names an instance field too, but it doesnt seem to help. Plus, the Combobox is being initialized in the constructor, in who's scope names did exist too.

DefaultComboBoxModel teamBox;
    Team [] t1;
    String []names;

    public TeamStats(Team [] theTeams) {
        initComponents();
        names = new String[theTeams.length];
        for(int i=0; i<names.length; i++){
            names[i] = theTeams[i].getName();
        }
        try{
           teamBox = new DefaultComboBoxModel(names);
           jComboBox1.setModel(teamBox);
        }
        catch(Exception e){
            System.out.println(e.toString());
        }
    }

That code looks OK to me. Have you tried printing the contents of names at the point where you create the default model?
ps in a general catch block it's best to call e.printStackTrace(); rather than printing e.toString because printStackTrace() prints all the available info about the error, rather tha just a summary.

As you can see the combobox does have content, but "Ghost" content. The names are not showing up, but the objects are apparently there

That sounds like theTeams[i].getName(); is returning nulls or maybe empty Strings (""). The only way to diagnose this is to keep printing those values until you find out where exactly they are going wrong.

I was trying to attach a snapshot in my previous post, but yeah you've gotten the idea. I did a println of the contents of names, and they are indeed null strings. Why though?

Who knows? Just keep printing them at earlier and earlier stages of the program until you find out where they are going null. Once you know exactly where it will probably be easy to find out why.

The line
[code]t.Teams = initTeams.getTeam();[/code] (Second post, third code segment, 1st line) is suddenly giving an error (non-static method getTeam() cannot be referenced from static object). It was working previously. I do not understand why it is suddenly throwing this error. I am trying to trace a point where the objects are populated, rather than null.

The Java language allows you to call a static method using an instance to identify the class, eg

 MyClass ins = new MyClass();
 ins.staticMethod();

this is now considered to be bad form and you are supposed to use the class to call static methods, ie
MyClass.staticMethod();

Just update your static method calls to use the class rather than an instance.

Thats all good but I have not intended it to be a static function. This method is supposed to work with the instance of the class, more specifically, return an array of an instances of teams. Heres the function:

public Team[] getTeam(){
        //t1 is an array of Teams. it is an instance field of initTeam, which this method is in.
        return t1;
}

No idea why the compiler think its static.

What's the definition of initTeams - is it static, or a local variable in a static method?

initTeams is the name of the jForm in which details for each team are entered via a table. Hence initTeams is a class defined as:

public class initTeams extends javax.swing.JFrame{
..
}

If you're asking about Teams [] t1, thats not static either.

OK, initTeams (despite the initial lower-case letter) is a class, getTeam() is an instance method, so initTeams.getTeam();is an attempt to call an instance method using a class rather than an instance.

Oh, how could I have been so stupid?

Ok, i think i have found the area causing the trouble. I added the following right after the assignment of t.Teams, so that:

t.Teams = enterform.getTeam();
       for(int i=0; i<t.Teams.length; i++){
            System.out.println(t.Teams[i].getName());
        }

And its showing a nullpointexception error. So is this assignment illegal? To refresh your memory, the above code segmant is in a class called CreateT which creates an instance t of of the class Tourn. Teams is an instance field of this class, and is an array of type Team.

If the assignment is illegal the compiler will tell you.
The exception tells you exactly which line the NPE happens on, so look at that line, if necessary print the variables and method returned values from that line to see which is null.

The error is coming on the line right after the assignment. That is the start of a for loop which is actually printing the variables. This suggests that the assignment was not properly carried out, ie

t.Teams = enterform.getTeam();

returns a null array to t.Teams. Does this tell you anything?

Never mind "suggests". Print t.Teams immediately after that line to confirm whether or not it is null. ***If ***it is null, then look in the getTeam method to see why it returned null.

Ok i've got it. CreateT does call enterform(The one with the table for input), but it does not wait for this form to be filled before carrying out the assignment. t.Teams is obviously then filled with an empty array. I need to make it pause for the input first. Any ideas?

I need to make it pause for the input first.

That's probably the wrong way to think about it. If that's really what you want then some kind of modal window is needed, but I suggest you re-think the logic flow in terms of a user-event-driven GUI. Why did you get in the position where you were trying to use info before the user has entered it? Try thinking through and documenting what should happen from the user's viewpoint.

Thats done. Thank you once again for your help. I added another button (Which the interface really needed anyway), so there is a seperate button for entering data and storing team data in the text file, and a seperate one for storing the tournament data in the text file. Its working now, and i sure did learn quite a lot on the way.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.