is Jlist Override the List automatic? (bug)? - java

I hope I will get help, I will ask as general question:
I am using a JList, and due to the JList not have a (value,text) (so I can display text and use the value in my code). Because of this leak I create List of object (myList), that work parallel with the JList. Every item I add to JList I add to myList, so the same index will contain the same info in the two objects (JList and mylist)
I use the JList.getselectedindex() method to get the index and use it in myList to pup information...
The problem: is when I select value, the next value of the myList is overridden with the first value!!!
Is this problem known?
mod_mp = new ModelMAPPING(); objects cotain values that ot exist in jList
msgF.setTo(incom.userID);/////// set parter!
if(isExCon==-1) {
// not exist
mod_mp.to = incom.userID; // incom is object that incom from another program
mod_mp.SetCovFile(incom.userID+".html");
mod_mp.ConvName = incom.getBody();
boolean added= model_list.add(mod_mp); // add to mylist
if(added) System.out.println(mod_mp._Hfile + " added");
model.addElement(mod_mp.ConvName);// add to Jlist by model
HestoryFile(Htmlhead+tohis,mod_mp._Hfile);//create _Hfile and write to it:"tohis" string.
} else { //exist#
// note isExcon return the index if exist else -1
model_list.get(isExCon).ConvName=incom.getBody();
mod_mp.SetCovFile(model_list.get(isExCon)._Hfile);
HestoryFile(tohis, model_list.get(isExCon)._Hfile);
}//end else
Here if file exists I just update the new text in the JList and set the current file
The select of JList is:
msgF.setTo (model_list.get(jList2.getSelectedIndex()).to); // set that we will send To...
mod_mp.SetCovFile(model_list.get(jList2.getSelectedIndex())._Hfile);//set the file
jLabel5.setText( bringFromFile(mod_mp._Hfile));//tell the label to read that file
It works fine, but when I have two items in JList if I select any, the other is overridden!!!

I am using a JList, and due to the JList not have a (value,text) (so I
can display text and use the value in my code)
It's really hard to understand your problem, but I "suspect" for the quoted line that you have a missunderstanding between JList model and text displayed by the JList itself. I think that's why you have a separate List.
The model can contain any object you want and the JList can also display a text as you want regardless the object itself. This last task is done by a ListCellRenderer. Take a look to Writing a Custom Cell Renderer
For instance you can have this class:
class Person {
String lastName;
String name;
public Person(String lastName, String name){
this.lastName = lastName;
this.name = name;
}
public String getLastName(){
return this.lastName;
}
public String getName(){
return this.name;
}
}
Now you want your JList keep Person objects to work with them later. This part is easy just create a ListModel and add elements into it:
DefaultListModel model = new DefaultListModel();
model.addElement(new Person("Lennon","John"));
model.addElement(new Person("Harrison","George"));
model.addElement(new Person("McCartney","Paul"));
model.addElement(new Person("Starr","Ringo"));
But you want to display the name and last name of each Person. Well you can implement your own ListCellRenderer to do this:
JList list = new JList(model);
list.setCellRenderer(new DefaultListCellRenderer(){
#Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(value instanceof Person){
Person person = (Person)value;
setText(person.getName() + " " + person.getLastName());
}
return this;
}
});
And your JList will show the items as you want:

Related

How do I update the quantity of an item without spawning a new object inside my JList

I want the quanitity shown in (*) to update the value whenver I select an item from the JList and change the quantity of the item without spawning another object in the list.
public void saveList() {
if(fieldValidate()) {
String name = nameText.getText();
Integer quantity = Integer.parseInt(quantityText.getText());
boolean bool = nextDayDelivery.isSelected();
String type = itemTypeBox.getSelectedItem().toString();
UUID productID = UUID.fromString(productIDText.getText());
Product newItemInput = new Product(productID, name, type, quantity, bool);
data.addElement(newItemInput);
newItem();
}
}
I've been trying for days and I have hit a brick wall now.
Updated to fix bad link
A search of the web for "update jlist item edited value" yields Java - Updating JList after changing an object

JComboBox fill with enum variable value

