Select text with KeyBoardFocusManager

I am trying to implement a class that will automatically select all text when focus is gained.

I am using the below code. I don't know why, but it does not work until AFTER you tab through all the components once. So, if you press tab 4 times, it will begin highlighting.

Any ideas why? It is not very intuitive why it would do this...

Thanks!

/*

* NewJFrame.java

*

* Created on July 4, 2007, 10:42 AM

*/

/*

* Main.java

*

* Created on July 4, 2007, 10:41 AM

*

* To change this template, choose Tools | Template Manager

* and open the template in the editor.

*/

package javaapplication1;

import java.awt.Component;

import java.awt.DefaultKeyboardFocusManager;

import java.awt.KeyboardFocusManager;

import javax.swing.JTextField;

import javax.swing.text.JTextComponent;

/**

*

* @author student

*/

publicclass NewJFrameextends javax.swing.JFrame{

class testFocusextends DefaultKeyboardFocusManager{

publicvoid focusNextComponent(Component aComponent){

super.focusNextComponent(aComponent);

if (aComponentinstanceof JTextComponent)

((JTextComponent)aComponent).selectAll();

}

}

/** Creates new form NewJFrame */

public NewJFrame(){

initComponents();

KeyboardFocusManager.setCurrentKeyboardFocusManager(new testFocus());

}

/** This method is called from within the constructor to

* initialize the form.

* WARNING: Do NOT modify this code. The content of this method is

* always regenerated by the Form Editor.

*/

// <editor-fold defaultstate="collapsed" desc=" Generated Code ">

privatevoid initComponents(){

jTextField1 =new javax.swing.JTextField();

jTextField2 =new javax.swing.JTextField();

jTextField3 =new javax.swing.JTextField();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jTextField1.setText("jTextField1");

jTextField2.setText("jTextField2");

jTextField3.setText("jTextField3");

javax.swing.GroupLayout layout =new javax.swing.GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addGap(67, 67, 67)

.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addGap(25, 25, 25)

.addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addGap(29, 29, 29)

.addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addContainerGap(102, Short.MAX_VALUE))

);

layout.setVerticalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addGap(54, 54, 54)

.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)

.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))

.addContainerGap(226, Short.MAX_VALUE))

);

pack();

}// </editor-fold>

/**

* @param args the command line arguments

*/

publicstaticvoid main(String args[]){

java.awt.EventQueue.invokeLater(new Runnable(){

publicvoid run(){

new NewJFrame().setVisible(true);

}

});

}

// Variables declaration - do not modify

private javax.swing.JTextField jTextField1;

private javax.swing.JTextField jTextField2;

private javax.swing.JTextField jTextField3;

// End of variables declaration

}

[6290 byte] By [jonjon123a] at [2007-11-27 11:09:36]
# 1

In the future Swing related questions should be posted in the Swing forum, because thats where all the Swing solutions are found.

Also, most of us don't use IDE's so posting code generated by an IDE doesn't help since we can't execute the code because we don't have access to the layout manager being used.

I'm exactly sure whats going on, but it appears to have something to do with the caret placement. I'm guessing that the first time a text field receives focus the caret is being placed at the beginning of the text field. And the caret positioning is happening "after" the selectAll() method is invoked so the selection is removed. The next time it gains focus it is not reset, so the highlighting stays.

Another interesting observation. Try tabbing backwards and the selection never occurs.

Anyway, check out my suggestion in this posting for an alternate solution:

http://forum.java.sun.com/thread.jspa?forumID=57&threadID=764444

camickra at 2007-7-29 13:36:27 > top of Java-index,Java Essentials,Java Programming...
# 2

overide the procudure processKeyEvent instead of focusNextComponent

HimSSSa at 2007-7-29 13:36:27 > top of Java-index,Java Essentials,Java Programming...
# 3

camickr,

I will post in Swing in the future!

The tabbing backwards does not work because I did not implement "focusPreviousComponent()", however the same situation occurs. It must have "tabbed off" of that component at least once before selectAll() will work.

