This question already has answers here:
Why is itemStateChanged on JComboBox is called twice when changed?
(10 answers)
Closed 6 years ago.
I've built a combobox that is dynamically populated depending on the contents of another combobox, and so on. I've decided, although it's a bit terrible, to experiment with iterating through the contents of the source array when populating the target combobox. However, although this results in combobox contents, they are repeated. I've stepped through the code, and the array is only being iterated through once.
private JComboBox regBuildingSelectBox;
...
String[] siteSelectStrings = {"Site", "London", "Long Island"};
JComboBox regSiteSelectBox = new JComboBox(siteSelectStrings);
regSiteSelectBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent arg0) {
getDropDownVariables gddv = new getDropDownVariables();
for(String s:
gddv.buildingSelectList
(regSiteSelectBox.getSelectedItem().toString()))
{
regBuildingSelectBox.addItem(s);
}
}
});
regSiteSelectBox.setBounds(24, 336, 282, 20);
contentPane.add(regSiteSelectBox);
regBuildingSelectBox = new JComboBox();
regBuildingSelectBox.setBounds(24, 367, 282, 20);
contentPane.add(regBuildingSelectBox);
The code containing the arrays is as follows:
public class getDropDownVariables {
public String[] buildingSelectList(String site)
{
switch (site)
{
case "London":
return new String[] {"Building", "Harvell",
"LYNX Complex", "Caroline", "Salters"};
case "Long Island":
return new String[] {"Building", "Phillips", "Pascal"};
}
return new String[] {"Failed to populate buildings"};
}
And the result:
Just a guess, but before you call regBuildingSelectBox.addItem(s); you probably have to clear it first, otherwise it just keeps adding to the list rather than replacing it. There allso might be a different method that sets the values vs adding.
Related
I'm trying to load an array, that I've read in from a text file, to be displayed as a JList. This is the method I have for loading the elements from the array into the JList
private JList stockList;
private JButton LoadStock;
DefaultListModel<String> model;
stockDataManager stockdataManager = new stockDataManager();
ArrayList<stock> shopStock = stockdataManager.getShopStock();
public void UpdateJList() {
stockdataManager.load();
model = new DefaultListModel<String>();
model.clear();
for (stock p : shopStock) {
model.addElement(p.toString());
}
stockList.setModel(model);
stockList.setSelectedIndex(1);
}
The ArrayList is referenced from another class.
private final ArrayList<stock> shopStock = new ArrayList<>();
public ArrayList<stock> getShopStock(){
return shopStock;
}
However every time I click the load button to load in my stock onto the JList, it will duplicate it, due to the fact I'm having an add and edit function. This means whenever I add new stock onto the array and try to update it, it's pasting in all the elements again but with new memory tags. Another issue I'm having is that it displays the array elements as their memory tags and not their string format.
I have not been using Java for very long and I'm pretty new to it so sorry if it's scuffed.
I'm trying to create an ArrayList of String[], but can't get it to add more than one item. Ultimately I want to extract the items from the ArrayList and send them to a JTable. The program is 5 separate classes, but here's the applicable code for this issue:
static JComboBox<String> foodChoice;
DefaultTableModel foodList;
static String[] newFood;
static List<String[]> foodData;
JTextField newFoodText, portionText, carbsText;
public Main() {
void createFood() {
String[] foodProperties = new String[3];
foodProperties[0] = newFoodText.getText();
foodProperties[1] = portionText.getText();
foodProperties[2] = carbsText.getText();
Main.createFood(foodProperties);
}
static void createFood(String[] foodArray) {
foodData = new ArrayList<String[]>();
foodData.add(foodArray);
foodChoice.addItem(foodArray[0]);
}
void addFoodToTable() {
String[] s = new String[3];
s = (String[]) foodData.get(foodChoice.getSelectedIndex());
System.out.println(foodData.get(0));
System.out.println(foodData.get(1));
}
addFoodToTable gets called with a button click. So the issue I'm having is that (based on the sysouts) I will get a pointer address to the first entry in the ArrayList, but then a Null Pointer Exception stating that it is out of bounds for Length 0 when it tries to print the second one to console. This is obviously after calling createFood() 3 or four times in order to populate foodData. I can provide additional code if required, it's just too much to place in whole into this post. Thanks!
you clear out foodData every time you call createFood remove this line:
foodData = new ArrayList();
and move the initialization to a static level , like this:
static JComboBox<String> foodChoice;
DefaultTableModel foodList;
static String[] newFood;
static List<String[]> foodData = new ArrayList<String[]>();
JTextField newFoodText, portionText, carbsText;
public Main() {
void createFood() {
String[] foodProperties = new String[3];
foodProperties[0] = newFoodText.getText();
foodProperties[1] = portionText.getText();
foodProperties[2] = carbsText.getText();
Main.createFood(foodProperties);
}
static void createFood(String[] foodArray) {
foodData.add(foodArray);
foodChoice.addItem(foodArray[0]);
}
void addFoodToTable() {
String[] s = new String[3];
s = (String[]) foodData.get(foodChoice.getSelectedIndex());
System.out.println(foodData.get(0));
System.out.println(foodData.get(1));
}
Every time you call createFood(String[] foodArray) you create a new List instead of just adding the incoming item to the existing list.
Create the ArrayList in a different place and remove the line from the createFood method and it should work fine.
Worked like a charm. Man I don't know how I missed that... I guess when you look at the same problem for too long you miss the obvious. Thanks guys!
I miss something and I will appreciate your help
I have this array for a combobox
String array [] = {"aa", "bb", "cc"};
and I have this for loop to run all over the array
for(String s: array) {
if(s.equals(array[0]) {
//do something
}
}
Now what I need is that, I need the "do something" to happen to each element in the array only when the element is selected by the combobox, my array is so long and I can't write if statement for each element in the array.
What I want is something like that
for(String s : array) {
if(s equals the array elements) {
substring the first index of each element
print s
so result let's say will be like this
a ----> if only element a is selected
b ----> if only element b is seleceted
etc ...
}
}
As px06 said, you might want to add an event listener on your Combobox and then handle item selection.
Here is code snippet for what you are looking for:
String[] array = {"aa", "bb", "cc"};
JComboBox comboBox = new JComboBox(array);
comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
JComboBox<String> combo = (JComboBox<String>) event.getSource();
String selectedItem = (String) combo.getSelectedItem();
if (selectedItem.equals("<some-choice>")) {
//do something
} else if (selectedItem.equals("<some-other-choice>")) {
//do something else...
}
}
});
However I do not see how you can escape checking which item was selected if you want to do something specific based on selection.
I hope this helps.
This fixed my problem, thank you all and sorry for disturbing you
for(String s: arrar) {
if(combobox.getSelectedItem().equals(s)) {
do something;
}
}
I am trying to make a button that, when multiple rows in a TableView are selected, all of the selected rows are removed.
I am creating an observable list using getSelectedIndicies and it isn't working right.
If I select the first three rows, I have it print out the indicies as it removes them and it prints 0,1 and then it removes the first and third row, but the middle of the three rows is not removed.
delBtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
ObservableList<Integer> index =
table.getSelectionModel().getSelectedIndices();
for (int location: index) {
System.out.println(location);
data.remove(location);
}
table.getSelectionModel().clearSelection();
}
});
For some reason, this works:
b.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
List items = new ArrayList (treeTable.getSelectionModel().getSelectedItems());
data.removeAll(items);
table.getSelectionModel().clearSelection();
}
});
I doubt that the internal implementation of the selectedItems list ( com.sun.javafx.collections.ObservableListWrapper ) might have some bug.
Edit
Yes it's definitely a bug: https://javafx-jira.kenai.com/browse/RT-24367
Removing using index can't work since at each suppression the remaining indexes change.
You could remove the selectedItems :
delBtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
data.removeAll(table.getSelectionModel().getSelectedItems());
table.getSelectionModel().clearSelection();
}
});
You can use a for loop, it make a snapshoot of your table selection and iterate in it. For exmple:
#FXML
private void deleteButtonFired(ActionEvent actionEvent) throws InterruptedException {
for(Object o : table.getSelectionModel().getSelectedItems()){
table.getItems().remove(o);
}
table.getSelectionModel().clearSelection();
}
I hope they fix this bug.
I came across a similar issue using ListView (selectedView in my case) and also guessed items were removed by indices. So I gave up on using a loop looking like the following
selectedView.getSelectionModel().getSelectedItems().forEach(i -> selectedView.getItems().remove(i));
changing it to
selectedView.getItems().removeAll(selectedView.getSelectionModel().getSelectedItems());
which worked just fine. Hope this helps anybody.
There is a way round this, using getSelectedIndices(), as the OP originally required. Here is the solution:
ArrayList<Integer> list = new ArrayList<>(listView.getSelectionModel().getSelectedIndices());
Comparator<Integer> comparator = Comparator.comparingInt(Integer::intValue);
comparator = comparator.reversed();
list.sort(comparator);
for(Integer i : list) {
listView.getItems().remove(i.intValue());
}
This works because it sorts the indices in descending order, and so only removes the highest index first so that the indices of other items to be removed are not changed as a result of the removal.
Sometimes you can't use the getSelectedItems() and removeAll(...) functions because removeAll will remove all occurences of the referenced objects. What if your list contains multiple entries with the same referenced object, and you only want to remove one of those references? That's why you need to use the getSelectedIndices() function.
I have a combo box and a string array that holds all the values of the combo box in it. I erase the items from the combo box and then want to add in the values from the string array. It doesn't seem to let me just add in a string array. And I tried to itterate through the string adding items one by one but won't let me do that (or atleast the way I wrote it, it won't work).
May seem like a stupid question but I am new to working with swing in java.
Here's the code where I want to "reload" the items from the combo box:
String str = JOptionPane.showInputDialog(null, "Enter Name: ", "", 1);
if(str != null){
JOptionPane.showMessageDialog(null, "New name added: " + str, "", 1);
nameCreator.addName(strNames, str);
strNames = NameLoader.getNames();
nameList.removeAllItems();
nameList.addItem(strNames);
}
EDIT: Made small typo and didn't realize what was wrong. Working now. Thanks for everyones help.
Did you used the method addItem(Object anObject)?
You should iterate your array an use that method:
String[] data = {a;b;c;d;e}
for(int i=0; i < data.length; i++){
comboBox.addItem(data[i]);
}
Luca
I'd suggest you to implement your own ComboBoxModel:
public class YourComboBoxModel implements ComboBoxModel{
#Override
public Object getSelectedItem() {
//return selected item Object;
}
#Override
public void setSelectedItem(Object anItem) {
//set selected item
}
#Override
public Object getElementAt(int index) {
//return the element based on the index
}
#Override
public int getSize() {
//return the size of your combo box list
}
}
And build your JComboBox passing that model as parameter:
ComboBoxModel yourModel = new YourComboBoxModel();
JComboBox yourComboBox = new JComboBox(yourModel);
Using a custom ComboBoxModel is the most flexible solution. It allows you to change the datastructure holding your datas, and the way you access it, modifying only the model you implemented instead of other unrelated part of code.
Whenever you need to work with editable models for these kinds of GUI elements it is always good to use a model. For the JComboBox you have an easy-to-use DefaultComboBoxModel.
It works easily:
DefaultComboBoxModel model = new DefaultComboBoxModel(new String[]{"Item1","Item2","Item3"});
JComboBox comboBox = new JComboBox(model);
in this way you have the model attached to the combobox, and it will display items from the array. Whenever you need to change them just do:
model.removeAllElements(); // if you need to empty it
model.addElement("New Item1");
model.addElement("New Item2");
model.addElement("New Item3");
model.fireContentsChanged();
and you'll have new items updated inside the GUI.
A bonus note: if you need to manage custom objects instead that strings you can easily add them to the JComboBox (in the sameway showed before), you just need to provide a custom public String toString() method that will manage the string representation.
In your example I don't get why you readd all the items everytime, you could just call addItem with the new String without removing everything and adding them back.
the best way to add some thing in your combo box in order that you can change it easily is to describe an array list first,if you would like to be dynamic you can user a text field then in a text field you can run an array list .
textField = new JTextField();
textField.setBounds(131, 52, 86, 20);
contentPane.add(textField);
textField.setColumns(10);
then you have to create an array list
ArrayList al=new ArrayList();
then you have to equal your text field text to a string
String str=textfield.getText();
then add it to your array
al.add(str);
then add al item to your combo box.
JComboBox comboBox = new JComboBox();
comboBox.setBounds(112, 115, 145, 20);
contentPane.add(comboBox);
comboBox.addItem(al);