W
Webby
Hi I've a attached a demo bit of code to go along with the problem explanation that follows.
Basically I have found that if I have a simple JFormattedTextField but assign a formatter to it and
an inputverifier the caret always seems to be set on the left had side when focus is given, even if
you try and force the position on a focus even.
In the following example I have two JFormattedTextFeilds, one is normal with no changes made, its
set to 10 if you change the cursor position and then tab out and tab back in the position is
remembered. The other field however has the formatter and verifier on it. It doesn't remember the
cursor position and even if I try and catch the focus and set it to position 1 it has no effect.
Has anybody any idea's if this is a problem with my code or maybe even the Sun classes ? There are
probably much better ways of doing this. But basically I wanted to stop the user losing focus if an
invalid value was entered, say 1000, but obviously when focus is regained if they want to edit the
value they don't want to have to move the cursor to the end again.
Try it out.
Cheers
Steve
-----------------------------
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.text.NumberFormat;
import java.text.ParseException;
import javax.swing.*;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;
public class testframe extends JFrame {
/** Creates new form testframe */
public testframe() {
initComponents();
noneValidatedField.setText("10");
setupIntegerEditor(validatedtField, 10, 1, 999);
}
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
jPanel1 = new javax.swing.JPanel();
validatedtField = new javax.swing.JFormattedTextField();
noneValidatedField = new javax.swing.JFormattedTextField();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setResizable(false);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
exitForm(evt);
}
});
jPanel1.setLayout(new java.awt.GridBagLayout());
validatedtField.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
validatedtFieldFocusGained(evt);
}
public void focusLost(java.awt.event.FocusEvent evt) {
validatedtFieldFocusLost(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 2;
gridBagConstraints.ipadx = 169;
gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
jPanel1.add(validatedtField, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.ipadx = 169;
gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
jPanel1.add(noneValidatedField, gridBagConstraints);
getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
pack();
}
private void validatedtFieldFocusLost(java.awt.event.FocusEvent evt) {
validatedtField.setCaretPosition(1);
}
private void validatedtFieldFocusGained(java.awt.event.FocusEvent evt) {
validatedtField.setCaretPosition(1);
}
private void exitForm(java.awt.event.WindowEvent evt) {
System.exit(0);
}
private void setupIntegerEditor(final JFormattedTextField jftf, int
value, int min, int max) {
// Create integer formatter setting the min and max integer values
NumberFormat integerFormat = NumberFormat.getIntegerInstance();
NumberFormatter intFormatter = new NumberFormatter(integerFormat);
intFormatter.setMinimum(new Integer(min));
intFormatter.setMaximum(new Integer(max));
jftf.setFormatterFactory(new DefaultFormatterFactory(intFormatter));
jftf.setInputVerifier(new QtyVerifier());
jftf.setValue(new Integer(value));
// Setup input map
jftf.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "check");
jftf.getActionMap().put("check", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
NumberFormatter formatter = (NumberFormatter)jftf.getFormatter();
if(formatter != null) {
try {
formatter.stringToValue(jftf.getText());
System.out.println("value is valid on enter");
} catch (ParseException pe) {
jftf.selectAll();
System.out.println("Value must be between " +
formatter.getMinimum() + " and " + formatter.getMaximum());
}
}
}
});
}
class QtyVerifier extends InputVerifier {
public QtyVerifier() {
}
public boolean verify(JComponent input) {
if(!(input instanceof JFormattedTextField))
return true;
JFormattedTextField jftf = (JFormattedTextField)input;
NumberFormatter formatter =
(NumberFormatter)jftf.getFormatter();
if(formatter == null)
return true;
try {
formatter.stringToValue(jftf.getText());
System.out.println("value is valid on qty check ");
return true;
} catch (ParseException pe) {
jftf.selectAll();
System.out.println("Value must be between " +
formatter.getMinimum() + " and " + formatter.getMaximum());
}
return false;
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
new testframe().show();
}
// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
private javax.swing.JFormattedTextField noneValidatedField;
private javax.swing.JFormattedTextField validatedtField;
// End of variables declaration
}
Basically I have found that if I have a simple JFormattedTextField but assign a formatter to it and
an inputverifier the caret always seems to be set on the left had side when focus is given, even if
you try and force the position on a focus even.
In the following example I have two JFormattedTextFeilds, one is normal with no changes made, its
set to 10 if you change the cursor position and then tab out and tab back in the position is
remembered. The other field however has the formatter and verifier on it. It doesn't remember the
cursor position and even if I try and catch the focus and set it to position 1 it has no effect.
Has anybody any idea's if this is a problem with my code or maybe even the Sun classes ? There are
probably much better ways of doing this. But basically I wanted to stop the user losing focus if an
invalid value was entered, say 1000, but obviously when focus is regained if they want to edit the
value they don't want to have to move the cursor to the end again.
Try it out.
Cheers
Steve
-----------------------------
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.text.NumberFormat;
import java.text.ParseException;
import javax.swing.*;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;
public class testframe extends JFrame {
/** Creates new form testframe */
public testframe() {
initComponents();
noneValidatedField.setText("10");
setupIntegerEditor(validatedtField, 10, 1, 999);
}
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
jPanel1 = new javax.swing.JPanel();
validatedtField = new javax.swing.JFormattedTextField();
noneValidatedField = new javax.swing.JFormattedTextField();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setResizable(false);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
exitForm(evt);
}
});
jPanel1.setLayout(new java.awt.GridBagLayout());
validatedtField.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
validatedtFieldFocusGained(evt);
}
public void focusLost(java.awt.event.FocusEvent evt) {
validatedtFieldFocusLost(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 2;
gridBagConstraints.ipadx = 169;
gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
jPanel1.add(validatedtField, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.ipadx = 169;
gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
jPanel1.add(noneValidatedField, gridBagConstraints);
getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);
pack();
}
private void validatedtFieldFocusLost(java.awt.event.FocusEvent evt) {
validatedtField.setCaretPosition(1);
}
private void validatedtFieldFocusGained(java.awt.event.FocusEvent evt) {
validatedtField.setCaretPosition(1);
}
private void exitForm(java.awt.event.WindowEvent evt) {
System.exit(0);
}
private void setupIntegerEditor(final JFormattedTextField jftf, int
value, int min, int max) {
// Create integer formatter setting the min and max integer values
NumberFormat integerFormat = NumberFormat.getIntegerInstance();
NumberFormatter intFormatter = new NumberFormatter(integerFormat);
intFormatter.setMinimum(new Integer(min));
intFormatter.setMaximum(new Integer(max));
jftf.setFormatterFactory(new DefaultFormatterFactory(intFormatter));
jftf.setInputVerifier(new QtyVerifier());
jftf.setValue(new Integer(value));
// Setup input map
jftf.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "check");
jftf.getActionMap().put("check", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
NumberFormatter formatter = (NumberFormatter)jftf.getFormatter();
if(formatter != null) {
try {
formatter.stringToValue(jftf.getText());
System.out.println("value is valid on enter");
} catch (ParseException pe) {
jftf.selectAll();
System.out.println("Value must be between " +
formatter.getMinimum() + " and " + formatter.getMaximum());
}
}
}
});
}
class QtyVerifier extends InputVerifier {
public QtyVerifier() {
}
public boolean verify(JComponent input) {
if(!(input instanceof JFormattedTextField))
return true;
JFormattedTextField jftf = (JFormattedTextField)input;
NumberFormatter formatter =
(NumberFormatter)jftf.getFormatter();
if(formatter == null)
return true;
try {
formatter.stringToValue(jftf.getText());
System.out.println("value is valid on qty check ");
return true;
} catch (ParseException pe) {
jftf.selectAll();
System.out.println("Value must be between " +
formatter.getMinimum() + " and " + formatter.getMaximum());
}
return false;
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
new testframe().show();
}
// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
private javax.swing.JFormattedTextField noneValidatedField;
private javax.swing.JFormattedTextField validatedtField;
// End of variables declaration
}