I understand what you mean about the carat positioning...but I'm interested in how you came up with this solution. Was it from testing (overriding a lot of functions and seeing when they were called), or is there a chart/tree that indicates the order of functions that a GUI component calls?

Thanks

jonjon123a at 2007-7-29 13:36:27 > top of Java-index,Java Essentials,Java Programming...
# 4

ProcessKeyEvent() worked too!

Here is the code. Although it is made through an IDE, it does not use any IDE-specific jars, so you can compile this on your own.

/*

* NewJFrame.java

*

* Created on July 4, 2007, 10:42 AM

*/

/*

* Main.java

*

* Created on July 4, 2007, 10:41 AM

*

* To change this template, choose Tools | Template Manager

* and open the template in the editor.

*/

import java.awt.Component;

import java.awt.DefaultKeyboardFocusManager;

import java.awt.KeyboardFocusManager;

import java.awt.event.KeyEvent;

import javax.swing.JTextField;

import javax.swing.text.JTextComponent;

/**

*

* @author student

*/

public class NewJFrame extends javax.swing.JFrame {

class testFocus extends DefaultKeyboardFocusManager {

/*

public void focusNextComponent(Component aComponent) {

super.focusNextComponent(aComponent);

if (aComponent instanceof JTextComponent)

((JTextComponent)aComponent).selectAll();

}

*/

public void processKeyEvent(Component focusedComponent, KeyEvent e) {

super.processKeyEvent(focusedComponent, e);

((JTextComponent)focusedComponent).selectAll();

}

}

/** Creates new form NewJFrame */

public NewJFrame() {

initComponents();

KeyboardFocusManager.setCurrentKeyboardFocusManager(new testFocus());

}

/** This method is called from within the constructor to

* initialize the form.

* WARNING: Do NOT modify this code. The content of this method is

* always regenerated by the Form Editor.

*/

// <editor-fold defaultstate="collapsed" desc=" Generated Code ">

private void initComponents() {

jTextField1 = new javax.swing.JTextField();

jTextField2 = new javax.swing.JTextField();

jTextField3 = new javax.swing.JTextField();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jTextField1.setText("jTextField1");

jTextField2.setText("jTextField2");

jTextField3.setText("jTextField3");

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addGap(67, 67, 67)

.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addGap(25, 25, 25)

.addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addGap(29, 29, 29)

.addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addContainerGap(102, Short.MAX_VALUE))

);

layout.setVerticalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()

.addGap(54, 54, 54)

.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)

.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

.addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))

.addContainerGap(226, Short.MAX_VALUE))

);

pack();

}// </editor-fold>

/**

* @param args the command line arguments

*/

public static void main(String args[]) {

java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {

new NewJFrame().setVisible(true);

}

});

}

// Variables declaration - do not modify

private javax.swing.JTextField jTextField1;

private javax.swing.JTextField jTextField2;

private javax.swing.JTextField jTextField3;

// End of variables declaration

}

jonjon123a at 2007-7-29 13:36:27 > top of Java-index,Java Essentials,Java Programming...
# 5

> ProcessKeyEvent() worked too!

Doesn't sound to me like it would be very efficient. What happens when you type characters "a, b, c, d..."? Doesn't that method get invoked as well. You are only concerned with a focus change.

> , it does not use any IDE-specific jars

GroupLayout is new in JDK6 and many people (including me) don't update to new versions as soon as they are released. So I guess I won't be able to help you in the future.

camickra at 2007-7-29 13:36:27 > top of Java-index,Java Essentials,Java Programming...
# 6

Yeah, it gets invoked, you're right, pretty inefficient.

GroupLayout: I did not realize that it is a new feature in JDK6. I mentioned it because previously, the NetBeans IDE would link a IDE-specific jar (that was around 2MB) & needed to be included with the distribution.

--

I did your it your way "camickr" and it works better. Thanks!

jonjon123a at 2007-7-29 13:36:27 > top of Java-index,Java Essentials,Java Programming...