I am making a JTable that uses an arrayList for data population. I have two sets of data in the arrayList. one for one type of table and another for another type of table.
What I am hoping to do is overload the getValueAt method on the abstractTableModel so that it takes in an argument to which set of data I want.
Is this possible or should I think about this a different way?
Nobody stops you from overloading the method. It's just that the JTable code won't call your new method. You will have to overwrite the regular public Object getValueAt(int rowIndex, int columnIndex) and call the other method from inside it, based on your business logic.
you can do so, however the problem is that whoever in Swing components is calling this method currently would not call the oveloaded one :)
It would not be too much usefull.
From my point of view, you have basically 2 options, as you need to present the specific data in 2 different table types:
either I'd go for 2 different table models and keep all the data separated
or the other approach might be to have some specific flag (new field) on model, that would indicate the table you use it in. This one could be set by setter or directly in constructor if you know which type you'd go for.
However the 1.st one would be a recommended way from my point of view.
There's nothing wrong with the accepted answer, but also consider a second TableModel that shares a reference to the given List with the first. A single JTable could display either model by simply invoking setModel().
In this exmaple, EnvDataModel obtains a its data via System.getenv(). A PropDataModel might obtain a its data via System.getProperties(). Both share access to System.
TableModel first = new EnvDataModel();
TableModel second = new PropDataModel();
JTable table = new JTable(fisrt);
...
table.setModel(second);
Related
Problem
I want to know if this is possible if I could create a State machine that would contain all the methods and the Values of MethodById would be stated in the machine.
P.S. this is my first question ever on here. If I do it wrong I'm sorry but that is why.
Description (TL;DR)
I'm trying to cross reference data about Sales representatives. Each rep has territories specified by zip-codes.
One dataset has the reps, their territories and their company.
Another data set has their names, phone number and email.
I made a Sales-rep class that takes from the first data-set and needs to be updated with the second data-set.
I also need the Sales-reps to be put in a look-up table (I used a hashmap for this) of <key: zip code, value: Sales-rep object>.
What I want is for each Sales-rep object to having an ID that is standard across all my datasets. I can't use the data I'm provided with because it comes from many different sources and its impossible to standardize any data field.
Names, for example, are listed so many different ways it would be impossible to reconcile them and use that as an ID.
If I can get an ID like this (something like an SSN but less sensitive) then I want to try what my question is about.
I want to iterate through all the elements in my <key: zip code, value: Sales-rep object> hashmap, we will call it RepsByZipCode. When I iterate through each Salesrep object I want to get an ID that I can use in a different hashmap called MethodById <key: ID, value: a method run on the Object with this ID>.
I want it to run a different method for each key on the Object with the matching key (AKA the ID). The point is to run a different method on each different object in linear time so that by the end of the for loop, each object in RepsByZipCode will have some method run on it that can update information (thus completing the cross-referencing).
This also makes the code very extendable because I can change the method for each key if I want to update things differently. Ex:
//SalesRep Object Constructor:
SalesRep(String name, String email, ..., String Id)
Map<String zipcode, Salesrep rep> RepsByZipCode = new HashMap<>{}
//code fills in the above with the first dataset
Map<String ID, ??? method> MethodById = new HashMap<>{}
//code fills in the above with the second dataset
for(String ZipKey:RepsByZipCode){
Salesrep Rep = RepsByZipCode.get(ZipKey);
Rep.getId = ID;
MethodById.get(ID);
//each time this runs, one entry in RepsByZipCode is updated with one
//method from MethodById.
//after this for loop, all of RepsByZipCode has been updated in linear time
You could put these methods into different classes that implement a common interface, and store an instance of each class in your map. If you're using at least Java 8 and your methods are simple enough, you could use lambdas to avoid some boilerplate.
I have implemented my own ComboBoxModel:
public class MyComboBoxModel extends AbstractListModel<MyType>
implements ComboBoxModel<MyType> {}
Now I obviously need to override public void setSelectedItem(Object item), but the documentation says the following:
The implementation of this method should notify all registered ListDataListeners that the contents have changed.
To do so, I guess I need to use the method AbstractListModel.fireContentsChanged(Object, int, int). The Problem with JComboBox is, that one can set the selected item without it having to be in the list, so when setSelectedItem(Object) is called, I cannot necessarily determine the index of the item in question, since it need not be in the underlying model.
I found an answer to another question (https://stackoverflow.com/a/7077192) which uses fireContentsChanged(item, -1, -1) in this case, but the person did not provide any details to that part of code. Now I am wondering, whether this was the correct way to deal with a changed selected item?
Should I ALWAYS use -1 as both indexes? Should I try and get the real index of an item, if it is actually in the model? Or should I do something entirely different?
I want to open a configuration screen and send back its data when user clicks ok.
I have these objects as configurations
configObjA a;
configObjB b;
Both implement IDisplayable (my interface).
Now the congfig screen gets two ArrayLists and put them in JLists gui.
it itterates the JList and put them in datamodel.
when I return from the screen , I want to send the main screen the results.
So I re-iterate the datamodel and put it all back in an arraylist
the problem is the main screen doesnt know anything about
Is there a way my configuration screen would return a type that the main screen will know?
I thought of returning
public List getOptionsList()
and in the method I wil create a list of the type I sent. (I would then have to keep the type i sent ). is that any good? how do i create a generic list when the type is of unknown
object type? any suggestion ?
btw: isnt my foolish gui process too complicated for that simple need?
how do i create a generic list when the type is of unknown object type?
You cannot. The whole point of generic lists is that you do know the object type at compile-time, so that the compiler can check your usage of that list.
If you know at least a parent class or interface (which is the usual case actually), you can use that:
List<IDisplayable> l;
If it can be any type of object, you can only say
List<Object> l;
which will accept any kind of Object, but removes the potential for meaningful compile-time type checking.
You can create a generic list of an unknown type, but you can't really put objects in them.
public <T> List<T> makeList() {
return new ArrayList<T>();
}
Of course, the method using this method then has to know the type, and can only put objects of this type in.
In your case, the problem seems to be that you want to misuse the JList as a data container. It is not, it is a view component. Use a real data structure for your logic, and wrap it in a ListModel to provide your list with data to show.
Ok, so I am working on a homework assignment, and I am using SWING to make a GUI for a Java project, and I am running into troubles with JList.
I have a customer object that I have made and set attributes to, and I want to add the object into a TreeMap. I want to hook up the Treemap so that any and all objects that are in the map will populate (the name attribute anyway) inside of the JList.
I have done a lot of looking around, and am seeing a lot about coding these things from scratch but little dealing with Swing implementation. I put my customer object into my map and then I would like for my JList to reflect the map's contents, but I don't know how to hook it up.
customers.put(c.getName(), c);
this.customerList.(What can I do here? add Customer object?? I can't find what I need);
Thanks for your help!!!
You need to create a custom list model that returns objects to put in each row of a JList. TreeMap can't be accessed with an index, so you'll need something else. So the general idea is this: (from JList javadoc):
ListModel bigData = new AbstractListModel() {
ArrayList customers;
public int getSize() { return customers.size() }
public Object getElementAt(int index) { return customers.get(index); }
};
JList bigDataList = new JList(bigData);
this way when you update your collection, just call revalidate() or repaint() on the JList and it will update its contents too.
so I am working on a homework
assignment
So what exactly is the assignment about? You've given us your attempted solution, but since we don't know the actual requirement we can't tell if you are on the right track or not.
Are you forced to use a TreeMap to store the objects? Because this is not a good collection to use for your ListModel since you can't access the objects directly.
Or is the assignment simply about displaying data from an object in a JList? If so then you can use the DefaultListModel. All you need to do is override the toString() method of you custom object to have the "name attribute" show in the list.
I'm missing something obvious here.
I have a glazedlists EventList<X> where X is my custom class. This list contains a bunch of values. When I update one of the values, how do I make sure the GUI updates its display for that row?
It looks like you can invoke addListEventListener to register a ListEventListener. See also the Glazed Lists Tutorial.
The FAQ mentiones two ways under the question:
How do I tell Glazed Lists that an Object in my EventList has been updated?
Either you use the get/set approach as pointed out by Jason, or you make the elements in the list observable by for instance the PropertyChangeListener and then use the ObservableElementList. I think this second approach is cleaner and it should also work with concurrent threads.
The way to do this appears to be to replace the list element with itself:
EventList<X> list = /* get reference to a list */
X x = list.get(3);
/* update x here */
list.set(3,x);