I came across this code:
public class Board extends JPanel implements ActionListener{
public Board() {
setFocusable(true);
}
}
What exactly does setFocusable(true) do to the JPanel object? What is the notion of a component being focused?
Based on the Java API, this method is located in the Component class, the super class of JPanel. The method description states "Sets the focusable state of this Component to the specified value. This value overrides the Component's default focusability." This description sounds way too technical and high-level jargon for me (who just finished a Java class in the summer). Sometimes, I think these method descriptions were not written for all people with different levels of knowledge of Java. May someone explain the method description in layman's terms?
The focusable flag indicates whether a component can gain the focus if it is requested to do so. The JPanel component is focusable by default, so nothing will be changed when you set it to true.
A component that is not focusable can not gain the focus.
An example
Let's say you have implemented a dialog with several text fields and you want the user to enter some text. When the user starts typing, one text field needs to have the focus of the application: it will be the field that receives the keyboard input.
When you implement a focus traversal (a convenient way for the user to jump from one text field to the next, for example by using the tab button), the user can "jump" to the next text field. The application will try to gain the focus for the next field to prepare it to receive text. When the next field is not focusable, this request will be denied and the next field will be tested. For example, you wouldn't want a label to get the focus because you cannot enter text into it.
The focusable flag is set to true by default in the Component class. When you construct an object derived from the Component class (for example, when you construct your JPanel), the constructor of the Component class is called and sets the default focusable flag to true.
Derived classes that wish to override this default can call the method setFocusable to change that default, like you did in your example.
Note that setFocusable does not set the focus in itself, it just gives the ability to potentially gain the focus to the component.
You can use setFocusable(boolean n), it´s mainly used to activate or deactivate the focus event (component of the graphical user interface that is selected to receive the input) of the view, both in the tactile / mouse mode, and in the keyboard (cursor) mode.
setFocusable() is actually a method from the Component class in Swing.
public void setFocusable(boolean focusable)
It lets the component (in your case, JPanel which extends Component) have the power of getting focused. It doesn't actually set the component to be focused, it just indicates if the component can be focused or not, which is determined by the boolean parameter passed.
Related
I have a class, like so:
public class MyFrame extends javax.swing.JFrame implements KeyListener { ... }
In the constructor:
addKeyListener(this);
setFocusable(true);
This works as long as the window itself is in focus. If I focus on a component within that window, the key listener no longer listens. I want it so that whenever the window is the active window, but regardless on which specific sub-component the focus is on, the key listener will be triggered. I wish to keep focus traversal keys, for quality of life, but they're not critical.
How do I do this?
Preferably you would use the key bindings API for each component, you can use the key bindings to change the level of focus required to trigger the given action, for example, for when the component has focus, when the component is a child of a focused component or when it is contained within the focused window...
See How to Use Key Bindings for more details
Add the KeyListener recursively to the sub components.
Check this
How to get all elements inside a JFrame?
i hope this could help!
Its generic question. If I add some UI objects such as JButton etc and check the isVisible property, it would return true. However, does it guarantee that the object is actually rendered and visible correctly on the display? If not, is there some better way to check the same?
No isVisible() is only a hint for this component itself. If it is really visible for the user depends on the parent hierarchy of the component. This can be verified best by isShowing() inherited by Component, which checks isVisible() and isDisplayable() of the component and all it's parent components. But as the javadoc mentions even that does not really guarantee that the component is really really visible to the user:
Note: sometimes there is no way to detect whether the Component is actually visible to the user. This can happen when:
the component has been added to a visible ScrollPane but the Component is not currently in the scroll pane's view port.
the Component is obscured by another Component or Container.
I have a CardDetailsPanel class which contains several JLabels and JTextFields. This class in contained in a AddCardsPanel and is initialized as follows:
cardDetailsPanel = new CardDetailsPanel(true);
add(cardDetailsPanel, java.awt.BorderLayout.CENTER);
I also have a JLabel that contains instructions. I want to update this label when the CardDetailsPanel first appears and when focus changes to each JTextField. I have found the addFocusListener() method that will work for the later. However, my compenentShown() method isn't working for the former:
addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentShown(java.awt.event.ComponentEvent evt) {
formComponentShown(evt);
}
});
(Okay, I know this is ugly. It was generated by NetBeans.)
private void formComponentShown(java.awt.event.ComponentEvent evt) {
this.frame = (BaseballFrame) this.getParent().getParent().getParent().getParent().getParent().getParent();
}
(Yah, this is even uglier. I'll deal with the chained getParent() calls later. I want to do other things here as well.)
So why doesn't my listener get called? And how do I write a listener that will perform some actions whenever my CardDetailsPanel appears on the screen?
Use an AncestorListener as described in dialog focus.
When a JDialog (or JFrame for that matter) is made visible, focus is placed on the first focusable component by default. There may be times when you want to change this behaviour. The obvious solution would be to invoke the requestFocusInWindow() method on the component you wish to receive focus. The problem is that this doesn’t work all the time.
...
The problem is .. a component can’t request focus unless it has been added to a “realized” dialog. A realized dialog basically means that the Swing JDialog has been added to a peer component that represents a dialog on the underlying OS. This occurs when you invoke the pack() or setVisible(true) methods on the JDialog.
And that is where the ancestor listener comes in handy. For a component in a modal dialog, it will be fired once the component becomes visible, and is realized & focusable.
Edit:
The above comment applies to components in any Swing container, including JFrame and JPanel.
I have a Java app that I'll call App. App will occasionally display a JFrame that we'll call myFrame. App will also display a JTextArea that is contained in either a JDialog or a JFrame (I'm not sure which, but I can find out if that's necessary to answer this question). Let's call this JTextArea "myTextArea".
Now, the following sequence of events happens:
We display myFrame. It has the focus and you can give it input.
We call myFrame.setVisible(false)
We display myTextArea.
We call myTextArea.requestFocus().
myTextArea has the focus (the cursor is blinking with in it), but all the keystrokes that are input are sent to myFrame!
Note that myTextArea is not contained in myFrame.
What is going on here? Has anyone heard of a non-visible JFrame receiving keystrokes? Not only receiving keystrokes but stealing them from some other component that has the focus?
I found what’s basically causing the problem. MyFrame has a class MyKeyEventHandler that implements KeyEventDispatcher. The method dispatchKeyEvent(KeyEvent e) is always returning false even for key strokes that are intended for myTextArea. Therefore the key strokes do not reach myTextArea.
It is not about toggling the visibility. The JFrame is initialized first and still has focus. You are only making it invisible, not taking away the focus from it.
Moreover, your JTextBox needs to have a parent container. Possibly
myFrame.add(myTextArea);
should work. To shift the focus to the JTextArea, use :
myTextArea.requestFocus();
in my application i get a component to focus ,
it could be a jpanel , and is could be a jbutton or a user custom made component
how can i know when to call transferFosus ,and when to call requestFocus
thanks you
transferFocus() sends focus to the next component. Also note that
transferFocus() will always transfer the focus in the forward direction.
requestFocus() sends focus to calling component. However, there is no guarantee that this will be successful. Focus behavior is platform-dependent to certain extend.
The recommended mentod for gaining focus is to use requestFocusInWindow(). Refer to this post - might come very handy in playing with focus.
Use transferFocus() when you want to advance focus according to the focus order.
requestFocus() is used to explicitly set the focus to a component.
Some background reading in Focus on Swing
It's rare that you would need to call either since its usually appropriate to let the user's keyboard/mouse actions determine focus. But transferFocus send focus away from your component and requestFocus brings focus to your component.