How to not render a component in wicket - java

I have table of player in html: [table]
How I can hide or not render this table when it is empty? I try to add if conditional in java code and add this table to the page only if there is some value but then wicket throws an exception that he cant find component with this id. So how I can do this?

It throws the exception because the html markup expects the component to exist. Ie you must add it.
If it's an entire panel you want to hide then using EmptyPanel is the will hide the entire panel.
You can also use component.setVisible(false) to hide it if its only one component in the panel.

You can override the isVisible() function and return false if no date is available. But, this function will be called a few times, so if determining if data is available(like, hitting a database) you can call the setVisible(boolean) function.
Another option is to exchange the Repeater with an EmptyPanel if no data is available.

You can use the same condition you already use in java, but instead of not adding the table to the page, use table.setVisible(false).
Another way to do it would be to override the setVisible() and isVisible() methods, but i don't think it is recommended (see here)
Hope this helps

As the other users have pointed out, overriding isVisible() is not recommended because this function is called many times before component is rendered.
You should instead override onConfigure() and put inside it the code that decides if your table must be visible or not. onConfigure() is called just once per request.

Related

How to update a panel which shows details of an object

I have a panel, let's call it detailsPanel, which holds a Person reference and displays its field values in the following manner:
Name: person.getName ();
Surname: person.getSurname ();
Emain: person.getEmail ();
.... .......
.... .......
And so on. I will use JLabels (correctly aligned using a GridBagLayout) to show each (fieldName, fieldValue). I have a lot of fields to display.
The problem is that the panel which shows the details must be always visible, i.e it will not be shown in a modal JDialog, so that i could create the panel by simply reading my Person object fields at the panel creation.
The panel must always be visible, and its Person reference will change when the user selects a different row in a Person list. This means i will call a method to update its state, something like:
detailsPanel.setPerson (aPerson);
Now, i'm wondering how i should update all the fields. Should i keep a reference to all the JLabels which show the values, and use setText(value) on each of them when i update the panel, or would it be better to override getText() method for every label, returning the correct field value, so that in the update method i would only repaint the panel, and the text would automatically change when the getter method is used on a different Person object?
Any suggestion is appreciated!
Since this is UI stuff which is usually called almost never (relative to how often things are called in other computation) you don't need to worry about efficiency at all. Just do what you think is the most elegant solution. There are three options That quickly come to my mind. They are ordered from quick and static to elegant and reusable:
Quick and dirty: create your constructor and make everything look nice. Then move everything from the constructor to a separate init() method and every time the entities change, you just call removeAll(); and then init() again.
As you suggested, keep a reference to all labels and use the setPerson() method to update all panels. Then call this method in the constructor (this is arguably the most common solution).
As you suggested, build your own extension of JLabel. This new class should either have an update() method which is to be called when things change, or have it set its own listeners to ensure that it gets notified of any relevant change.
If you are planning to create a single panel which is supposed to display all kinds of objects, you could have those object implement an interface called Displayable which gives you generic access to all its values and maybe even listeners to each value. An alternative to the Displayable interface is to use reflection and use annotations to allow the panel to get its values for display.
Please note that the most elegant solution is - contrary to what some people may tell you - not always the best for any situation. How much maintenance do you expect there to be in the future? How big is the application? Will you ever hand off the code to someone else? All these and more need to be considered to decide how "nice" you want your solution to be.

How to make part tab inactive (disable) in Eclipse RCP?

I have partStack with a lot of parts in tabs. I'd like to know how can I make tabs inactive when I don't need them and active when I need.
By inactive I mean tab which is visible but I can't click on it and it is like disable function (for example text on it is gray instead of black).
I use an e4 RCP (with Application.e4xmi).
Thanks for help.
Handling of the selection of parts in a part stack is handled by the part stack renderer org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer which basically uses a CTabFolder.
You can use a renderer factory to override the stack renderer see here
You can extend the existing StackRenderer class and override methods to change its behavior. In this case probably the hookControllerLogic method. But you are going to have to study the source carefully to see what needs to be done.
You can try using using EPartService to manipulate a part but I think active/inactive part just means visible or not.
Or you can just loop and disable all swt controls yourself manually 😄
Use Renderer factory to override the stack renderer.
Extend the existing StackRenderer class and override hookControllerLogic() or activate() methods with empty implementation.
Example-
public class MyE4Part extends ContributedPartRenderer {
/*
* Don't activate the Part on part selection. part should not be gain the focus on any
* selection on part .
*/
#Override
public void hookControllerLogic( MUIElement me )
{
//Don't do anything.
//super.hookControllerLogic( me );
}
}

Best way to use additional components in wicket behaviors

I've create a new subclass of a wicket behavior which can be attached to form components. If a validation error occurs for such a component, the behaviors shows/hides a specific error label. My code looks similar to this:
public MyErrorBehavior(Component errorComponent) {
// show/hide errorComponent within onUpdate() or
// onError() based on getComponent().isValid()
}
My questions is: Is it ok to pass a component to a behaviors constructor?
Cheers,
Andreas
Yes, a behavior is allowed to keep references to components, please see EqualInputValidator as an example.
Take care if you remove these components from your component tree: you should remove the behavior too, otherwise you'll have dangling references of components which are no longer detached.
There is no need to keep a reference to the component because Wicket will pass the component in the callback method, e.g.
#Override
public void onComponentTag(Component component, ComponentTag tag)
{
// cast component to FormComponent and make the check here
}
This way there is no need to clean up and you can add the same Behavior instance to more than one (Form)Component.

Calling a Java method using javascript from within a JPanel

I have a Java application which displays results on a JPanel. The results are displayed using HTML by using a JLabel.
Now I want to let the user interact with the local application by allowing local methods to be called when the user clicks on a link in that HTML document.
Is this possible?
To answer you question, then, it is possible, however you cannot use a JLabel, you need to insert a JavaFX component, and then you can set your class as a window variable on the DOM, and thus your methods can be called from JavaScript.
Have a look at this answer on this question. It looks like they are doing exactly what you want.

Reset JComponent to default value

For example, if component is a checkbox it must set to false, or it is a textfield it must be clear the text. I am trying to write a method for reset all components in a JPanel. It must work like reset function in HTML forms.
How to reset a JComponent to the default value?
As a good developer, you probably have a nice separation between view and model. When the model gets updated, those changes are then reflected in the view.
If you have such structure, you could simply reset your model to a default state, and that reset-ed state then become visible in the UI (which means the UI is reset to its default state)
One possible workaround would be to create a custom reset function. Reinitialize the panel ( your form).
For e.g.
void reset(){
//recreate the form panel.
formPanel = new FormPanel();
}
Create a custom class FormPanel to store the form fields and their listeners.
Re initializing the panel components would result in an overhead of reassigning the listeners as #Robin suggested.
There is no reset function in Swing. The best way to do this is to create a method with the values you want to reset and set everything here e.g. :
public void resetWindow(){
checkBox.setSelected(false);
textField.setText("");
}
The advantage of using this way is that you can just reuse this method whenever you want to reset and also when the class loads.
The other way you could do it is by creating another instance of your Panel and throwing away the original. That way everything would be in the start state.
Write a method which sets the initial values of all elements on start. Then you can reuse this initialization method to "reset" the values.
there is no reset sort of method for swing component, your code should handle it.

Categories