This discussion is archived
4 Replies Latest reply: Aug 24, 2012 2:27 PM by 929204 RSS

Ctrl-TAB moves focus from JTextArea even tho focus traversal keys disabled

929204 Newbie
Currently Being Moderated
Hello everyone,

I hope someone can help me with this problem because I've tried everything I can think of, I've scoured Google, I'm exhausted and still completely stumped.
I have a JTextArea, for which I've called setFocusTraversalKeysEnabled(false). I've even done the following, though I don't think it's necessary:
setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
When I put the text area in a window (JFrame), the expected happens - Ctrl-TAB doesn't move the focus.
HOWEVER, when I put two of these JTextAreas in a JSplitPane, Ctrl-TAB jumps the focus to a JTextField at the bottom of the window (outside of the JSplitPane)!
I've confirmed with various calls to getFocusTraversalKeysEnabled() that the traversal keys are indeed disabled (and remaining disabled).
Calling setFocusTraversalKeysEnabled(false) for the JSplitPane doesn't change anything...

If I catch Ctrl-TAB in a key listener registered on the JTextAreas and consume the event, the focus doesn't move. That is one solution I suppose, but I'm really bugged by the fact that for some reason setFocusTraversalKeysEnabled(false) isn't working.
Does anyone have any ideas why this could be happening?
THANKS!
  • 1. Re: Ctrl-TAB moves focus from JTextArea even tho focus traversal keys disabled
    aterai Journeyer
    Currently Being Moderated
    Hi, you might be able to use a JSplitPane#setFocusCycleRoot(boolean):
    import java.awt.*;
    import javax.swing.*;
    public class FocusTraversalKeysTest {
      public JComponent makeUI() {
        JPanel p = new JPanel();
        p.add(new JButton("111"));
        p.add(new JButton("222"));
        p.add(new JButton("333"));
    
        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPane.setResizeWeight(.5);
        splitPane.setFocusCycleRoot(true);
        splitPane.setTopComponent(new JScrollPane(makeTextArea()));
        splitPane.setBottomComponent(new JScrollPane(makeTextArea()));
    
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(p, BorderLayout.NORTH);
        panel.add(splitPane);
        return panel;
      }
      private JTextArea makeTextArea() {
        JTextArea textArea = new JTextArea(16,12);
        textArea.setFocusTraversalKeysEnabled(false);
        return textArea;
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          @Override public void run() { createAndShowGUI(); }
        });
      }
      public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new FocusTraversalKeysTest().makeUI());
        f.setSize(320, 240);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
      }
    }
  • 2. Re: Ctrl-TAB moves focus from JTextArea even tho focus traversal keys disabled
    929204 Newbie
    Currently Being Moderated
    Thank you for your reply and for your sample code.

    Interestingly, calling setFocusCycleRoot(true) for the JSplitPane DID make Ctrl-TAB ineffective. However, for some reason, Shift-Ctrl-TAB still jumped out of the text areas.
    What I did next is try calling setFocusCycleRoot(true) for the JPane parent that contains the JSplitPane, and that did the trick.

    There was still an issue, however. I have to nest split panes if the user gives a command to create more panes. When I nested split panes, I found that I could move the focus via Ctrl-TAB and Shift-Ctrl-TAB from within the nested panes. So the solution only worked for a single split pane and not for nested split panes. This still seems odd to me, since I am positive that I turned off the focus traversal keys in every existing text area.

    I found one thing that worked, and your example code was a good clue. I set the parent pane containing all split panes and text areas to be the focus cycle root, AND then I set its focus traversal policy, as follows:
              editorPaneParentContainer.setFocusCycleRoot(true);
              editorPaneParentContainer.setFocusTraversalPolicy(new InternalFrameFocusTraversalPolicy() {
                   
                   @Override
                   public Component getLastComponent(Container aContainer) {
                        // TODO Auto-generated method stub
                        return null;
                   }
                   
                   @Override
                   public Component getFirstComponent(Container aContainer) {
                        // TODO Auto-generated method stub
                        return null;
                   }
                   
                   @Override
                   public Component getDefaultComponent(Container aContainer) {
                        // TODO Auto-generated method stub
                        return null;
                   }
                   
                   @Override
                   public Component getComponentBefore(Container aContainer,
                             Component aComponent) {
                        // TODO Auto-generated method stub
                        return null;
                   }
                   
                   @Override
                   public Component getComponentAfter(Container aContainer,
                             Component aComponent) {
                        // TODO Auto-generated method stub
                        return null;
                   }
              });
    As you can see, Eclipse generated the method stubs for me and I just left them as is. Thus no focus traversal happens, and my understanding is that the parent pane to which this applies enforces this policy for all components contained inside it.

    So I guess that works, but its hardly an elegant solution.

    My intention was actually to write my own Actions for commands that move the focus, and then bind them to keys that are made available from within the text areas. Commands like "next/previous text area" as well as "next/previous window" to shuffle through frames (BTW, what I'm working on here is a text editor). I was thus thinking that I would not deal with focus cycles and traversal policies, and rather just use "toFront()" for windows and "requestFocusInWindow()" for text areas as needed, within my own Actions.
    Part of it is that I didn't want to bother learning the focus API in detail, you know? :) I actually didn't think I would need to know much about it. But the crux of the problem is that for some reason setFocusTraversalKeysEnabled(false); just isn't working for me.

    Having explained these things, what would you recommend to me? Would you recommend that I code my own focus traversal policy and customize the keys that create focus movement, all using the focus API? Or should I go forward with my original plan, and roll my own focus movements with Actions?

    In the latter case, my next question would be, do you know of an elegant way to just forcibly turn off focus traversal keys, as I tried to do in the code above?

    THANK YOU!
  • 3. Re: Ctrl-TAB moves focus from JTextArea even tho focus traversal keys disabled
    aterai Journeyer
    Currently Being Moderated
    I'm not sure of the problem, but can do this inone of two ways.
    (It's up to you to decide which of these two ways you will choose)
    just forcibly turn off focus traversal keys...
    How about using the [url http://docs.oracle.com/javase/7/docs/api/java/awt/KeyboardFocusManager.html#setDefaultFocusTraversalKeys(int, java.util.Set)]KeyboardFocusManager:
    KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
    focusManager.setDefaultFocusTraversalKeys(
        KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
        Collections.<AWTKeyStroke>emptySet());
    focusManager.setDefaultFocusTraversalKeys(
        KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
        Collections.<AWTKeyStroke>emptySet());
  • 4. Re: Ctrl-TAB moves focus from JTextArea even tho focus traversal keys disabled
    929204 Newbie
    Currently Being Moderated
    Thank you for your help, aterai!

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points