private void initialize() {
loadPersistenceContext();
List<Events> events = getEventsChoiceBox(getPersistenceContext());
ObservableList<Event> data = FXCollections.observableList(events);
cbEvent.setItems(data); // Inserting data into the ChoiceBox
}
This is my main code. Problem is when the form is loaded, I get the Objects inserted in the ChoiceBox and not the properties.
This is the content of my List Events
Object[]
|- String
|- Integer
Object[]
|- String
|- Integer
So I want a ChoiceBox with that String property showing up and the Integer mapped to my controller.
I tried a lot of things but couldn't figure it out.
Here is another simple implementation from forums.oracle.com
Create a class for key - value
public class KeyValuePair {
private final String key;
private final String value;
public KeyValuePair(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() { return key; }
public String toString() { return value; }
}
Then create the ChoiceBox as:
ChoiceBox<KeyValuePair> choiceBox = new ChoiceBox<KeyValuePair>();
Fill the elements as;
choiceBox .getItems().add(new KeyValuePair("1", "Active"));
Hint: Retrive key-value pair from you database into an ArrayList and iterate
To retrieve the value:
choiceBox.getValue().getKey(); // returns the "1"
choiceBox.getValue().toString(); // returns the "Active"
See this example of a JavaFX ChoiceBox control backed by Database IDs.
The example works by defining a Choice class consisting of a database row ID and a string representation of the item to be displayed in the Choice box. The default toString method of Choice is overridden with a custom implementation that returns a string representation of the item to be displayed and not the database ID. When you add the choices to the ChoiceBox, the ChoiceBox will convert each Choice into a string for display. The displayed string value of the Choice is just the choice text rather than also including the database ID or using the default toString of Choice that would just display a meaningless object reference.
Output of choicebox sample app:
Also consider a ComboBox for such an implementation, as it has a mechanisms built into it to abstract the values of nodes from the display of the nodes (via a CellFactory). Use of a ComboBox is however often more complex than a ChoiceBox.
Or simply do: myChoiceBox.setConverter(myStringConverter), passing in an instance of your own subclass of javafx.util.StringConverter(JavaDoc).
Overriding the toString (and fromString) gives you full control over how your object is displayed without having to implement a toString in the object itself.
Related
I have below feature file with Given annotation
Given user have below credentials
|user |password |
|cucumber1 |cucumber |
|cucumber2 |cucumber |
And i'm created below datamodel
public Class DataModel{
public string user;
public String password;
}
Trying to fetch data into the cucumber stepdefinition as below
Public Class stepdefinition {
#Given("^user have below credentials$")
Public void user_have_below_credintials(List<DataModel> dm){
//Iterator or foreach is required to fetch row,column data from dm
}
}
Please help me how can I Iterate object 'dm' to get row and column values
// The old way
for (int i = 0; i < dm.size(); i++) {
DataModel aDataModel = dm.get(i);
String username = aDataModel.user;
String password = aDataModel.password;
}
// A better way if java5+
for (DataModel aDataModel : dm) {
String username = aDataModel.user;
String password = aDataModel.password;
}
// another way if java8+
dm.forEach(aDataModel -> {
String username = aDataModel.user;
String password = aDataModel.password;
});
Note that the variables won't be available outside the loop with the way I wrote it. Just a demonstration of iterating and accessing the properties of each DataModel in your list.
A thing to keep in mind is that you're describing your list of DataModel objects as a data table. But it's not a table, it's simply a collection of values contained in an object, which you have a list of. You may be displaying it, or choosing to conceptualize it as a data table in your head, but the model that your code is describing isn't that, which means you aren't going to iterate through it quite like a table. Once you access a "row", the "columns" have no defined order, you may access them in any order you want to the same effect.
I am using the following code to populate a combobox:
private void fillComboBox(ArrayList<Customer> a){
filling = true;
for (Customer c : a)
selectCustomerCB.addItem(c);
filling = false;
}
The values for the array are stored in a plain text file (customers.txt). There are three values for each customer, email, first name, and last name. I would like for the combobox to display the email address for each customer, but it is displaying "jamesdevenberg.customer.Customer#xxxxxxx" where xxxxxxx are alpha-numeric characters that are different for each customer, and change every time I run the application.
How do I get the combobox to display the email address instead?
If you are adding a Custom object to the combo box then you need to create a custom renderer for the combo box to display the email property of the Custom object.
Check out Combo Box With Custom Renderer for more information and examples on how to do this.
You are actually adding a Customer reference instead of an email. I don't know how does the Customer class look like, but:
selectCustomerCB.addItem(c.getEmail());
would be more appropriate.
The getEmail() method would be a member of the Customer class that returns an email retrieved from a file.
EDIT:
The other approach is to override toString() method in the Customer class:
public class Customer {
String email;
/*... implementation ... */
public String toString(){
return email;
}
}
I am trying to save an Enum field to database but I am having a problem mapping the field to database. The code I have is as follows:
public enum InvoiceStatus {
PAID,
UNPAID;
}
and I am using this enum in one of my application classes as follows:
public class Invoice {
Enumerated(EnumType.ORDINAL)
#Column(name="INVOICE_STATUS", nullable = false, unique=false)
private InvoiceStatus invoiceStatus;
}
finally I let the app user select the Invoice Status from the view (JSP) using a drop down menu.
But I am not sure how to map the value received from the drop down menu selection to the Invoice Status field
I tried mapping the value received to short as follows, but it won't compile
invoice.setInvoiceStatus(Short.parseShort(request.getParameter("inbStatus")));
can someone please tell me how to map the data received from the view to the enum field?
Enum ordinal values are zero based indexes. In your case:
PAID = 0
UNPAID = 1
So the following code will return PAID:
int invoiceStatus = 0;
invoice.setInvoiceStatus(InvoiceStatus.values()[invoiceStatus]);
And the following code will return UNPAID:
int invoiceStatus = 1;
invoice.setInvoiceStatus(InvoiceStatus.values()[invoiceStatus]);
That means you should be able to do this way:
short invoiceStatus = Short.parseShort(request.getParameter("inbStatus"));
invoice.setInvoiceStatus(InvoiceStatus.values()[invoiceStatus]);
But only if inbStatus is 0 or 1. You should always validate user input for null and invalid values.
I see that u are using
Enumerated(EnumType.ORDINAL)
however after a while it could be quite difficult to troubleshoot if your enum will grow. Another issue with the ordinal is that you could refactor your code and change the order of the enum values and after that you could be in trouble. Mainly if it is a shared codebase and someone just decides to cleanup the code and "group the relevant enum constants together". If you'll use:
Enumerated(EnumType.STRING)
Directly the enum "name" will be inserted into the database. (Therefore you need Varchar type). If you want to present more user friendly version of your enum you could probably have:
public enum InvoiceStatus {
PAID(0, "Paid"), UNPAID(1, "Unpaid"), FAILED(2, "Failed"), PENDING(3, "Pending");
private int st;
private in uiLabel;
private InvoiceStatus(int st, String uiLabel){
this.st = st;
this.uiLabel = uiLabel;
}
private Map<String, InvoiceStatus> uiLabelMap = new HashMap<String, InvoiceStatus> ();
static {
for(InvoiceStatus status : values()) {
uiLableMap.put(status.getUiLabel(), status);
}
}
/** Returns the appropriate enum based on the String representation used in ui forms */
public InvoiceStatus fromUiLabel(String uiLabel) {
return uiLableMap.get(uiLabel); // plus some tweaks (null check or whatever)
}
//
// Same logic for the ORDINAL if you are keen to use it
//
}
Probably this could be also a solution for your problem, however i would really not use the ORDINAL based mapping. But just personal feeling.
I have this DefaultListModel
DefaultListModel listModel;
//constructor does the right hting... etc.. I skipped over a lot of code
JList jlist_available_items;
....
jlist_available_items= new JList(cartModel); //etc
Everything is working almost perfectly the issue is that
listModel.addElement(product);
if I change it to product.name it will look correctly, but behave wrongly [the object itself won't be accesisble, only the name]
Is adding the object to the view, and all I want to add is the object name.
When I change it to the name it causes all sorts of issues, because I store the objects in a hashmap, and the hashmap uses objects as keys, not the product.name string.
The reason is so that this method can search the hashmap for the right object.
for (Product p : store.database.keySet()) {
if (jlist_available_items.getSelectedValuesList().contains(
(Product) p)) { // if item is selected
cart.addItem(p);
}
}
How can I fix this?? I have been trying to fix it and related bugs for almsot two hours = ( !
Also sample output is
Product [description=descrion test, name=test]
That is what it is printing. I just want it to print the name. = (!
Also the objects are in a hashmap. I can just iterate through the hashmap until an object has the same name value and then use that, but I don't want to. I want a more proper and scalable solution, namely because I am having so much trouble thinking of one.
BY THE WAY! This is a GUI app in Swing! If you want images just ask = )!
EDIT: And now nmy list cell renderer is broken! It was working just a moment ago... = (
#Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
Product product = (Product) value;
return this;
}
}
By default, the toString() method of the objects in the model is called to display the list element. And your Product.toString() method returns Product [description=descrion test, name=test].
If you want to display something else, then use a ListCellRenderer, as explained in the swing tutorial about JList.
EDIT: your renderer has a bug: it doesn't set the text of the returned component (which is a JLabel). It should be:
Product product = (Product) value;
setText(product.getName());
return this;
I want to bind an indexed property to JFace ComboViewer.
Lets say that I have a DataModel class like this:
class DataModel {
private String[] props = {"A","B","C"};
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public String getProperties( int idx ){
return props[idx];
}
public void setProperties( int idx, String value ){
String oldVal = props[idx];
props[idx] = value;
pcs.fireIndexedPropertyChange( "properties", idx, oldVal, value );
}
// code to add/remove PropertyChangeListener
// ...
}
The data binding code for simple property would look like this:
DataModel dataModel = ...
ComboViewer propertyChoice = ...
DataBindingContext ctx = new DataBindingContext();
IObservableValue target = ViewerProperties.singleSelection().observe( propertyChoice );
IObservableValue model = BeanProperties.value( DataModel.class, "properties" ).observe(dataModel);
ctx.bindValue( target, model );
but with an indexed property I have to inform the ctx at which index is the value that I want to bind. I have tried
IObservableValue model = BeanProperties.value( DataModel.class, "properties[0]" ).observe(dataModel);
but it doesn't work.
Is it possible to bind indexed property instead of simple property? How?
Unfortunately this seems to be unsupported. I was looking for exactly the same functionality. There is no documentation in BeanProperties that says it is supported.
When looking into the implementation of BeanProperties.value, you find that it delegates to BeanPropertyHelper for reading and writing a property. The method Object readProperty(Object source, PropertyDescriptor propertyDescriptor) does not know about the subclass IndexedPropertyDescriptor. When it is invoked for an indexed property, readProperty tries to use a read method that reads the entire array. I think this method is optional for indexed properties. For indexed properties it should use the IndexedPropertyDescriptor.getIndexedReadMethod().
Depending on your use case you may be able to workaround the problem by using BeanProperties.list. However you cannot use this in combination with indexed properties. I tried this by adding a method that returns the entire array but still keeping the method that does a "fireIndexedPropertyChange". Unfortunately this gives a ClassCastException: Eclipse's BeanListProperty seems to suppose that the value in the change event is an array or list. However for an indexed property it is a single element of the array.
Or perhaps you can use an observable map instead?