I have a JComboBox where the items are the results of a query. The combo shows all the categories names taken from a query, right? Ok, it works. Now I need to give each item a value, which would be the ID of the product.
This is what I've got so far:
final JComboBox proveedorCombo = new JComboBox();
contentPanel.add(proveedorCombo);
ProveedorDAO dao = new ProveedorDAO();
List<Proveedor> proveedor = dao.getAll();
Object[][] elementos = new Object[proveedor.size()][2];
for (int i = 0; i < proveedor.size(); i++) {
Proveedor p = proveedor.get(i);
elementos[i][0] = p.getId();
elementos[i][1] = p.getNombre();
proveedorCombo.addItem(elementos[i][1]);
}
As you can see in the code, the "label" of each item is the name of it. Now, how can I set each item its ID so I can manipulate after?
You'll want to use the IDs of the values as the values in your JComboBox, and use a custom ListCellRenderer to look up the name for an ID value.
You can do this by building a Map of names by their ID, and having your renderer return names for values.
Related
I have two objects: Books and BookLoans. All the books are stored on a ArrayList called books and Bookloans on loans.
A component of BookLoans is bookId. I want all books to be added to a combobox if the bookId doesn't already exist on the BookLoans List. Both the lists are different sizes.
I'm using MVC and the View side of the combobox is working.
I presume it will consists of two for-loops so this is my current attempt:
int length = books.size();
int loansLength = loans.size();
String[] listBooksCombo = new String[length];
for (int i = 0; i < loansLength; i++){
for(int j = 0; j < length; j++){
title = books.get(j).getTitle(); // Currently for testing purposes the getTitle and getBookId both are titles of a book
if(loans.get(i).getBookId() != title ){
listBooksCombo[j] = title;
}
currentView.comboBox(listBooksCombo); // sets the combo model
}
}
Currently the only result i've had is nothing appear in the combo box when there are objects in both array lists.
Here's how I would do it. The explanation is in the comments.
// collect the IDs of the book loans in a set - this makes lookup faster
Set<String> loanedBookIds = HashSet<>();
for (BookLoan loan : bookLoans) {
loanedBookIds.add(loan.getBookId());
}
// put the names of unloaned books here
List<String> unloanedTitles = new ArrayList<>();
for (Book book : books) {
// add all books whose IDs are not in `loanedBookIds`
if (!loanedBookIds.contains(book.getId())) {
unloanedTitles.add(book.getTitle());
}
}
// show titles in the ComboBox
currentView.comboBox(unloanedTitles);
As JB Nizet pointed out, you should separate the part that checks for which books are loaned into a separate method to make your code simpler and cleaner (then you can just write something like books.stream().filter(book -> !hasBeenLoaned(book)).map(book -> book.getTitle()). I've chosen not to do that here merely for brevity.
I have a ComboBox of Type Integer that I setup like this:
Collection<Integer> cbItems = new HashSet<>();
for(Integer i = 100; i < 360; i+=5){
cbItems.add(i);
}
ComboBox<Integer> cb = new ComboBox<>();
cb.setItems(cbItems);
I create a Collection of Integers and fill it with certain Integer values (100, 105, 110, etc...). The Code compiles, and the ComboBox is displayed in the view.
My Problem is that the items in the ComboBox are not sorted (or better: not sorted in the way I thought it would be).
Why does it re-sort my Integer-Collection, and how can I prevent it?
I would recommend you to populate vaadin components like ComboBox with DataProvider. It will make things easier later.
Your own solution works fine if there is not added items later to the ComboBox elsewhere. If items are added it might be needed to perform Collections.sort() again.
With a little change to use DataProvider:
ListDataProvider<Integer> dp = new ListDataProvider<>(cbItems);
// the first param is function that returns the value to sort
// in case of Integer it is that Integer itself.
dp.setSortOrder(i -> {return i;}, SortDirection.ASCENDING);
ComboBox<Integer> combo = new ComboBox<>();
combo.setDataProvider(dp);
Now, if you later add items to combo (through the original Collection):
// add some items to see where they are sorted
cbItems.add(102);
cbItems.add(113);
these items should be sorted to right place in ComboBox.
Then consider a bit more complex example. If you had a class like:
#RequiredArgsConstructor
public class Wrapper {
#Getter
private final Integer id;
#Getter
private final String name;
}
and you wanted to sort it by name descending, it would be like (with test data):
// generate some dymmy data
Collection<Wrapper> wrappers = new HashSet<>();
for(int i=1000; i<=2000; i+=150) {
wrappers.add(new Wrapper(i,
"Rand"+ThreadLocalRandom.current().nextInt(5000, 6000)) );
}
ListDataProvider<Wrapper> dpWrappers = new ListDataProvider<>(wrappers);
// now function returns the name of the wrapper to sort as sort argument
dpWrappers.setSortOrder(wrapper -> {return wrapper.getName();},
SortDirection.DESCENDING);
ComboBox<Wrapper> comboWrappers = new ComboBox<>();
comboWrappers.setDataProvider(dpWrappers);
// remember to set this to have the name of wrapper in combo vaptions
// instead of the value of Wrapper.toString();
comboWrappers.setItemCaptionGenerator( item -> {return item.getName();});
Okay I figured it out:
I changed the Collection to a List (ArrayList) so I can use Collections.sort(cbItems);
List<Integer> cbItems= new ArrayList<>();
for(Integer i = 100; i < 360; i+=5){
cbItems.add(i);
}
Collections.sort(cbItems);
ComboBox<Integer> cb = new ComboBox<>();
cb.setItems(cbItems);
Now the items are sorted ascendingly.
I have a JTable defined in this way:
public JTable table_1;
model_3 = new DefaultTableModel();
table_1 = new JTable(model_3);
scrollPane_5.setViewportView(table_1);
Add row:
model_3.addRow(new Object[]{table.getValueAt(row,0) , table.getValueAt(row,1) ,table.getValueAt(row,2) , commentFood });
Remove Row:
model_3.removeRow(row); //row is an integer
Until here, it used to work properly. As you can see this table is defined as public because sometimes I need to fill it up from another JFrame in this way:
takeOrder to = new takeOrder();
//Get data from DB to resultSet
to.table_1.setModel(DbUtils.resultSetToTableModel(resultSet));
If I fill up the table in this way and try to add or remove my model_3, it will not work! Any suggestion that how I can add or remove to the table after using DbUtils.resultSetToTableModel(resultSet) will be appreciated.
As I couldn't find any information on the internet and I saw couple of people asked same question with no answer. I came up with this solution:
if (formOut) {
for (int i = 0; i < table_1.getRowCount(); i++) {
model_3.addRow(new Object[]{table_1.getValueAt(i,0),
table_1.getValueAt(i, 1), table_1.getValueAt(i, 2)});
}
}
formOut = false;
table_1.setModel(model_3);
fromOut is a boolean to check if I have used another model for my table. If so I add data from table to previous model, and then I reference that model to my table. Now I can add to that model as well.
Hashmap contains key and value(result of parsing an XML). Hashmap contains things in the way that key is a string and value is a vector.
A key may have single value in the vector or mutiple values in the vector.
This hashmap, has to be put into a jtable,such that if the key has single value, put it to text box. If it has multiple values insert a combobox in the table.
You may change the code.
hashmap.put(nodeList.item(j).getNodeName(), nodeValueList);
Set keys = PropertyIMPL.hashmap.keySet();
Iterator iteratorKeys = keys.iterator();
while (iteratorKeys.hasNext()) {
String key = (String) iteratorKeys.next();
if (nodeValueList.size() > 1) {
tablemodel.insertRow(0, new Object[]{key});
String[] ss = (String[]) nodeValueList.toArray(
new String[nodeValueList.size()]);
TableColumn col = table.getColumnModel().getColumn(1);
col.setCellEditor(new MyComboBoxEditor(ss));
} else {
tablemodel.insertRow(0, new Object[]{key, nodeValueList});
}
}
keys.clear();
Short answer is you need to override the getCellEditor(...) method of JTable.
I have List and List and I need to create JTable with theese two columns. I am confused with model, can anybofy show me how to do that please, I am new to swing and Java ?
Please check out my answer to some other question. Where I have presented a simple table model often use.
In your case you would create data in a following way:
//I assumed here list 1 and 2 have the same sizes
List<Object> list1 = getList1();
List<Object> list2 = getList2();
int rNo = list1.size();
List<List<Object>> data = new ArrayList<List<Object>>(rNo);
int cNo = 2;
for(int i = 0; i < rNo; i++)
{
List<Object> r = new ArrayList<Object>(cNo);
r.add(list1.get(i));
r.add(list2.get(i));
data.add(r);
}
tm.setData(data);
No worries, just set your desired component as a cell editor for that column. Simple ain't it.
Example Snippet
public class JTextFieldCellEditor extends DefaultCellEditor {
JTextField textField;
public JTextFieldCellEditor() {
super(new JTextField());
textField = (JTextField) getComponent();
}
}
Then include it like below,
TableColumn column = myTable.getColumnModel().getColumn(0);
column.setCellEditor(new JTextFieldCellEditor());
Further reading:
Here is your best bet, Swing tutorial for JTable.