That sounds good. Thanks for you efforts.
Best Regards Reto Merz On 4/14/2016 22:11, Semyon Sadetsky wrote: > On 4/14/2016 9:25 PM, Reto Merz wrote: > > This is a small part of our focus/validation framework. > I just try to explain it as simple as possible. > > javax.swing.InputVerifier gives only access to the source component. > > We need to know the target component. > > Would it be possible to overload verify(..) (or introduce another method) > which has the "to"/target component as a argument too? Yes. That is what I will be able to do. Something like: public boolean verifyTarget(JComponent input) { return true; } public boolean shouldYieldFocus(JComponent from, JComponent to) { return shouldYieldFocus(from) && verifyTarget(to); } --Semyon > Thanks > Reto Merz On 14.04.2016 16:52, Semyon Sadetsky wrote: Thank for explanation. It seems to me such functionality belongs to the input validation domain and should not be mixed up with the Swing focus transfer internals. Swing has javax.swing.InputVerifier which you could extend and set to each component of your framework. I suppose it would be better design choice for you because it decouples your code from the focus transfer details which may be changed in future JDK releases. While the javax.swing.InputVerifier functionality will be preserved. --Semyon On 4/14/2016 4:58 PM, Reto Merz wrote: Exactly, the target can reject the focus transfer (and the source too). All our UI components support "FocusRequestEnterExit" listeners which has a requestEnter(EnterExitEvent) and requestExit(EnterExitEvent) method (among others focusGained/focusLost methods). The EnterExitEvent has a reject() and accept() method. requestEnter is invoked on the target component and requestExit on the source component listeners. The focus is only transferred after all source/target listeners have accept it. This can be used for simple user input validation. It is far more complex because our RIA is ULC based (https://ulc.canoo.com/developerzone/technicalconcept.html) which split UI components into client- and server-side half objects, but, basically this is how parts of our focus/validation framework works. Open Component#requestFocusInWindow(CausedFocusEvent.Cause) does not work because this allows only conditional invoking super.requestFocusInWindow. At this point it is not yet clear if the focus can be really transferred (see isRequestFocusAccepted). And after super.requestFocusInWindow it is to late because KeyboardFocusManager.setMostRecentFocusOwner is already invoked. From my point of view the best (and easiest to maintain) solution is introducing a isRequestFocusAccepted() method which is invoked by isRequestFocusAccepted(boolean,boolean,CausedFocusEvent.Cause) at the end. So the new isRequestFocusAccepted makes the final decision to transfer focus or not. Furthermore that dont require to make CausedFocusEvent.Cause public (which looks a bit creepy). Best Regards Reto Merz On 14/04/16 14:49, Semyon Sadetsky wrote: Okay... You said the you need to intercept the focus request in the place where the target is set. From my point of view opening Component#requestFocusInWindow(CausedFocusEvent.Cause cause) resolves that. But it looks like you need extra. What is the final purpose? Maybe you want to reject focus transfer depending on the target? --Semyon On 4/14/2016 3:19 PM, Reto Merz wrote: Thanks for your investigation Semyon. Make Component#requestFocusInWindow(CausedFocusEvent.Cause cause) public/protected will not help us. I can explain it more detailed if you want. What would help is to introduce a "protected boolean Component#isRequestFocusAccepted()" which is invoked by Component#isRequestFocusAccepted(boolean,boolean,CausedFocusEvent. Caus e) after the "Component.requestFocusController.acceptRequestFocus" statement (and only if acceptRequestFocus has returned true). This way you also don't have to make CausedFocusEvent.Cause public. Best Regards Reto Merz On 14/04/16 13:09, Semyon Sadetsky wrote: The FocusTraversalPolicy can be obtained using public API. It may give you the target. But I believe this is not what you would like to do... It seem sensible to make Component#requestFocusInWindow(CausedFocusEvent.Cause cause) public. Will it be enough for you? I could start to implement this right after the 8080395 push. --Semyon On 4/14/2016 12:30 PM, Reto Merz wrote: Hello Semyon, We need to know the target component: "which component will be focused". Target component means the component which should be "really" focused, so this can only be known after all the FocusCycle / FocusTraversalPolicy logic has processed. DefaultKeyboardFocusManager focusNextComponent/focusPreviousComponent provides only the source component. Not the target. The second argument of RequestFocusController#acceptRequestFocus is the "real" target component. We use only this argument in our custom RequestFocusController implementation. Thanks Reto Merz On 14/04/16 08:31, Semyon Sadetsky wrote: Hi Reto, It is unlikely that AWTAccessor API may be opened. It gives access to internal undocumented methods not to even mention that those methods have private and package accesses. As I understand you need the way to intercept focus transfer initiated by a traversal key. Why to subclass the DefaultKeyboardFocusManager to override its focusNextComponent/ focusPreviousComponent methods? --Semyon On 4/12/2016 2:37 PM, Reto Merz wrote: Hello Alexandr, Basically we need to detect and intercept focus changes. java.awt.Component allows to override this methods: requestFocus() requestFocus(boolean) requestFocusInWindow() requestFocusInWindow(boolean) requestFocus() is only invoked when the component is focused by a mouse click. But no requestFocus* method is invoked when a FocusTraversalPolicy is involed (f. e. the user press TAB to focus next component). sun.awt.RequestFocusController#acceptRequestFocus is invoked in both cases. Attached a demo to reproduce it: - if TextField is focused by a mouse click "requestFocus" and "acceptRequestFocus" is logged - if TextField is focused by TAB only "acceptRequestFocus" is logged Some more notes about the test program: ComponentAccessorDelegator delegates all calls to the original ComponentAccessor implementation. Only ComponentAccessor#setRequestFocusController is changed to keep our RequestFocusController implementation. I have just filled a RFE onhttp://bugreport.java.com/bugreport Thanks Reto Merz On 11/04/16 21:02, Alexander Scherbatiy wrote: Hello Reto, Could you provide use cases which illustrate tasks the requested API is intended to solve in your application? Please, also create a request in the bug system http://bugreport.java.com/bugreport Thanks, Alexandr. On 11/04/16 12:26, Alexander Scherbatiy wrote: Resending the request to awt-dev alias. Thanks, Alexandr. On 4/4/2016 4:54 PM, Reto Merz wrote: Hello, Jigsaw will disallow access to internal packages. We have written a complex validation and focus management implementation for our closed-source RIA and maintain it since JRE 1.4. For this we use some internal API. We have a custom implementation of these interfaces: sun.awt.RequestFocusController sun.awt.AWTAccessor.ComponentAccessor And use this getter and setter: sun.awt.AWTAccessor#setComponentAccessor(AWTAccessor.ComponentAc cesso r) sun.awt.AWTAccessor#getComponentAccessor() sun.awt.AWTAccessor.ComponentAccessor#setRequestFocusController(Req ue stFocusController) Please make this API public. Furthermore we need to call java.awt.Component#revalidateSynchronously(). We do this with reflection. It would be nice to have a public API for this. Maybe a new static method on AWTAccessor: AWTAccessor.revalidateSynchronously(Component) Best Regards Reto Merz