JDK-4293388 : JSplitPane has problems with setting focus
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.1.8
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_7
  • CPU: sparc
  • Submitted: 1999-11-22
  • Updated: 2001-01-05
  • Resolved: 2001-01-05
Related Reports
Duplicate :  
Description

Name: skT88420			Date: 11/22/99


java -version
java version "1.1.8"

JSplitPane has a bug with focus events.  The items inside the JSplitPane would
lose focus. Trying to set requestFocus() or even grabFocus() on any of its
components would fail.  To regain the focus, you have to click the mouse on the
specific component. This problem happens only with Solaris 2.x. Under Win 32 it
works fine. BTW, the problem can be reproduced with JDK 1.2.  as well.
Please see the attached program which demonstrates this problem.  Compile and
run this program on Solaris 2.x. Just make sure your mouse pointer is outside of
the main window, when it starts up. The program creates just two buttons inside
a JSplitPane. After the window starts up, you can see the focus is
missing.(There is no rectangular box around button A, even though it is set) Try
tab key to move around. But it won't help. The keyboard is completely inactive.
But once you move the mouse pointer inside the window, the focus is gained and
the keyboard starts working. The same program works fine when you use JPanel
instead of JSplitPane.
  To compile: javac JSplitPaneFocus.java
  To run : java JSplitPaneFocus 1   ==> uses JSplitPane
         java JSplitPaneFocus  2  ==> uses JPanel.

Note: Our application needs to be fully accessible and operational even when
there is no mouse. This bug is posing a real problem in achieving this, since
we use JSplitane any many places in the GUI. So, we would like this bug fixed
asap.

// ------------------ Start test program --------------------
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.util.*;
// Program to demonstrate JSplitPane focus bug.
// To compile javac JSplitPaneFocus.java
// To run <java JSplitPaneFocus 1> ==> uses JSplitPane
// To run <java JSplitPaneFocus 2> ==> uses JPanel

public class JSplitPaneFocus {

    private static JButton buttonA, buttonB;
    private static JSplitPane jsp;
    private static JPanel jp;

    private static void CreateButtons() {

        buttonA = new JButton("Button A");
        buttonB = new JButton("Button B");
        buttonA.setVisible(true);
        buttonA.requestFocus();

        // Add a Focus listener to button A
        FocusListener fl = new FocusListener() {

           public void focusGained(FocusEvent e) {
             System.out.println("Button A focusGained");
           }
          public void focusLost(FocusEvent e) {
             System.out.println("Button A focusLost");
           }

        }; //Focus listener

       buttonA.addFocusListener(fl);
    }

    public static void main(String[] args) {
        JFrame mainFrame = new JFrame();
        CreateButtons();
        // Add buttons to JPanel if option 2 is passed
        // else use JSplitPane
        try {
          if(args[0].equals("2")) {
            // Use a JPanel
            JPanel jp = new JPanel(new BorderLayout());
            jp.add(buttonA,"North");
            jp.add(buttonB,"South");
            mainFrame.getContentPane().add(jp,BorderLayout.CENTER);
          }
          else {
          // Use a JSplitPane
            JSplitPane jsp =
              new JSplitPane(JSplitPane.VERTICAL_SPLIT,true,buttonA,buttonB);
            mainFrame.getContentPane().add(jsp);
          }
        }
        catch (Exception e) {
          // Use a JSplitPane
            JSplitPane jsp =
              new JSplitPane(JSplitPane.VERTICAL_SPLIT,true, buttonA,buttonB);
            mainFrame.getContentPane().add(jsp);
        }

        mainFrame.setSize( 300, 300 );
        mainFrame.setLocation(20, 20);
        // Window listener
        WindowAdapter wa = new WindowAdapter() {

         public void windowClosing(WindowEvent event)
           {
             System.exit(0);
           }

         public void windowDeactivated(WindowEvent event)
           {
             System.out.println("Window Deactivated !" );
             buttonA.requestFocus();
           }
  
         public void windowOpened(WindowEvent event)
           {
             System.out.println("Window Opened !" );
             buttonA.requestFocus();
           }
         public void windowActivated(WindowEvent event)
           {
             System.out.println("Window Activated !" );
             buttonA.requestFocus();
           }

       }; //Window listener
       mainFrame.addWindowListener(wa);
       mainFrame.setVisible(true);
       mainFrame.show();

    }//main()
}//End JSplitPaneFocus class

// ---------------- end test program ---------------------
(Review ID: 98038) 
======================================================================

Comments
EVALUATION BasicSplitPaneUI creates a Canvas to handle drawing when noncontinousLayout is set to true to deal with the case where heavyweights are contained in the splitpane. I believe this is causing focus problems. I'm reassigning to Hania as she has a better clue as to why the Canvas would cause problems with the focus being assigned to the JButton. scott.violet@eng 2000-01-19 This is fixed in merlin with the focus changes and an additional fix to BasicSplitPaneUI, which, rather than moving the heavyweight divider from a hidden place when needed, adds it and then removes it when it is no longer needed. Having it simply mapped at a spot where it's not visible does not prevent it from taking focus, and that's what was causing this bug. Note that this bug can probably be fixed in pre-1.4 releases by doing the change to BasicSplitPaneUI. hania.gajewska@Eng 2001-01-04
04-01-2001

WORK AROUND Use SwingUtilities.invokeLater to assign focus in the WindowListener. scott.violet@eng 2000-01-19
19-01-2000