I have a Link in the constructor of the class DetailsPanel and I want it to save a change in the form of the class DetailsPanel when I click on it and go to the next page.
When I use for example if(propertyModel.getSomething() != null) { // change something } in the constructor Details() the change is made.
When I do the same in the constructor DetailsPanel() that is if(info.getSomething() != null) { // change something } the change is not made because the model is not updated when I click the link. It just goes to the next page and when I go back the change does not remain..
I have tested the code and the value of "something" passes in both cases.
I am just trying to understand how the wicket model works here...
public class DetailsPanel extends Panel {
private static final class Details extends BootstrapForm<InfoModel> {
public Details(String id, final CompoundPropertyModel<InfoModel> propertyModel) {
// form with various components..
}
}
public DetailsPanel(String id, final InfoModel info) {
// my link is here
}
}
public class InfoModel implements IClusterable {
// private fields with getters and setters eg.
private int something;
}
Related
my problem is that I can't find the way to bind a combobox, my goal is to autocomplete a combobox after clicking on a table (Grid):
The combobox data is taken from the BD Acception table, but the table data is taken from the WordAcception class
These are the errors it shows me:
[enter image description here][1]
[enter image description here][2]
WORDACCEPTION.java
public class WordAcception implements Serializable, Cloneable {
private String idacception = "";
public String getIdacception() {
return idacception;
}
public void setIdacception(String idacception) {
this.idacception = idacception;
}
}
VISTA.java
private ComboBox<Acception> WordAcceptioncombo = new ComboBox<>("idacception");
WordAcceptioncombo.setItemLabelGenerator(Acception::getIdAcception);
WordAcceptioncombo.setItems(AcceptionPersistence.getInstance().findAllIdAcception());
add(WordAcceptioncombo);
wordacceptionGrid.asSingleSelect().addValueChangeListener(event ->
formword.setWordAcception(wordacceptionGrid.asSingleSelect().getValue()));
WORDACCEPTIONFORM.java
binder.bind(WordAcceptioncombo, Acception::getIdAcception,
Acception::setIdAcception);
public void setWordAcception(WordAcception wordAcception) {
if(wordAcception != null) {
System.out.println("setWordAcception= "+wordAcception.getIdacception());
WordAcceptioncombo.setValue(wordAcception.getIdacception());
}
binder.setBean(wordAcception);
if (binder.getBean() == null) {
setVisible(false);
} else {
setVisible(true);
idacception.focus();
}
}
Aception.java
public class Acception implements Serializable, Cloneable {
private String idAcception = "";
public String getIdAcception() {
return idAcception;
}
public void setIdAcception(String idAcception) {
this.idAcception = idAcception;
}
}
/////////////UPDATE///////////
The combobox is completed thanks to the Acception class, for that reason I had to create an Acception instance in the WordAcception class in order to obtain that instance of the class (this has hidden the problems from me, but the combobox still does not autofill)
ACCEPTION.JAVA
public class Acception implements Serializable, Cloneable {
private Clase clase;
public Clase getClase() {
return clase;
}
public void setClase(Clase clase) {
this.clase = clase;
}
WORDACCEPTIONFORM.JAVA
binder.bind(WordAcceptioncombo, WordAcception::getAcception,
WordAcception::setAcception);
BUT I DON'T NOTICE ANY CHANGE, THE COMBOBOX STILL NOT FILLED
You usually get that kind of is not applicable for the arguments error from .bind when you are using a getter and setter for a value that is a different type than your field. In your case WordAcception.idAcception is type String but your ComboBox is set to take in items of type Acception.
If you want a ComboBox that gives you the option of selecting which particular id belongs to this specific WordAcception and for changing that id (without changing the WordAcception instance), the type of the ComboBox should be String. If you want a ComboBox that selects a specific Acception for you, you need to use a getter and setter for a field of that type.
Unrelated to the error, I'm not quite certain if there is supposed to be some connection between Acception and WordAcception, but based on the examples currently there is none. Did you mean for one of them to extend the other?
I am creating a simple GUI game (number guessing) in Java.
Apparently, I have a button called Give Up.
When I click the Give Up button, I want to display the answer on a textarea.
However, the targetNumber variable is declared as private:
public class GameUtility {
private String targetNumber = "2543";
//rest of the code
}
class GiveUpButton implements ActionListener { //Inner class
public void actionPerformed(ActionEvent gEvent) {
GameUtility utility = new GameUtility();
textArea.append(utility.targetNumber); //How to access the value of targetNumber?
}
}
How can I access a value of a private variable?
To make the state of the managed bean accessible, you need to add setter and getter methods for that state.
Once the setter and getter (accessor) methods have been added, you can update and access the value of the private instance. The code should look like the following example:
public class AccessorExample {
private String attribute;
public String getAttribute() {
return attribute;
}
public void setAttribute(String attribute) {
this.attribute = attribute;
}
}
Letting access the information inside the private instance from outside of the class, only if they ask through a provided mechanism we will call method. The mechanisms for asking an object to reveal information about itself we can call the getter method (e.g. accessorExample.getAttribute();).
The private modifier implies that you don't have access to the property directly. But perhaps more importantly, private implies that you shouldn't have access to the property directly. Create a getter for providing access to external classes:
public class GameUtility {
private String targetNumber = "2543";
public String getTargetNumber() {
return targetNumber;
}
//rest of the code
}
class GiveUpButton implements ActionListener {
public void actionPerformed(ActionEvent gEvent) {
GameUtility utility = new GameUtility();
textArea.append(utility.getTargetNumber());
}
}
See also: Java Documentation on Access Control
The recommended way is to create appropriate Getters and Setters.
See this post to get more insights as how do getters and setters work?
public class AccessorExample {
private String attribute;
public String getAttribute() {
return attribute;
}
public void setAttribute(String attribute) {
this.attribute = attribute;
}
}
Most of the IDEs provide support to directly generate getters and setters.
Generate Getters and setters in Netbeans.
Generate Getters and setters in Eclipse.
I need to use #SessionScope to make a list stay in the page after refreshing, but when I use it, Stripes:error is not diplaying any more. Stripes:error runs actually(as I see nothing will happen) but it just doesn't show the error message in the page any more. I'm sure there is something with #SessionScope because when I run the code without it all the errors shown in the page.
Any Idea of how to fix this?
Note: I also tried to use #Wizard(startEvents="event") and it lets errors to be shown but doesn't do anything with saving the list in the page!
java
#SessionScope
#UrlBinding("/Student/import.action")
public class ImportAction implements ActionBean {
private String userCheckBox;
public Resolution importStudents() throws IOException {
if (userCheckBox == null) {
this.getContext().getValidationErrors().add("userCheckBox",new SimpleError(error));
}
return new RedirectResolution("import.action");
}
public String getUserCheckBox() {
return userCheckBox;
}
public void setUserCheckBox(String userCheckBox) {
this.userCheckBox = userCheckBox;
}
}
jsp
<stripes:checkbox name="userCheckBox"/>
<stripes:errors field="userCheckBox"/>
<stripes:submit name="importStudents" value="Import"/>
I don't know if this is the correct way to do this but instead of using #SessionScope how about storing the list in the session directly via your subclassed ActionBeanContext? For example, mine has
public class IlmpActionBeanContext extends ActionBeanContext {
private static final String REQUEST_TOKEN = "request_token";
public Token getRequestToken() {
return (Token) this.getRequest().getSession()
.getAttribute(IlmpActionBeanContext.REQUEST_TOKEN);
}
public void setRequestToken(final Token requestToken) {
this.getRequest()
.getSession()
.setAttribute(IlmpActionBeanContext.REQUEST_TOKEN, requestToken);
}
I wanted to improve the code of my gwt-project by using editors to bind the POJOs, which I used to manually parse to the widgets back and forth. However I find the documentation confusing, mostly because it references ui binder, another feature I haven't figured out yet.
Does it make sense to use editors without ui binder? My ParentDTO contains a number of childDTOs. The following snippet shows how I am trying to nest some ChildEditors extended by TextArea into my ParentEditor (tried to strip it down to the essentials):
public class MyEditorPage {
// editors
class ParentDTOEditor implements Editor<ParentDTO> {
Integer dataBaseId;
List<ChildDTOEditor> childs;
public void attach(RootPanel rootPanel) {
for (ChildDTOEditor widget : childs) {
rootPanel.add(widget);
}
}
}
class ChildDTOEditor implements Editor<ChildDTO> extends TextArea {}
// driver
interface Driver extends SimpleBeanEditorDriver<ParentDTO, ParentDTOEditor> {}
Driver driver = GWT.create(Driver.class);
// load set widgets to the root panel
public void loadPage(RootPanel rootPanel) {
// get pojos from server
myService.getSuff(...
...
public void onSuccess(ParentDTO result) {
ParentDTOEditor editor = new ParentDTOEditor();
driver.initialize(editor);
driver.edit(result);
editor.attach(rootPanel);
}
}
// save
public void save() {
ParentDTO dto = driver.flush();
... // call myService.saveStuff(dto,...
}
}
Do I even need separate editors or just a parent editor of type ListEditor directly holds the child dtos?
Does it make sense to use editors without ui binder?
Yes, the features are independent and each can be used without the other.
Do I even need separate editors or just a parent editor of type ListEditor directly holds the child dtos?
You could create a ListEditor implementation direcly, but GWT can do that for you if you tell it how to create and destroy an Editor<ChildDTO> by extending EditorSource<ChildDTOEditor> and using ListEditor.of(new YourChildDTOEditorSourceImpl())
There's a decent example here but I'll call out a minimum implementation here.
public class FooEditor extends Composite implements Editor<Foo> {
// Implement one of uibinder+fields, fields, methods, or LeafValueEditor.set/getValue()
public FooEditor() {
initWidget(/* root widget or call to uiBinder.createAndBindUi(this) */)
}
}
public class FooListEditor extends Composite implements IsEditor<ListEditor<Foo, FooEditor>> {
private class FooEditorSource extends EditorSource<FooEditor> {
#Override
public FooEditor create(int index) {
FooEditor subEditor = new FooEditor();
// any additional per-item config can go here, e.g wiring up delete handler
listPanel.insert(subEditor, index);
return subEditor;
}
#Override
public void dispose(FooEditor subEditor) {
subEditor.removeFromParent();
}
#Override
public void setIndex(FooEditor subEditor, int index) {
listPanel.insert(subEditor, index);
}
}
// FlowPanel or anything else you want to use to hold the sub-editors.
// Instantiated explicitly or through uibinder.
FlowPanel listPanel = new FlowPanel();
// Let GWT handle the ListEdiotr implementation
ListEditor<Foo, FooEditor> editor = ListEditor.of(new FooEditorSource());
public FooListEditor() {
initWidget(listPanel /* or uiBinder.createAndBindUi(this) */);
}
#Override
public ListEditor<Foo, FooEditor> asEditor() {
return editor;
}
}
Now you can create an editor driver and use it as you would a normal editor, but pass it a list instead.
interface Driver extends SimpleBeanEditorDriver<List<Foo>, ListEditor<Foo, FooEditor>> {}
Driver driver = GWT.create(Driver.class);
FooListEditor fooListEditor = new FooListEditor();
/* snip */
driver.initialize(FooListEditor);
driver.edit(someListOfFoo);
Given that I have this entity as part of an editor chain:
public class Commission implements Serializable
{
private EnumSet<CommissionType> commissionTypes;
private CommissionType type; // must exist in commissionTypes
private String value;
public Commission()
{
}
}
and this editor for it:
public class CommissionEditor extends Composite implements Editor<Commission>
{
private static CommissionEditorUiBinder uiBinder = GWT.create(CommissionEditorUiBinder.class);
interface CommissionEditorUiBinder extends UiBinder<Widget, CommissionEditor>
{
}
#UiField(provided = true)
ValueListBox<CommissionType> type = new ValueListBox<CommissionType>(new AbstractRenderer<CommissionType>()
{
#Override
public String render(CommissionType object)
{
return object == null ? "" : object.toString();
}
});
#UiField
TextBox value;
public CommissionEditor()
{
type.setAcceptableValues(Arrays.asList(CommissionType.values()));
initWidget(uiBinder.createAndBindUi(this));
}
}
At the moment the ValueListBox renders all possible options for CommissionType, like this:
The EnumSet could contain between 1 and 4 of the possible options, depending on the particular entity. Is there a way to make the ValueListBox only render the options in the EnumSet and then save the value in commissionType?
Bear in mind that I want to set the value of commissionType as well.
There are two ways to solve it:
1.) If you have a direct access to the CommissionEditor then create a setter in it call it when you edit the entity:
public void setAcceptableValues(List<CommissionType> values) {
type.setAcceptableValues(values);
}
And call it like this when you call driver.edit(entity);:
commissionEditor.setAcceptableValues(commission.getCommissionTypes());
2.) Instead of extending the Editor interface you can extend the ValueAwareEditor and in the setValue() method call setAcceptableValues with the corresponding values.
Approach 2 is probably the cleaner approach.