Why does my component not get focus? - java

I am running an applet, and am trying to focus on a component outside of the init method. I have tried using requestFocus and requestFocusInWindow. Both of these return true, as do isDisplayable, isVisible, and isFocusable, but calling hasFocus right after this returns false. The component just doesn't show up in the applet.
Here is the method called by the event listener (when the user clicks 'begin battle'), trying to focus on the component:
private void beginBattle(){
BattleSequence bs = new BattleSequence(..);
remove(pnlInit);
remove(pnlOOB);
remove(pnlBattle);
add(bs);
bs.setVisible(true);
bs.requestFocusInWindow(); //this returns 'true'
bs.setBounds(0, 0, bs.getSize().width, bs.getSize().height);
bs.init();
}
public class BattleSequence extends RavelSequence
public abstract class RavelSequence extends Applet implements KeyListener, FocusListener
Why is the focus request denied? If there is more code that is relevant, I can post it!
***EDIT:
Adding the mouse listener worked to get focus to the component, but I don't want to have the user need a mouse to control the game. I changed the declaration of RavelSequence to extend Container instead of Applet, and everything works peachy.
bs.hasFocus still returns false, but the key events are handled appropriately.

Try to call it on event dispatch thread.

Try adding a MouseListener to the component in question, and request focus in the mouseClicked() method.

Related

How to handle access to Views if the user is not authenticated yet?