I have a JComboBox that I made this way, using an enum for its values:
JComboBox<StudyGrade> maxLevelOfStudiesCombo = new JComboBox<StudyGrade>(StudyGrade.values());
The enum looks like this:
public enum StudyGrade {
ELEMENTARY ("Primaria"),
MIDDLE ("Secundaria"),
MIDDLE_HIGH ("Preparatoria"),
HIGH ("Universidad"),
MASTERS ("Maestría / Posgrado"),
DOCTORATE ("Doctorado"),
POST_DOCTORATE ("Post Doctorado");
private String studies;
private StudyGrade(String studies) {
this.studies = studies;
}
public String getStudies() {
return studies;
}
public void setStudies(String studies) {
this.studies = studies;
}
#Override
public String toString() {
return studies;
}
}
As you can see I'm overriding the toString() method, so I can have the studies values shown instead of the enum ones...
However I want to show the studies values only in the JComboBox not everytime I use the StudyGrade enum.
How would I change the code, so whenever I use something like:
System.out.println(StudyGrade.HIGH);
I get printed HIGH instead of Universidad, but not for the JComboBox?
I'm overriding the toString() method, so I can have the studies values shown instead of the enum ones...
I've never used a enum before but I assume you can use it like any custom object added to the combo box so you should be able to use a custom renderer so you can control which data is displayed by the combo box.
Check out Combo Box With Custom Renderer for more information and a helper class.
You're looking to extend an enum, but that's impossible. It means that something is wrong with your requirement.
Rendering is done in the UI component, and it's not enum's business to deal with presentation of data. You should make you UI component render enum the way you'd like instead of trying to make enum understand where it's being used. Since you're a Swing fanatic you should know how to do that, something like this:
maxLevelOfStudiesCombo.setRenderer(new DefaultListCellRenderer() {
#Override
public Component getListCellRendererComponent(JList<?> jList, Object o, int i, boolean b, boolean b1) {
Component rendererComponent = super.getListCellRendererComponent(jList, o, i, b, b1);
setText(o instanceof StudyGrade ? ((StudyGrade) o).getStudies() : o.toString());
return rendererComponent;
}
});
That's going to do that.
You could just remove the toString override as the default toString for an enum is to return the name of the enum element.
And you could just have a simple for loop that would iterate through the values in your enums and add it to a string array. Then, you would need to pass that array as the argument for your JComboBox and it should be gold.
The code for it should look a bit like that:
//get all study grades
StudyGrade[] temp = StudyGrade.values();
//create a string array of same length as the array
String[] str = new String[temp.length];
//append all the studies value to the string array
for(int i = 0; i< temp.length; i++){
str[i] = temp[i].getStudies();
System.out.println(temp[i]);//debug
}
System.out.println("---------------------");//debug
for(String s : str){//debug
System.out.println(s);//debug
}//debug
//pass it
JComboBox<StudyGrade> maxLevelOfStudiesCombo = new JComboBox<StudyGrade>(StudyGrade.values());
Here is an example I made on repl.it
https://repl.it/GH28/1

Object in JComboBox in JTable is not associated with same object in combo list

my problem is that when I put Object to table in cell with CellEditor set to work as JComboBox and it's fine, but when click on the cell i got list with Objects, but selected one is not that which were in cell before, but just first on the list. Is there simple way to fix it?
public void setValueAt(Object value, int row, int col) {
data.get(row).values.set(col, (Device) value);
fireTableCellUpdated(row, col);
}
and
for(int i = 0; i < deviceTable.getModel().getColumnCount(); i++){
ExtendedAbstractTableModel model = (ExtendedAbstractTableModel) deviceTable.getModel();
JComboBox<Device> combo = new JComboBox<Device>();
for(Device value : model.columnsCombo.get(i)){
combo.addItem(value);
}
TableColumn columnModel = deviceTable.getColumnModel().getColumn(i);
columnModel.setCellEditor(new DefaultCellEditor(combo));
}
As shown in this example, DefaultCellEditor handles this for you. You're adding multiple instances in a loop; a single instance can handle the entire column. DefaultCellEditor works by overriding setValue() in the nested EditorDelegate. It's not clear how you've defeated this feature, but understanding the default may guide your search.
public void setValue(Object value) {
comboBox.setSelectedItem(value);
}
Finally I found what was wrong. I didn't override equal method in my class, and that is why these components couldnt recognise same item. Anyway, thank you all.

