WadeG
WadeG

Reputation: 61

Populating a JComboBox with an ArrayList from another class

I am trying some self teachings and am working on a small app that reads details from a text file and shows them in a JComboBox for selection. The plan is to be able to select an item from the combobox, push the button and have a pop-up message appear with text depending on the selection, but I digress.

Currently, when it compiles the combobox is showing what I think to be some kind of exception. It says [Ljava.lang.Object;@175078b.

What am I doing wrong here?

This is the class that has the ArrayList:

import java.io.File;
import java.io.FileNotFoundException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.Scanner;

public class Stuff {

    private ArrayList<String> list;
    private String name;

    private ArrayList<String> getList() {
        return list;
    }

    private void setList(ArrayList list) {
        this.list = list;
    }

    public Stuff() {
        readNames();
    }

    public void readNames() {
        File file = new File("Names.txt");
        try {
            ArrayList<String> list = new ArrayList<>();

            Scanner in = new Scanner(file);
            while (in.hasNextLine()) {
                list.add(in.nextLine());
            }
            Collections.sort(list);
//            for (int i = 0;  i < list.size();++i){            
//        System.out.println(list.get(i));
//            }
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

This is the class with the GUI:

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.util.ArrayList;
import javax.swing.*;


public class GUI extends JFrame{
    private JLabel label = new JLabel("Who is the most awesome?");
    private JComboBox box = new JComboBox();
    private JFrame frame = new JFrame();
    private JTextArea text = new JTextArea();
    private JButton button = new JButton("Press Me");
    private JPanel panel = new JPanel();
    private ArrayList<Stuff> list = new ArrayList<>();


    private JFrame getFrame(){
        return frame;
    }
    private ArrayList<Stuff> getList(){
        return list;
    }
    private void setList (ArrayList<Stuff> list){
        list = list;
    }



    public GUI(){        
        buildGUI();
    }

    private void buildGUI(){           
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        panel.setLayout(new FlowLayout());
        panel.add(label);
        panel.add(box);
        panel.add(button); 
        box.addItem(list.toArray());

        frame.add(text);
        frame.add(panel, BorderLayout.CENTER);
        frame.setSize(400,100);
        frame.setVisible(true);
    }
}

Upvotes: 2

Views: 9108

Answers (2)

David Yee
David Yee

Reputation: 3646

Your problem is in the line: box.addItem(list.toArray());

The addItem() method for a JComboBox requires an Object as a parameter. Typically, a String object is used as the parameter. Instead, what you are doing is trying to add the actual list reference to the combo box when you really meant to add every item in the list.

Instead, you should add the individual items in the list as follows:

for(Stuff stuff : list) {
    box.addItem(stuff.getName());
}

EDIT: Reading your original worded problem again, I think your second code snippet regarding the GUI should not be using another ArrayList of Stuff if you actually intended to use the ArrayList in one instance of a Stuff object. Therefore, you should first change:

private ArrayList<Stuff> list = new ArrayList<>();

to

private Stuff = new Stuff();

and change the for loop to iterate through stuff.getList() instead of list. To clarify, the for loop might look like:

for(String detail : stuff.getList()) {
    box.addItem(detail); // add each extracted detail from the text file that was stored in the list of the stuff object
}

Upvotes: 4

MadProgrammer
MadProgrammer

Reputation: 347204

The main problem is you're adding a single array to the combo box...

box.addItem(list.toArray());

You either need to build a ComboBoxModel around the list the list of items...

DefaultComboBoxModel model = new DefaultComboBoxModel(list.toArray(new Stuff[list.size()]));
box.setModel(model);

Or add each item from the list to the combo box

for (Stuff stuff : list) {
    box.addItem(stuff);
}

See How to use combo boxes for more details

The responsibility for rendering values in JComboBox comes down to the ListCellRenderer.

Take a look at Providing a Custom Renderer for more details.

This approach allows you to custom how the object is rendered without having to modify the underlying object itself. It also means that you maintain the object relationship. Rather then having to provide some kind of mapping between the view and the original list of objects, you can simply get a direct reference of the object from the combo box, because the ListCellRenderer is performing the transformation for you.

Now, having said that, this will prevent the user from been able to use combo boxes built in search feature.

To that end, check Combo Box With Custom Renderer for a possible work around. This is authored by our very own camickr

Upvotes: 3

Related Questions