This question already has answers here:
JList.getModel() ClassCastException
(4 answers)
Closed 6 years ago.
I have implemented a button that will simply delete a "contact" in the JList contactList. What the program is supposed to do is if the button deletes "Broadcast", which is the first element in contactList, will return an error by outputting a display message. Otherwise, it is supposed to simply remove the contact from the contact list.
My question is how do I delete the contact from the JList using DefaultListModel correctly? I saw that DefaultListModel needs to be used because remove function isn't in JList nor ListModel.
What the example contact list of size 4 may look like:
[Broadcast]
[Andro]
[Denis]
[Micheal]
...
This is the error:
[java] Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JList$4 cannot be cast to javax.swing.DefaultListModel
... //rest of error
Code:
private JList<String> listContacts;
//constructor:
listContacts = new JList<String>(controller.getContacts());
//gets contact list from controller class which gets contact list from client class.
listContacts.setModel(new DefaultListModel());
JButton deleteUser = new JButton("Delete User");
menuPanel.add(deleteUser,BorderLayout.EAST);
deleteUser.addActionListener(new MyButtonListener5());
class MyButtonListener5 implements ActionListener{
public void actionPerformed(ActionEvent e){
DefaultListModel<String> list = (DefaultListModel)(listContacts.getModel());
String contact = listContacts.getSelectedValue();
int j = -1;
for(int i = list.getSize()-1; i >= 0; i--){
if(list.getElementAt(i).equals("Broadcast")) {
controller.displayMsg("[ERROR] You cannot delete broadcast\n");
}
else if(list.getElementAt(i).equals(contact)){
j = i;
}
}
if(j != -1){
list.remove(j);
}
}
(DefaultListModel)list.remove(j);
list.remove() returns the item that was removed from the list, which in your case is a String. Why are you casting it to a DefaultListModel?
or did you really mean
((DefaultListModel<String>)list).remove(j);
which casts "list" to a DefaultListModel, and then calls that model's remove() method. But "list" is already declared as a DefaultListModel, so the cast is superfluous.
Just get rid of the cast.
Related
This question already has answers here:
How to fill a List of Lists?
(3 answers)
Working with a List of Lists in Java
(8 answers)
Closed 5 years ago.
So I'm trying to create "piles" of cards in a class called Table using an ArrayList with stacks inside of it that contain the card objects (which are defined in a separate class).
I initialized it like so:
private MyArrayList<MyStack<Card>> piles;
public Table()
{
MyStack<Card> piles = new MyStack<>();
}
My issue is that I can't figure out how to add things to and from the stack inside the ArrayList. Is my initialization of it wrong? If so, how can I fix it?
Note: MyArrayList and MyStack are just slightly different versions of ArrayList and Stack essentially.
The variable names are a little confusing. Consider:
// private MyArrayList<MyStack<Card>> piles;
private final ArrayList<Stack<Card>> allPiles;
public Table() {
// MyStack<Card> piles = new MyStack<>();
allPiles = new ArrayList<>();
}
then you can do something like this:
public void addCardToPile(Card card, int pileIndex) {
while (allPiles.size() < pileIndex) {
allPiles.add(new Stack<Card>());
}
allPiles.get(pileIndex).push(card);
}
public Card getTopCardFromPile(int pileIndex) {
while (allPiles.size() < pileIndex) {
allPiles.add(new Stack<Card>());
}
if (allPiles.get(pileIndex).isEmpty()) {
return null;
}
return allPiles.get(pileIndex).pop();
}
But it's not clear if ArrayList is the most appropriate here. Consider a Map<Integer, Stack<Card>> allPiles, and instead of pileIndex have something like pileNumber. Or Map<String, Stack<Card>> allPileswith pileName.
Iterate through the list here piles, push card in the Stack.
for (MyStack cards: piles) {
cards.push(new Card);
}
I'm using a JList which displays correctly. However, I'm having trouble removing elements from the list.
JList nameList = new JList(db.getAllNames());
nameList.setVisibleRowCount(6);
nameList.setFixedCellWidth(400);
JButton removeNameButton = new JButton("Remove Name");
removeNameButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
String id = nameList.getSelectedValue().toString(); //valid value when button pressed
int index = nameList.getSelectedIndex(); //valid value when value pressed
namesList.remove(index); //ERROR
}
The JList contains 4 names, which displays perfectly and seem to have the correct indexes. (If I check the value System.out.println(copiersList.getModel().getSize()); it always displays 4
Here is the error message:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 3
Oddly, if I remove Adam, I do not get an error (but visibly the list does not change and calling .getSize() method displays 4):
id selected: Adam
index selected: 0
However, any other:
id selected: BobException in thread "AWT-EventQueue-0"
index selected: 1
java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 1
at java.awt.Container.remove(Unknown Source)
Don't remove from the JList itself since the remove(...) method does not do what you think that it does. It in fact is trying to remove a component that is held in the JList as if it were a JPanel that held other components, even if no such component exists. Instead remove from the JList's model, usually a DefaultListModel. The DefaultListModel class has a removeElement(Object element) and a removeElementAt(int index) method that can help you.
i.e.,.
public void actionPerformed(ActionEvent e) {
String id = nameList.getSelectedValue().toString(); //valid value when button pressed
int index = nameList.getSelectedIndex(); //valid value when value pressed
DefaultListModel listModel = (DefaultListModel) namesList.getModel();
listModel.removeElementAt(index);
}
In the code below, I attempted to create a DefaultListModel object to use for my JComboBox.
Apparently, the setModel() method only accepts a object that is a ComboBoxModel. I attempted to convert it, and I got the exception, java.lang.ClassCastException.
I already searched up how to fix this specific problem, but I couldn't find anything helpful.
I then tried to create a ComboBoxModel object instead, yet I learned that this class is abstract. How can I bypass this problem, and get the valid argument for setModel()?
private void setComboBoxYears(int numberOfYears, JComboBox comboBox) {
DefaultListModel<Integer> years = new DefaultListModel<>();
for(int i = 1; i <= numberOfYears; i++)
years.addElement(i);
comboBox.setModel((ComboBoxModel) years);
If you are looking for solution then try in this way:
final JComboBox<Integer> comboBox = new JComboBox<Integer>();
Integer[] years = new Integer[numberOfYears];
for (int i = 0; i < numberOfYears; i++)
years[i] = i + 1;
comboBox.setModel(new DefaultComboBoxModel<Integer>(years));
Use a DefaultComboBoxModel instead.
Please have a look at the API as all of this information can be gleaned from it by a simple glance.
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.
For my Java project I am creating buttons from strings stored in an array as such:
public class UserInterface implements ActionListener {
ArrayList<CardButton> currButtonList; // Current list of card buttons used
public void createAndShowGUI(String[] allCards){
//unrelated to question code
//for each String in allCards[]
for(int i=0; i<allCards.length; i++){
//Assign the button names relative to which card has is being created
String name = allCards[i];
CardButton button = new CardButton(name);
//add the button to the CardPanel
button.setFaceDown();
button.setBorderPainted(false);
int width = button.getWidth();
int height = button.getHeight();
button.setSize( new Dimension( width, height ) );
//button.setPreferredSize(new Dimension(150, 150));
CardPanel.add(button);
currButtonList.add(button);
}
}
//rest of creating the Panels, more unrelated to question code
Code complies but:
Exception in thread "main" java.lang.NullPointerException
at memory_game.GameFunction.(GameFunction.java:47)
Which is where I try to assign listeners to each object in the array list.
Am I correct in assuming that the ArrayList is not having the buttons added to it correctly?
If so, why? How can I make this work?
You need to instantiate your ArrayList<CardButton>. This is wrong (because it leaves currButtonList undefined, that is null) -
ArrayList<CardButton> currButtonList; // Current list of card buttons used
Try this instead
// Current list of card buttons used
List<CardButton> currButtonList = new ArrayList<CardButton>();
Or you could add this to your UserInterface constructor(s) -
currButtonList = new ArrayList<CardButton>(); // Instantiate the currButtonList.
Finally, as for your subject line question - you seem to be doing that correctly with these lines -
CardButton button = new CardButton(name); // Create a new CardButton instance.
currButtonList.add(button); // Add it to the list (currButtonList was null, not button)
Are you ever instantiating your ArrayList like
ArrayList<CardButton> currButtonList = new ArrayList<CardButton>();
I don't believe ArrayList is an intrinsic type that will work without instantiating it.
Your arrayList is not initialized, default is NULL. That is why you get null pointer exception when you try to add button to currentButtonList variable.
Initialize your array with empty list as below.
ArrayList<CardButton> currButtonList = new ArrayList<CardButton>(); // Current list of card buttons used