Custom Classes and JLists

2019-08-10 03:53发布

I'm working in NetBeans on a Java Project.

I need to display every State (e.g. "Oklahoma") in an ArrayList<State> in a JList.

I can't figure out how to do this... especially not in NetBeans.

I think it involves creating a DefaultListModel with each State as a String. I've tried this a million different ways to no avail.

Is it possible to just load the ArrayList<State> (perhaps if the State class has a toString() method)? This would be especially helpful, because I could directly modify the ArrayList<State> via actionPerformed().

For the sake of the question, let's assume a State is an object with a name of type String and a population of type int.

I hope this makes sense.

Thanks.

5条回答
Ridiculous、
2楼-- · 2019-08-10 04:14

Unfortunately, the only 'easy' initialization of JList with a List is via Vector

Vector<State> myStates = new Vector();
//add states
JList list = new JList(myStates);
查看更多
Ridiculous、
3楼-- · 2019-08-10 04:15

All these answers are great, and certainly useful. I ended up solving it very simply from the controller:

view.getStatesList().setListData(model.getStates().toArray());

The key is the use of .setListData() (which can take an Array as an argument) instead of .setModel().

查看更多
家丑人穷心不美
4楼-- · 2019-08-10 04:17

I presume your talking about the Matisse GUI builder here, otherwise this should be fairly trivial.

First off you need to create the custom ListModel

public class StateListModel extends AbstractListModel{
    private final List<State> list;

    public StateListModel(List<State> list) {
        this.list = list;
    }

    @Override
    public int getSize() {
        return list.size();
    }

    @Override
    public Object getElementAt(int index) {
        return list.get(index);
    }

}

in the constructor of your class initialise the ListModel before initComponents() is called, and make it a field not a local variable.

stateListModel = new StateListModel(myListofStates);

In the NetBeans GUI builder right click on your JLIst, and select 'customize code'. You will see something along the lines of jList1.setModel(...) Change the dropdown to custom property and edit the code to read

jList1.setModel(stateListModel);
查看更多
别忘想泡老子
5楼-- · 2019-08-10 04:22

All answers provided here are great (+1). In my opinion you will be best creating your own model which you can later reuse easily knowing how it works.

import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;

/**
 * 
 * @author Konrad Borowiecki
 */
public class ObjectDataTableModel extends AbstractTableModel
{
    private static final long serialVersionUID = 1L;
    private List<String> columnNames = new ArrayList<String>();
    private List<List<Object>> data = new ArrayList<List<Object>>();
    public ObjectDataTableModel()
    {
    }

    public void setColumnNames(List<String> cNames)
    {
        this.columnNames = cNames;
    }

    public void setData(List<List<Object>> dbData)
    {
        this.data = dbData;
    }

    public List<List<Object>> getData()
    {
        return data;
    }   

    @Override
    public void setValueAt(Object value, int row, int col)
    {
        List<Object> allRow = this.data.get(row);
        allRow.set(col, value);
    }

    @Override
    public boolean isCellEditable(int row, int col)
    {
        //  if(col == 3){       //set column with id=3 to be not editable
        //      return false;
        //  }
        return false;//true;
    }

    public boolean isDataNull()
    {
        if(this.data == null)
            return true;
        return false;
    }

    @Override
    public int getColumnCount()
    {
        return columnNames.size();
    }

    @Override
    public String getColumnName(int col)
    {
        return columnNames.get(col);
    }

    @Override
    public int getRowCount()
    {
        return data.size();
    }

    @Override
    public Object getValueAt(int row, int col)
    {
        if(data.get(row).isEmpty())
            return null;
        return data.get(row).get(col);
    }
}

And here you have a very simple use example.

ObjectDataTableModel tm = new ObjectDataTableModel();
        String[] columnNames = new String[]
        {
            "1", "2", "3"
        };//, "4", "5", "6", "7"};
        tm.setColumnNames(Arrays.asList(columnNames));
        int rNo = 30;
        List<List<Object>> data = new ArrayList<List<Object>>(rNo);
        int cNo = columnNames.length;
        for(int i = 0; i < rNo; i++)
        {
            List<Object> r = new ArrayList<Object>(cNo);
            for(int j = 0; j < cNo; j++)
                r.add("i=" + i + ", j=" + j);
            data.add(r);
        }
        tm.setData(data);

I recommend it for you to have such a model always somewhere, e.g. in a utility package, available and ready to use. You will see how often such simple model you will find useful. This one is perfect for displaying any type of data.

All the best, Boro.

查看更多
祖国的老花朵
6楼-- · 2019-08-10 04:26

The easiest solution is to create a DefaultListModel and then iterate through the ArrayList adding your State objects into the list model as you go. Then use this model as the model of your JList. If on the other hand you want to use the ArrayList in the model, then you'll likely need to create a class that extends AbstractListModel class, but be ready to have to flesh out more of the methods of this class for it to work well.

查看更多
登录 后发表回答