Add Multiple Elements to ListModel using Combo box - java

I want to add multiple elements to JList using JComboBox. When user select an item from the JComboBox, it should add to JList. If the item already exists in the List message should pop up to notify that. How do I do this?
private void cmbBagSizeItemStateChanged(java.awt.event.ItemEvent evt) {
DefaultListModel listModel = new DefaultListModel();
lstBagSize.setModel(listModel);
if ((evt.getStateChange() == ItemEvent.SELECTED)) {
if (listModel.getSize() != 0) {
for (int i = 0; i < listModel.getSize(); i++) {
listModel.addElement(cmbBagSize.getModel().getSelectedItem());
break;
}
} else {
listModel.addElement(cmbBagSize.getModel().getSelectedItem());
}
}
}

I managed to find the solution to above issue. I used method called contains to check where any duplicates exists.
DefaultListModel listModel = new DefaultListModel();
if (listModel.contains(this.cmbBagSize.getSelectedItem())) {
JOptionPane.showMessageDialog(null, "Duplicate");
} else {
listModel.addElement(this.cmbBagSize.getSelectedItem());
this.lstBagSize.setModel(listModel);
}

Related

Upon loading JTable dynamically, before selected JComboBox appears visible

I use:
Java 10 SE
Java Swing
Eclipse IDE
I have JTable, the contents gets loaded at runtime dynamically. It has some JComboBoxes. If I select the JComboBox, and then attempt to reload the table, the JComboBox appears visible at the time when the table loading is in progress.
Besides that, if the JComboBox's contents gets updated (elsewhere in different table, when the combo supposed to reflect that new contents), that new contents does not get visible staright away after loading the JTable dynamically.
The snap-shot sample of the app:
That's, the table being loaded at runtime up, and in the middle you have vsisble JComboBox persistent from the previous selection.
How to:
Get rid off that persistent JComboBox
Make the data visible instantly, upon update under the combo, once you load the table dynamically
I have the public final class TableColumnEditor extends DefaultCellEditor{
which returns the JComboBox on a specific column:
else if(row == ROW_2_DEVS_WORK_WEEKEND) {
ProjectMetrics metrics = new ProjectMetrics();
JComboBox<String> combo = new JComboBox<>();
combo.setBackground(Color.WHITE);
for(String devs : metrics.identifyDevsThatWorkAtWeekend()) {
combo.addItem(devs);
}
return combo;
}
I have the public final class TableColumnRenderer extends DefaultTableCellRenderer{
which makes sure that the view displays the JComboBox under that specific column:
else if(row == ROW_2_DEVS_WORK_WEEKEND) {
ProjectMetrics metrics = new ProjectMetrics();
JComboBox<String> combo = new JComboBox<>();
combo.setBackground(Color.WHITE);
for(String devs : metrics.identifyDevsThatWorkAtWeekend()) {
combo.addItem(devs);
break;
}
return combo;
}
The table gets loaded dynamically right here (non-essential things removed):
public static void reloadTableDynamically(JTable metricsTable){
DefaultTableModel model = (DefaultTableModel)metricsTable.getModel();
if(projectData.isEmpty()) {
metricsTable.clearSelection();
int rowCount = model.getRowCount();
for(int item = (rowCount - 1); item >= 0; item--) {
model.removeRow(item);//clears previous rows
}
metricsTable.repaint();
return;
}
model.getDataVector().clear();
int rowCount = constantRows + ((devsTask.size() == 0) ? 1 : devsTask.size());
try {
new Thread(()-> {
int lastRowID = 0;
int devsTaskID = 0;
for(int item = 0; item < rowCount; item++) {
Object[] input = null;
if(item == 0) {
input = new Object[] {"", metrics.getProjectDateRange(), "" };
}//similar branches removed
else {
devsTaskID++;
input = new Object[] {"", devsTask.get(devsTaskID).getDeveloper(), ""};
}
model.addRow(input);
metricsTable.scrollRectToVisible(new java.awt.Rectangle(metricsTable.getCellRect(lastRowID++, 0, true)));
metricsTable.repaint();
try {
Thread.sleep(Config.getInstance().getReloadInOutTable());
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
metricsTable.scrollRectToVisible(new java.awt.Rectangle(metricsTable.getCellRect(projectData.size() - 1, 0, true)));
metricsTable.repaint();//so that to reach the last row
}).start();
}
catch(Exception e) {
}
}
What do you think?
Well, I figured out how to overcome this problem.
Firstly, the JComboBox gets updated on EDT(Event Despatch Thread).
/**
* #param combo The JComboBox ref.
* #param toDisplay The value to add to it
*/
public static void updateComboBoxOnEventDespatchThread(JComboBox<String> combo, String toDisplay) {
Runnable doComboUpdate = new Runnable() {
public void run() {
combo.addItem(toDisplay);
}
};
SwingUtilities.invokeLater(doComboUpdate);
}
Under the JTable column editor:
else if(row == ROW_2_DEVS_WORK_WEEKEND) {
ProjectMetrics metrics = new ProjectMetrics();
JComboBox<String> combo = new JComboBox<>();
combo.setBackground(Color.WHITE);
Runnable doComboInsert = new Runnable() {
public void run() {
int id = 0;
for(String devs : metrics.identifyDevsThatWorkAtWeekend()) {
UIutils.updateComboBoxOnEventDespatchThread(combo, "("+ ++id +") " + devs);
}
}
};
SwingUtilities.invokeLater(doComboInsert);
return combo;
}
But the main fix, without which both issues do not go away, is following.
That is, I noticed that in order for data to appear under the table instantly, firstly, you need to select any other unrelated table's cell.
That is, the Java thread, which loads the JTable at runtime, does need to have this:
if(model.getRowCount() > 0) {
metricsTable.selectAll();
}
That's probably a hack, but it works for me!

Trying to add item listener to a JCheckBox object

I am trying add an item listener to a checkbox to see if its been checked, and if it is, to be added to a list of SQL table names to be selected. Inversely, if it is not selected then remove it from the list. I cannot add a listener though to any checkbox because "they are not effitively final". What can I do/is there a better way to attack it?
My method:
public JPanel drawChecks(){
ArrayList<String> list = MainFrame.grabSQLTableNames();
int index = list.size();
int rows = 1;
while(index > 1){
rows++;
index = index - 3;
}
GridLayout c = new GridLayout(rows, 3);
JPanel panel = new JPanel(c);
JCheckBox check[] = new JCheckBox[list.size()];
for(int x = 0; x < list.size(); x++){
check[x] = new JCheckBox(list.get(x));
check[x].setVisible(true);
check[x].addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (check[x].getState == true){
//do something
}
}
});
panel.add(check[x]);
}
Get the source of the event using the getSource method of the ItemEvent
public void itemStateChanged(ItemEvent e) {
JCheckBox checkBox = (JCheckBox)e.getSource();
if ( checkBox.isSelected() ){
//do something
}
}
For future reference, please read the following for tips on posting code examples for asking questions on stack overflow: https://stackoverflow.com/help/mcve

How to link two Jlists

I have two Jlists of vectors filled with data extracted from a mysql db. What I want is when the user select an item (menu) from Jlist1 (which I called menuList) Jlist2 (which I called productList) must display the products of that menu and other things, such as the ability to insert a new product in THAT menu or in a new menu just created.
I've accomplished this task in a way which I think is weak, by using some boolean variables which tells if the user is inserting a product in an existing menu or in a newly created one. Please, can you suggest me a better solution (if exists)? Here is an extract of the most significant part of the code, this is the method which saves a new product in the db:
private void bAddProdActionPerformed(java.awt.event.ActionEvent evt) {
//If new menu is saved, get the new menu's Id
if (newMenuIsSaved == true) {
Product newProduct = new Product();
newMenuId = DBConnection.getNewMenuId();
newProduct.setMenuId(newMenuId);
newProduct.setProductName(productName.getText());
if (checkPPriceValidity(productPrice.getText(), newProduct)) {
int result = DBConnection.insertProduct(newProduct);
if (result == 1) {
reloadProductList();
disableProductButtons();
}
}
} else {
Product newProduct = new Product();
//If a new menu wasn't saved, get the menuId from the selected one (from menuList):
Menu selectedMenu = (Menu) menuList.getSelectedValue();
newProduct.setMenuId(selectedMenu.getMenuId());
newProduct.setProductName(productName.getText());
if (checkPPriceValidity(productPrice.getText(), newProduct)) {
int result = DBConnection.insertProduct(newProduct);
if (result == 1) {
reloadProductList();
newMenuIsSaved = false;
disableProductButtons();
bNewProduct.setEnabled(true);
}
}
}
}
And here is the method reloadProductList():
private void reloadProductList() {
modelProductList.clear();
if (newMenuIsSaved) {
Vector<Product> productVoices = DBConnection.fillProductList(newMenuId);
for (int i = 0; i < productVoices.size(); i++) {
modelProductList.addElement((Product) productVoices.get(i));
}
} else {
Vector<Product> productVoices = DBConnection.fillProductList(selectedMenuId);
for (int i = 0; i < productVoices.size(); i++) {
modelProductList.addElement((Product) productVoices.get(i));
}
}
}
Thank you very much.
One way is to add a ListSelectionListener to menuList and have the handler set the other list's model to display the details for the selected row.

How to get the selected index of JCheckbox?

How to get the selected index (from a number of jcheckbox added to the screen using for loop) of JCheckbox?.
// for some t values:
checkBoxes[t] = new JCheckBox("Approve");
checkBoxes[t].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean selected = checkBoxes[t].isSelected();
System.out.println("Approved"+selected);
}
});
When i click the check box, i want to get the selected check box's index.
You have an array of JCheckBox, and you can simply iterate through your array and find out which JCheckBox has been selected.
Regarding:
When i click the check box, i want to get the selected check box's index.
Edit: You would find out which checkbox was selected by using the getSource() method of the ActionEvent passed into the ActionListener. For example you could change your ActionListener to as follows:
checkBoxes[t].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean selected = checkBoxes[t].isSelected();
System.out.println("Approved"+selected);
int index = -1;
for (int i = 0; i < checkBoxes.length; i++) {
if (checkBoxes[i] == e.getSource()) {
index = i;
// do something with i here
}
}
}
});
As far as I understand, you want to get the index of a selected JCheckBox in order to respond appropriately on a user's action.
If this is the case, you might want to consider a different approach: you can register an ItemListener for each of your checkboxes.
JCheckBox check = new JCheckBox("Approve");
check.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (check.isSelected()){
System.out.println(check.getName() + " is selected");
}
}
});
(inspired by java2s.com tutorial)
In this case the event will be fired immediately and you will always know which checkbox was just clicked.
Iterate throuh the Checkboxes and check the isSelected flag
I would try something like:
for (int i=0; i < checkBoxes.length; i++) {
if (checkBoxes[i].isSelected() == true) {
index = i; }
return index; }
From your question, this is what I gather that you are looking for.
EDIT:
My above previous method is flawed because it makes the very naive approach that one and only one box will be selected and that no box will be deselected.
Where 'e' is the ActionEvent object,
for (int i=0; i < checkBoxes.length; i++) {
if (checkBoxes[i] == e.getSource()) {
index = i; } }
return index;
This way the most recent selection or deselection check box is identified.