My Vaadin 14's mainpage is a MainView with the root Route.
MainView is used as a "template" for the other View (with layout = MainView.class) so I see it more like a "abstract" view that should not be initialized by itself and is only used for the other views as layout.
Now the issue: If a user accesses the MainView the BeforeEnterEvent is called AFTER the constructor. This may lead to exceptions thrown because the user is not authenticated yet and the constructor executes stuff like building the Tabs already.
Is there a way to prevent the user from accessing the route of the MainView or an event that is executed before the constructor is called? Accessing the View is only allowed if the user is authenticated.
#Route("")
public class MainView extends AppLayout implements BeforeEnterObserver {
public MainView() {
super();
// Creates all the Tabs that are used in the MainView, may throw exception if the user calls the URL of this View before authenticated
setupView();
}
...
#Override
public void beforeEnter(BeforeEnterEvent event) {
// Reroute to Login if User is NOT authenticated
}
}
#Route(value = "foo", layout = MainView.class)
public class OtherView {
Update:
The fix is released as experimental feature in Vaadin 14.2.
The issue with instances being created too early was actually closed a few hours ago. It will take some time before it's released.
That being said, an instance method can't possibly be called before the constructor, so it does not fix your particular case.
I would suggest moving your view setup code to onAttach. If you only want to run the setup code once, you can use AttachEvent#isInitialAttach to only execute your code on the first attach.
Once the issue I linked above is released, you can have the code in the constructor, but the instance that has the observer method will still be created before beforeEnter is called, just not the child view instances.
To not have any views created, you can add listener directly to the UI using UI#addBeforeEnterListener as soon as the UI is created, utilizing a UI init listener. Again, only when the fix has been released.
Your code may have a security issue, as described in the tutorial series for spring security with Vaadin. it is explained how to secure Views in the VaadinServiceInitListener instead.
But the proposed solution also adds a beforeEnterListener to the Views, so I don't think your problem is resolved with this.
A solution to your problem may be to throw a custom Exception (let's call it NotAuthorizedException for further reference) in the constructor of MainView if the user is not authorized. Then you let your LoginView implement HasErrorParameter<NotAuthorizedException>
I was able to fix it temporarely with an additional check for authentication. It may not be the best solution but it works for now. In the future #Tazavoo's answer should be implemented.
public MainView() {
super();
if (!isAuthenticated())
return;
setupView();
}

Vaadin wizard addon event fire twice

I am using Vaadin wizard addon and I have a problem with the following case:
When the user only presses forward/next step, there is no problem. However, if the user wants to go to the previous step, I am accidentally adding a Button click listener to the same event(That is my assumption. I have debugged the program and saw that if the user goes to the previous page, the event fires twice)
I have tried to remove the event listener before going to the next page, however, I could not find a method to remove all of the event listeners once. Also, I don't know where to remove them, since I could not find a function executed before the user is moved to the next page in Vaadin wizard.
I am following this example:
https://github.com/tehapo/WizardsForVaadin/tree/master/wizards-for-vaadin-demo/src/main/java/org/vaadin/teemu/wizards
Is there a method to remove all of the ClickListeners?
If it exists, where should I add that functionality?
Also, I am using ListDataProvider and NativeSelect components too.
NativeSelect has HasValue.ValueChangeListener<String> listener and in the default implementation, I Could not find a method such that I can use this:
NativeSelect<String> select = new NativeSelect<>("List");
select.addValueChangeListener(new HasValue.ValueChangeListener<String>() {
// some overwritten valuechange method
}
select.removeValueChangeListener(); // This does not exist
I am setting the click listener in the public Component getContent() {} method
In Vaadin 8 you need to use the Registration interface to remove Listeners.
When you add a Listener it will return the Registration:
final Registration registration = select.addValueChangeListener(this::doSomething);
And then to remove it:
registration.remove();

How to validate a textfield in pageablelistview in java wicket

i have added a pageable listview with two components,one is text field and other is a dropdown. Normal way of checking for validation is by adding a feedback panel.But when same method is used in grid its giving an error saying that feedback component with wicket:id="xy" has already been parsed.
is there any way to validate those components?
JAVA CODE HTML CODE
Somewhere in the code (e.g. your overridden Form#onSubmit() or Form#onError(), one of your Ajax behaviors, etc.) you add the component with wicket ID "FeedbackSubQuestions_" again, even though this component has already been added before. Something like the following:
public class MyPage extends WebPage {
public MyPage() {
this.add(new FeedbackPanel("FeedbackSubQuestions_"));
this.add(new Form<Void>("myForm"){
#Override
protected void onError() {
// This call the produce the error as the feedback component is already in the component hierarchy
MyPage.this.add(new FeedbackPanel("FeedbackSubQuestions_"));
}
});
...
Adding all the form components with validation and their ajax behaviors
...
}
}
In wicket, once you construct the component hierarchy, subsequent interactions with the page do not need to reinitialise any of it anymore. That is, once you add the feedback panel in order for it to display your feedback you do not need to add this panel again. If there are errors to be displayed (e.g. a form validation fails, or Component#error(String) is called manually) the feedback will pick those up automatically when the feedback panel is being rendered again (e.g. when you add it to your ajax response or the whole page is being re-rendered as part of the form submission process).

Required solution for all Textbox on value change event - generic way

In my application we are using
1. Screen are designed using UIBinder with a view class to bind
2. Presenter as controller and model.
3. We do have Base Presenter (abstract with few generic implementations)
4. We are having many such screens with all screen will have textbox in it and all screen presenter will extends Base Presenter.
-- My requirement is to fire and catch generic event when user changes any textbox in any screen.
-- I dont want to define event for each and every textboxes available in each screen.
-- I want to register all textbox on value change (ValueChangeHandler) event in generic.
Is there anyway we can achieve this.
As far as I understand, you want to add a value change handler to each and every textbox that appear in a set of screens without adding to each individual text box.
You can extend the textbox and add value change handler in the constructor and provide a hook to do any manipuation.
public class MyTextBox extends TextBox
{
public MyTextBox()
{
super();
addValueChangeHandler( new ValueChangeHandler<String>()
{
#Override
public void onValueChange( ValueChangeEvent<String> event )
{
// TODO Auto-generated method stub
}
} );
}
}

rich:simpleTogglePanel neither calls action nor actionListener

I've implemented the following rich:simpleTogglePanel
<rich:simpleTogglePanel
switchType="server"
ationListener="swapPanelState"
action="swapPanelState2">
No matter which switchType I set - server, ajax, or client - neither the `action nor theactionListener` gets called. I've activated breakpoints at these methods and they never get invoked.
Here are the methods:
public Object swapPanelState2() {
logger.info("swapPanelState");
return null;
}
public void swapPanelState(ActionEvent event) {
logger.info("swapPanelState");
}
The panel is nested inside a h:form tag. Other actionListeners are called without a problem. We're using RichFaces in the version 3.3.2.
You need to write
actionListener="#{yourBean.swapPanelState}"
instead of
ationListener="swapPanelState"

Categories