<AWT Dev> <Swing Dev> Public RequestFocusController/AWTAccessor API

Reto Merz reto.merz at abacus.ch
Thu Apr 14 12:19:56 UTC 2016


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.Cause)
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 on http://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.ComponentAccesso
r)
sun.awt.AWTAccessor#getComponentAccessor()
sun.awt.AWTAccessor.ComponentAccessor#setRequestFocusController(Reque
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









More information about the awt-dev mailing list