3

I'm having issues giving focus to a JScrollPane. I'm trying to do this when the window is created so that I can try out the key bindings I'm working on. Everything shows up where it's supposed to be and at the correct size. What I've got looks like this:

import java.awt.*;
import java.swing.*;

public class MyInterface extends JFrame {
   public MyInterface() {}

   public static void main(String[] args) {
      javax.swing.SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGUI();
         }
      });
   }

   private static void createAndShowGUI() {
      // define custom table model
      JTable table = new JTable(model);
      MyScrollPane scrollPane = new MyScrollPane(table);
      MyInterface frame = new MyInterface();
      scrollPane.setPreferredSize(new Dimension(512, 512));
      frame.getContentPane().add(scrollPane);
      frame.pack();
      frame.setVisible();
      scrollPane.requestFocus();
   }
}

public class MyScrollPane extends JScrollPane implements KeyListener {
   public MyScrollPane(Component view) {
      super(view, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
   }

   // key event processing
}

I tried adding a window listener to the frame which would request focus for scrollPane after the window was finished opening, but it didn't help. Any ideas?

EDIT: Thought I should mention that scrollPane.isFocusable() and scrollPane.isRequestFocusEnabled both return true, so I should be able to give it focus.

EDIT: It seems I'm unable to give focus to anything (frame, table, etc.), so there's some other problem here. No matter what I try, this displays null:

Component compFocusOwner =   KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
System.out.println("focus owner: " + compFocusOwner);
bendicott
  • 369
  • 2
  • 17
  • 2
    Why does the code extend `JScrollPane`? It is generally preferred to avoid extending classes, and nothing seen in the example justifies it. BTW - For better help sooner, post an [SSCCE](http://pscode.org/sscce.html). – Andrew Thompson Aug 23 '11 at 08:17

4 Answers4

4

Why do you need this? I think you should set focus on the component inside the JScrollPane. How do you detect that the focus isn't there? Scrollpane itself has no visible part (may be just 1 pixel frame is visible).

StanislavL
  • 56,971
  • 9
  • 68
  • 98
  • hmmmm again faster than me +1 – mKorbel Aug 23 '11 at 06:29
  • Sorry, I didn't think anyone would want my test code. I added this line after attempting to give scrollPane focus: System.out.println("scrollPane has focus?: " + scrollPane.hasFocus()); – bendicott Aug 23 '11 at 07:01
4

I think that not possible to set the Focus to the JScrolPane, but set Focus to the JComponent, which is place into JScrolPane couldn't be problem

    Runnable doRun = new Runnable() {

        @Override
        public void run() {
            myComponent.requestFocus();//requestFocusInWindow
            myComponent.grabFocus();
        }
    };
    SwingUtilities.invokeLater(doRun);
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • I tried this on the table inside the scroll pane, but it won't allow me to give that focus either, apparently. I'd rather focus the scroll pane anyways if at all possible; I'm adding a KeyListener to allow scrolling on the scroll pane through the arrow keys; basically, I'm using the scroll pane to house a game's map, so I'd rather the container interpret key events than the contents, as the map will be changing every now and then. Also, because the key handlers will be moving the scrollbars, it'd be a lot messier to have the table controlling that than the scroll pane itself. – bendicott Aug 23 '11 at 07:08
  • then just add as last line `myTable.changeSelection(row, col, false, false);` – mKorbel Aug 23 '11 at 07:16
  • Oh, I meant that the contents would be changing, not the table itself (I'm planning on adding destructible terrain, but that's another topic); there will be multiple tables, but only one displayed at a time. For example, one table for the overworld map, one for inside a building. It would be impractical to edit the overworld map itself every time the player walked into a store (which would also be a much smaller map), so I'll simply swap the contents as needed. This would require that every map have code for interpreting key events intended for scrolling though, which isn't exactly intuitive. – bendicott Aug 23 '11 at 07:28
  • At any rate, I tried the code above but couldn't get the table focused. There's still some problem with the code I've got... – bendicott Aug 23 '11 at 07:43
  • I'm sorry no idea what you are trying, fro code that you posted works from me in 1) create new JTable on Runtime, 2) switching betweens Cards which are Layed by CardLayout, 3) create new JPanel with JScrollPane and with JTable, really now I don't know another way, or are you want to edit this TableCell at Focus??? – mKorbel Aug 23 '11 at 07:58
  • I have a frame with a scrollPane in it, with a table in it, with ImageIcons (game tiles) in it. The scrollPane implements KeyListener, allowing me to scroll with the keyboard. To intercept key events, the scrollPane needs to be focused. At the moment, I have no interest in editing cells. I only want to focus the scrollPane. However, nothing I've tried (including the above code and a window listener added to the frame) works. For some reason, I'm unable to focus *anything*, including the frame and the table housed within the scrollPane. – bendicott Aug 23 '11 at 08:23
  • @bendicott then check post by (@trashgod +1) – mKorbel Aug 23 '11 at 08:51
3

As noted in How to Use Key Bindings: How Key Bindings Work, composite components typically use the WHEN_ANCESTOR_OF_FOCUSED_COMPONENT map. You can even add bindings to the top-level component's root pane, as shown in Key Bindings.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Thanks for the heads-up on key bindings; this looks much more powerful than implementing KeyListener. – bendicott Aug 23 '11 at 09:09
  • Agreed; see this related [example](http://stackoverflow.com/questions/5797862/draw-a-line-in-a-jpanel-with-button-click-in-java/5797965#5797965). – trashgod Aug 23 '11 at 09:17
0

I've no clue what the problem was; for lack of a better idea I deleted and retyped everything, and now it works. It is possible to focus a JScrollPane, in case anyone reading this wishes to. I assumed it was possible, since by default both .isFocusable() and isRequestFocusEnabled() are set to true. But yeah, I have no idea; at the very least I got a few good links for key binding. Thanks for the help!

bendicott
  • 369
  • 2
  • 17