I am trying to get the Id of my selected choice on a DropDownChoice but I get an error..
I know that when I choose a value I just update the model and not the object (reflection).
I expected to get all the values of object "User" through getModelObject() but all i get is a NullPointerException..
I have tried many things according to tutorials and Wicket 8 documentation but nothing seems to work..
My code is like:
// POJO
class User {
private Integer id;
private String name;
[...]
}
// Main.class
private User selected;
ChoiceRenderer<User> choiceRenderer = new ChoiceRenderer<User>("id", "name");
List<User> list = getUsers();
final DropDownChoice<User> dropdown1 = new DropDownChoice<User>("dropdown",
new PropertyModel<User>(this, "selected"), list, choiceRenderer);
Button btn = new Button("btn") {
private static final long serialVersionUID = 1L;
#Override
public void onSubmit() {
RecrRemoteOperations recr = new RecrRemoteOperations();
try {
// NullPointerException!
// Integer id = dropdown.getModel().getObject().getId();
// id: the id of the selected "User" value on dropdown
recr.updateCommand(id);
} catch (Throwable e) {
e.printStackTrace();
}
}
}.setDefaultFormProcessing(false);
private static List<User> getUsers() {
List<User> allUsers = new ArrayList<User>();
[...]
return list;
}
The problem is in button.setDefaultFormProcessing(false). This tells Wicket to not use the submitted values and to not update the models of the FormComponents, i.e. the DropDownChoice won't have model object and thus won't set selected.
.setDefaultFormProcessing(false) is usually used for Cancel buttons, where you just want to leave the form.
I am not sure but my problem is very similar to this question
I was told that I don't need to use Ajax but I will try to see if it works
Related
This has baffled me for a while now and I cannot seem to get the grasp of it. I'm using Cell Value Factory to populate a simple one column table and it does not populate in the table.
It does and I click the rows that are populated but I do not see any values in them- in this case String values. [I just edited this to make it clearer]
I have a different project under which it works under the same kind of data model. What am I doing wrong?
Here's the code. The commented code at the end seems to work though. I've checked to see if the usual mistakes- creating a new column instance or a new tableview instance, are there. Nothing. Please help!
//Simple Data Model
Stock.java
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getstockTicker() {
return stockTicker.get();
}
public void setstockTicker(String stockticker) {
stockTicker.set(stockticker);
}
}
//Controller class
MainGuiController.java
private ObservableList<Stock> data;
#FXML
private TableView<Stock> stockTableView;// = new TableView<>(data);
#FXML
private TableColumn<Stock, String> tickerCol;
private void setTickersToCol() {
try {
Statement stmt = conn.createStatement();//conn is defined and works
ResultSet rsltset = stmt.executeQuery("SELECT ticker FROM tickerlist order by ticker");
data = FXCollections.observableArrayList();
Stock stockInstance;
while (rsltset.next()) {
stockInstance = new Stock(rsltset.getString(1).toUpperCase());
data.add(stockInstance);
}
} catch (SQLException ex) {
Logger.getLogger(WriteToFile.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection Failed! Check output console");
}
tickerCol.setCellValueFactory(new PropertyValueFactory<Stock,String>("stockTicker"));
stockTableView.setItems(data);
}
/*THIS, ON THE OTHER HAND, WORKS*/
/*Callback<CellDataFeatures<Stock, String>, ObservableValue<String>> cellDataFeat =
new Callback<CellDataFeatures<Stock, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<Stock, String> p) {
return new SimpleStringProperty(p.getValue().getstockTicker());
}
};*/
Suggested solution (use a Lambda, not a PropertyValueFactory)
Instead of:
aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));
Write:
aColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());
For more information, see this answer:
Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages
Solution using PropertyValueFactory
The lambda solution outlined above is preferred, but if you wish to use PropertyValueFactory, this alternate solution provides information on that.
How to Fix It
The case of your getter and setter methods are wrong.
getstockTicker should be getStockTicker
setstockTicker should be setStockTicker
Some Background Information
Your PropertyValueFactory remains the same with:
new PropertyValueFactory<Stock,String>("stockTicker")
The naming convention will seem more obvious when you also add a property accessor to your Stock class:
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getStockTicker() {
return stockTicker.get();
}
public void setStockTicker(String stockticker) {
stockTicker.set(stockticker);
}
public StringProperty stockTickerProperty() {
return stockTicker;
}
}
The PropertyValueFactory uses reflection to find the relevant accessors (these should be public). First, it will try to use the stockTickerProperty accessor and, if that is not present fall back to getters and setters. Providing a property accessor is recommended as then you will automatically enable your table to observe the property in the underlying model, dynamically updating its data as the underlying model changes.
put the Getter and Setter method in you data class for all the elements.
This has baffled me for a while now and I cannot seem to get the grasp of it. I'm using Cell Value Factory to populate a simple one column table and it does not populate in the table.
It does and I click the rows that are populated but I do not see any values in them- in this case String values. [I just edited this to make it clearer]
I have a different project under which it works under the same kind of data model. What am I doing wrong?
Here's the code. The commented code at the end seems to work though. I've checked to see if the usual mistakes- creating a new column instance or a new tableview instance, are there. Nothing. Please help!
//Simple Data Model
Stock.java
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getstockTicker() {
return stockTicker.get();
}
public void setstockTicker(String stockticker) {
stockTicker.set(stockticker);
}
}
//Controller class
MainGuiController.java
private ObservableList<Stock> data;
#FXML
private TableView<Stock> stockTableView;// = new TableView<>(data);
#FXML
private TableColumn<Stock, String> tickerCol;
private void setTickersToCol() {
try {
Statement stmt = conn.createStatement();//conn is defined and works
ResultSet rsltset = stmt.executeQuery("SELECT ticker FROM tickerlist order by ticker");
data = FXCollections.observableArrayList();
Stock stockInstance;
while (rsltset.next()) {
stockInstance = new Stock(rsltset.getString(1).toUpperCase());
data.add(stockInstance);
}
} catch (SQLException ex) {
Logger.getLogger(WriteToFile.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection Failed! Check output console");
}
tickerCol.setCellValueFactory(new PropertyValueFactory<Stock,String>("stockTicker"));
stockTableView.setItems(data);
}
/*THIS, ON THE OTHER HAND, WORKS*/
/*Callback<CellDataFeatures<Stock, String>, ObservableValue<String>> cellDataFeat =
new Callback<CellDataFeatures<Stock, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<Stock, String> p) {
return new SimpleStringProperty(p.getValue().getstockTicker());
}
};*/
Suggested solution (use a Lambda, not a PropertyValueFactory)
Instead of:
aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));
Write:
aColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());
For more information, see this answer:
Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages
Solution using PropertyValueFactory
The lambda solution outlined above is preferred, but if you wish to use PropertyValueFactory, this alternate solution provides information on that.
How to Fix It
The case of your getter and setter methods are wrong.
getstockTicker should be getStockTicker
setstockTicker should be setStockTicker
Some Background Information
Your PropertyValueFactory remains the same with:
new PropertyValueFactory<Stock,String>("stockTicker")
The naming convention will seem more obvious when you also add a property accessor to your Stock class:
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getStockTicker() {
return stockTicker.get();
}
public void setStockTicker(String stockticker) {
stockTicker.set(stockticker);
}
public StringProperty stockTickerProperty() {
return stockTicker;
}
}
The PropertyValueFactory uses reflection to find the relevant accessors (these should be public). First, it will try to use the stockTickerProperty accessor and, if that is not present fall back to getters and setters. Providing a property accessor is recommended as then you will automatically enable your table to observe the property in the underlying model, dynamically updating its data as the underlying model changes.
put the Getter and Setter method in you data class for all the elements.
I had a problem with a Form Field (Transient wicket form field ignored) and I had no much luck with the answers, so I made some changes and now the field is sometimes updated, and sometimes not... here's the current code:
The User entity:
#Entity(name = "user")
#Audited
public class User extends DataObjectAudit {
private static final long serialVersionUID = 1L;
private RoleTypeEnum role = null;
public RoleTypeEnum getRole() {
return role;
}
public void setRole(RoleTypeEnum role) {
this.role = role;
}
}
And in the panel, there is a drop down panel (extends GenericPanel) and the options possible are the current active role of the user is loaded among with the "lower" possible roles. The chosen option should be loaded into the "role" property.
User sessionUser = StudySession.getSessionUser();
List<RoleTypeEnum> roles = new ArrayList<RoleTypeEnum>();
roles.addAll(sessionUser.getRole().getLowerAndEqualsThanSelf());
WefDropDownPanel<RoleTypeEnum> role = new WefDropDownPanel<RoleTypeEnum>(helper.of(RoleTypeEnum.class, "role").errorRequired(), roles).setSizes(Size.S0, Size.S1, Size.S4);
add(role);
There is no validation for that field, others have though.
The only thing that is made before saving the form is:
#Override
protected void onBeforeSave(AjaxRequestTarget target, WefForm<User> form) {
User user = getModelObject();
DataService dataService = ServiceFactory.getBean(DataService.class);
ProjectCenter projectCenter = dataService.findUniqueByParameters(ProjectCenter.class, new Parameter<Object>("center", user.getCenter()));
if (projectCenter != null) {
user.setProject(projectCenter.getProject());
}
}
So the result is that sometimes "role" is updated, and sometimes it is not... Also, all the other fields (that I have erased to simplify) are also being ignored...
If I erase the onBeforeSubmit method, the result is the same... sometimes the entity is updated with the values the user entered, sometimes not...
The funny thing is that sometimes the entity is updated, and sometimes it is not... most of the time it works...
Create a quickstart and report back on the user list - I'll happily debug the problem.
I have a Struts 2 textfield tag where I just need to get a user enter value and send to the action.
<s:textfield name="user.firstAnswer" size="110" cssClass="FormObjectCompulsary" autocomplete="off" />
Even when this page loads user object contains value for first answer, I don't want to display it in the text field instead I want the text field to be blank.
But with out specify the value attribute still the value in user object shows in this field.
If you are adding a new object user, then you should create this object with new operator before you show it in the JSP. It will contain null references that are not displayed. If the value attribute is not specified, then name is used to show the value.
Make your user object null after inside the execute(). So again it will not show value inside text box.
eg. user = null;
I am showing you piece of code, may be it will help you.
See the execute().
package online.solution;
import com.opensymphony.xwork2.Action;
public class MyAction implements Action {
UserBean user = new UserBean();
public UserBean getUser() {
return user;
}
public void setUser(UserBean user) {
this.user = user;
}
#SuppressWarnings("finally")
#Override
public String execute() throws Exception {
String result = "";
try {
user.setGuest("Bye bye");
System.out.println(user.getUsername() + " " + user.getPassword());
if (user.getUsername().equals(user.getPassword())) {
result = SUCCESS;
}
else {
result = ERROR;
}
user = null; //Make it null when all task completed.
}
catch (Exception exception) {
System.out.println("Exception -> " + exception);
}
finally {
return result;
}
}
#Override
protected void finalize() throws Throwable {
super.finalize();
}
}
By looking at name="user.firstAnswer" I am thinking that you are implementing ModelDriven<> to your action class. What might be happening is that when you return success in your action class and come to the jsp page, and if in action your user model had some values on it.. model driven will set those fields for your on your JSP page.
I have used this approach for update form functionality while learning struts2. Just make sure that user object contains nothing before you return...
In Silverlight, a frequently used pattern is:
Request data
Get back an empty container for the data
Asynchronously fire off a query to fill the container
When the query returns, fire an event on the container
Update the UI according to the container's contents
Can this be done in GWT?
The reason I ask is that I'm trying to make a SuggestBox that contains a list of group names and icons. First, I query Facebook to get a list of groups IDs that are close to the current String in the SuggestBox. Then, I fire off queries to get icons for each group id. The problem is that I have to return the suggestions before those queries are done. I'm not sure how to go back and insert the data after I have it. I don't want to block until the calls are complete, and there's no real way to know in advance what data to load.
I could return a widget for the suggestion that loads an image, but the suggestion must be a plain String.
What is the right approach here?
Let's assume you're using GWT RPC. You'll have some service interface that lets you fetch the groupIds for a suggestion and the icon for a specific group id.
public interface FacebookService extends RemoteService {
List<String> getFacebookGroupIds(String suggestion);
Icon getIconForGroup(String groupId);
}
You should build your own implementation of Suggestion that can display itself with either just a groupId or a groupId and an Icon.
public class FacebookGroupSuggestion implements Suggestion {
private String groupId;
private Icon icon;
public FacebookGroupSuggestion(String groupId) {
this.groupId = groupId;
}
public String getDisplayString() {
StringBuilder builder = new StringBuilder();
builder.append("<b>");
builder.append(this.groupId);
builder.append("</b>");
if (this.icon != null) {
builder.append(this.icon.toSafeHtml());
}
return builder.toString();
}
}
I'm using Icon as your own implementation of an icon, it's not a standard class.
Then, you can make your implementation of SuggestOracle to fetch the groupIds and icons asynchronously. The SuggestOracle uses a callback to inform the suggestBox that some response to a request is available. So fetch your results, and call the callback when you get them. It'll look something like this.
public class FacebookSuggestOracle extends SuggestOracle {
private FacebookServiceAsync service = GWT.create(FacebookService.class);
private Request currentRequest;
private Callback currentCallback;
#Override
public void requestSuggestions(Request request, Callback callback) {
// Save request & callback for future use.
this.currentRequest = request;
this.currentCallback = callback;
// Fetch the groupIds
service.getFacebookGroupIds(request.getQuery(), new AsyncCallback<List<String>>() {
public void onSuccess(List<String> result) {
createSuggestionsForGroupIds(result);
}
});
}
private void createSuggestionsForGroupIds(List<String> groupIds) {
List<FacebookGroupSuggestion> suggestions = new ArrayList<FacebookGroupSuggestion>();
for (String groupId : groupIds) {
suggestions.add(new FacebookGroupSuggestion(groupId));
}
Response response = new Response(suggestions);
// Tell the suggestBox to display some new suggestions
currentCallback.onSuggestionsReady(currentRequest, response);
// Fetch the icons
for (String groupId : groupIds) {
service.getIconForGroup(groupId, new AsyncCallback<Icon>() {
public void onSuccess(Icon result) {
// match the icon to the groupId in the suggestion list
// use the callback again to tell the display to update itself
}
});
}
}
}