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

Reto Merz reto.merz at abacus.ch
Mon Apr 18 08:26:12 UTC 2016

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);


> 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. 


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? 


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 

which is invoked by 

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. 


On 4/14/2016 12:30 PM, Reto Merz wrote: 
Hello Semyon, 

We need to know the target component: "which component will be 

Target component means the component which should be "really" 

so this can only be known after all the FocusCycle / FocusTraversalPolicy 
logic has processed. 


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 

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? 


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() is only invoked when the component is focused by a mouse 

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 

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 

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 


On 11/04/16 12:26, Alexander Scherbatiy wrote: 

   Resending the request to awt-dev alias. 


On 4/4/2016 4:54 PM, Reto Merz wrote: 

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 

For this we use some internal API. We have a custom implementation of 
these interfaces: 


And use this getter and setter: 




Please make this API public. 

Furthermore we need to call 
We do this with reflection. It would be nice to have a public API for 
Maybe a new static method on AWTAccessor: 

Best Regards 
Reto Merz 

More information about the awt-dev mailing list