How to update the string name of an item inside a DefaultListModel [duplicate]

This question already has answers here:
Java - Updating JList after changing an object
(3 answers)
Closed 8 years ago.
I have a Jlist with a DefaultListModel with data from XML.
I want to be able change the name of the item in the Jlist. but the DefaultListModel has no update method.
So if the user clicks on a name it should edit the name.
So far I thought if I get the location of the item and remove it and update with new data. But if I update with then new name will it be put in the same location as the old or will things be messed up ?
My code :
private class EditName extends AbstractAction {
public EditName() {
putValue(NAME, "Change Name");
putValue(SHORT_DESCRIPTION, "Some short description");
}
public void actionPerformed(ActionEvent e) {
int x = objTypeJList.getSelectedIndex();
String newName = JOptionPane.showInputDialog("New Name?");
if (x >= 0) {
String oldName = ReadXMLFile.getInstance().getModel().getElementAt(x).toString();
ReadXMLFile.getInstance().getModel().removeElementAt(x);
objTypeJList.setModel(ReadXMLFile.getInstance().getModel());
}
// newText I wanna add into the the location I edit
}
}
"I want to be able change the name of the item in the Jlist. but the DefaultListModel has no update method."
What makes you say that? Have you looked carefully at the docs ?
What do you think this method does?
public void setElementAt(E element, int index) - Sets the component at the specified index of this list to be the specified element. The previous component at that position is discarded.
OR
public E set(int index, E element) - Replaces the element at the specified position in this list with the specified element.

jList - Add element and show String?

what's up?
I created one jList on my project that I can't retrieve the element. I know jList only accepts objects, but I was adding Strings to my list, because when I add "Discipline" object, I see something like "Discipline{id=21, name=DisciplineName}" on my view. So, I'm adding strings instead objects.
Following is my code:
ArrayList<Discipline> query = myController.select();
for (Discipline temp : query){
model.addElement(temp.getNome());
}
When I get the index of a double click in one element, I try to retrieve my String to make a query and know what's this discipline. But I'm getting some errors, see what I already tried:
Object discipline = lista1.get(index);
// Error: local variable lista1 is accessed from within inner class; needs to be declared final
String nameDiscipline = (String) lista1.get(index);
// Error: local variable lista1 is accessed from within inner class; needs to be declared final
I really don't know what means "final", but what can I do to solve this problem? One thing that I thinked is:
Can I add a Discipline instead String, show to user discipline.getName() and retrieve Discipline object?
Yes, add Discipline objects. A quick fix is to change Discipline's toString method, but a much better fix is to create a ListCellRenderer that displays each Discipline's data in a nice String.
Here are two ListCellRenderers that I have used in a project of mine to change the item displayed in my JList from text to an ImageIcon:
private class ImgListCellRenderer extends DefaultListCellRenderer {
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
if (value != null) {
BufferedImage img = ((SimpleTnWrapper) value).getTnImage();
value = new ImageIcon(img); // *** change value parameter to an ImageIcon
}
return super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
}
}
private class NonImgCellRenderer extends DefaultListCellRenderer {
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
// all this does is use the item held by the list, here value
// to extract a String that I want to display
if (value != null) {
SimpleTnWrapper simpleTn = (SimpleTnWrapper) value;
String displayString = simpleTn.getImgHref().getImgHref();
displayString = displayString.substring(displayString.lastIndexOf("/") + 1);
value = displayString; // change the value parameter to the String ******
}
return super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
}
}
They are declared like so:
private ListCellRenderer imgRenderer = new ImgListCellRenderer();
private ListCellRenderer nonImgRenderer = new NonImgCellRenderer();
And I use them thusly:
imgList.setCellRenderer(imgRenderer);
The DefaultListCellRenderer is pretty powerful and knows how to display a String or an ImageIcon correctly (since it is based off of a JLabel).

Categories