Checking if an item already exists in a JComboBox?

Is there an easy way to check if an item already exists in a JComboBox besides iterating through the latter? Here's what I want to do:
Item item = ...;
boolean exists = false;
for (int index = 0; index < myComboBox.getItemCount() && !exists; index++) {
if (item.equals(myComboBox.getItemAt(index)) {
exists = true;
}
}
if (!exists) {
myComboBox.addItem(item);
}
Thanks!
Use a DefaultComboBoxModel and call getIndexOf(item) to check if an item already exists. This method will return -1 if the item does not exist. Here is some sample code:
DefaultComboBoxModel model = new DefaultComboBoxModel(new String[] {"foo", "bar"});
JComboBox box = new JComboBox(model);
String toAdd = "baz";
//does it exist?
if(model.getIndexOf(toAdd) == -1 ) {
model.addElement(toAdd);
}
(Note that under-the-hood, indexOf does loop over the list of items to find the item you are looking for.)
Check with this:
if(((DefaultComboBoxModel)box.getModel()).getIndexOf(toAdd) == -1) {
box.addItem(toAdd );
}
or
if(((DefaultComboBoxModel)box.getModel()).getIndexOf(toAdd) < 0) {
box.addItem(toAdd );
}
Update:
myComboBox.setSelectedIndex(-1);
String strItem="exists";
myComboBox.setSelectedItem(strItem);
if(myComboBox.getSelectedIndex()>-1){
//exists
}

Categories