JDK-4157017 : Tabbing through components stops if next component is off screen
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.1.6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_2.5.1
  • CPU: sparc
  • Submitted: 1998-07-14
  • Updated: 1999-07-20
  • Resolved: 1999-07-20
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other Other
1.1.8 1.1.8Fixed 1.2.2Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description

Name: mf23781			Date: 07/14/98


The following testcase can be used to show the problem

import java.awt.*;
import java.awt.event.*;

public class traverse extends Frame
{
    public traverse()
    {
        Frame f = new Frame("Focus test");
        Panel p =new Panel(new FlowLayout());
        for (int i=0; i<6; i++)
            p.add(new Button("Button "+i));
        f.add(p);
        f.pack();
        f.setVisible(true);
    }

    static public void main(String args[])
    {
        new traverse();
    }
}

Compile and run the application.
You can use the TAB key and SHIFT TAB to traverse forwards and
backwards through the buttons (wrapping around at each end)
Make the frame slightly smaller so that the last componenet 
disappears off the screen.
Tabbing now stops at the component before the one off the screen.


======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.1.8 FIXED IN: 1.1.8 1.2.2 INTEGRATED IN: 1.1.8 1.2.2 VERIFIED IN: 1.1.8
14-06-2004

EVALUATION This problem was caused because XmProcessTraversal cannot set focus to a widget that is not visible within the bounds of the root window. The fix was to replace XmProcessTraversal with XtSetKeyboardFocus. aboyd@netscapesrv 1998-11-20 The change made in awt_MToolkit.c to replace XmGetFocusWidget() is not necessary if we still use XmProcessTraversal() in awt_Component.c. Corrected in 1.1.8. xianfa.deng@Eng 1999-01-11 This bug verified as fixed via regression testing with jdk118g. john.s.lee@Eng 1999-02-08 This bug is _not_ fixed on fvwm, olwm, and with no window manager running. I have verified the fix works on dtwm and mwm. I was unable to test twm because the test case does not work correctly on twm. david.mendenhall@eng 1999-02-10
10-02-1999

SUGGESTED FIX A fix might involve adding an X action and translation for the TAB key and handling the change focus operation ourselves using XmProcessTraversal(). For example: void do_tab(Widget w, XtPointer client_data, XtPointer call_data) { printf("Pressed Tab\n"); ... } static XtActionsRec tabActions[] = { {"do_tab",(XtActionProc)do_tab} }; then in sun_awt_motif_MButtonPeer_create() (or whichever component we're interested in) ... XtAppAddActions(awt_appContext,tabActions,1); XtOverrideTranslations(cdata->widget,XtParseTranslationTable("<Key>Tab: do_tab()")); But this action only seems to get called when a mouse button is held down - otherwise the normal tab behaviour is engaged, and our action isn't called. It works okay in a plain X program - I think the problem lies in handleKeyEvent() in canvas.c. Moving the case statement for XK_Tab to the top of the switch() and making it read "*cont=TRUE; return;" causes our action to be called whenever the tab key is pressed, which is what we want. Making do_tab() call "XmProcessTraversal(w,XmTRAVERSE_NEXT);" looks promising - focus traversal now jumps over buttons which aren't visible, as it should. The Shift-Tab combination should make the traversal run backwards, which would require another translation for "Shift<Key>Tab: do_shift_tab", with corresponding action, which would then call "XmProcessTraversal(w,XmTRAVERSE_PREV);". The same translations would then need to be applied to all components which can be part of the focus traversal (although the same action procs can be used). I think this would result in good behaviour, consistent with the Focus Traversal description in "The Java Class Libraries Second Edition, volume 2" page 423. But the behaviour on Windows is slightly different - focus is given to components which are not visible, which I think is wrong, so I believe a full fix would also make the Windows focus traversal miss out non-visible components. matthew.chapman@eng 1998-10-09 The fix I initially implemented for this was to change assignFocus in Window.java to implement the non-Win32 behaviour described above. This change meant that only components who had some part visible within their root window could receive focus (which is consistent with X). However, two objections were raised about this fix: a) components who were visible within their window but who were offscreen would get focus (i.e. the focus would not wrap in this case as it would if the component was not visible within their window) which meant there was an inconsistency and, b) because a person who could not see the screen would not be able to tell what state components were at in relation to their screen visibilty, they would not know where a tab took them. So, it was decided to change the fix to implement the Win32 behaviour instead. Implementing the Win32 behaviour meant abandoning XmProcessTraversal in favour of XtSetKeyboardFocus in awt_Component.c:requestFocus; and replacing XmGetFocusWidget with XtGetKeyboardFocusWidget in awt_MToolkit.c:dispatchToWidget. aboyd@netscapesrv 1998-11-20
20-11-1998