Percent JFormattedField

D

Dmitri

Hello, guys

I'm trying to create a text field where I could enter any valid
digits for percents (let's say -900 .. 900) and have it displayed
with '%' sign, when the field looses focus or ENTER is pressed.
I am using NumberFormat.getPercentInstance() to get formatter and
it displays the initial value fine (with '%' sign). I limit my
input to digits with PercentInputFilter. The problem is, when I
delete the current contents of the field, enter my new value
(let's say 50) and click the button the value is not accepted
and reverted to the previous one. As far as I understand, with
getPercentInstance() it requires '%' char to be present. But
what I'm trying to achieve is to enter digits and have '%' to
be automatically displayed (if it's not there yet).

I am browsing doc on JFormattedText field, but could come up
with a good solution to meed my above mentioned needs.

Any suggestions, help, sample code are appreciated.
See sample code below. You can actually compile and run it
to see the problem.

Thanks
-Dmitri

<sample_code>

import javax.swing.JFormattedTextField;
import java.text.NumberFormat;
import javax.swing.text.DocumentFilter;
import javax.swing.text.BadLocationException;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;

public class SpeedField extends JFormattedTextField {

public static final int DEFAULT_COLUMNS = 11;
public static final double DEFAULT_VALUE = 1.00; // 100%

public SpeedField() {
//super(NumberFormat.getPercentInstance());
super();
setColumns(DEFAULT_COLUMNS);
setHorizontalAlignment(javax.swing.JTextField.RIGHT);

NumberFormatter formatter =
new NumberFormatter (NumberFormat.getPercentInstance()) {
protected DocumentFilter getDocumentFilter() {
return filter;
}
private DocumentFilter filter = new PercentInputFilter();
};

DefaultFormatterFactory dff = new DefaultFormatterFactory();
dff.setDefaultFormatter(formatter);
dff.setDisplayFormatter(formatter);
dff.setEditFormatter(formatter);
setFormatterFactory(dff);

setValue(new Double(DEFAULT_VALUE));
}

protected int getColumnWidth() {
return getFontMetrics(getFont()).charWidth('0');
}

private class PercentInputFilter extends DocumentFilter {

public void insertString(FilterBypass fb,
int offset,
String string,
AttributeSet attr) throws BadLocationException {

StringBuffer buffer = new StringBuffer(string);
for (int i = buffer.length() - 1; i >= 0; i--) {
char ch = buffer.charAt(i);
if (!Character.isDigit(ch) && ch != '-')
buffer.deleteCharAt(i);
}
super.insertString(fb, offset, buffer.toStri343ng(), attr);
}

public void replace(FilterBypass fb,
int offset,
int length,
String string,
AttributeSet attr) throws BadLocationException {

if (string != null) {
StringBuffer buffer = new StringBuffer(string);
for (int i = buffer.length() - 1; i >= 0; i--) {
char ch = buffer.charAt(i);
if (!Character.isDigit(ch) && ch != '-')
buffer.deleteCharAt(i);
}
string = buffer.toString();
}
super.replace(fb, offset, length, string, attr);
}

} // class PercentInputField

/** -----------------------------------------------------------------------
* TEST UNIT
*/
public static void main(String[] argv) {

javax.swing.JFrame frame = new javax.swing.JFrame("SpeedField Test");
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

final SpeedField speed = new SpeedField();
javax.swing.JPanel p = new javax.swing.JPanel();
p.add(speed);

javax.swing.JButton btValue = new javax.swing.JButton("Value");
btValue.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
System.err.println("value = " + speed.getValue());
}
});

p.add(btValue);
frame.getContentPane().add(p, java.awt.BorderLayout.NORTH);

frame.pack();
frame.setSize(new java.awt.Dimension(200, 80));
frame.setLocation(100,100);
frame.setVisible(true);

}

} // class SpeedField

</sample_code>
 
A

Andrew Thompson

On 22 Nov 2004 11:19:27 -0800, Dmitri wrote:

I'm not so experienced with JFormattedTextField to solve your
problem, though I played with your code out of interest.
See sample code below. You can actually compile and run it
to see the problem.

Good example! Except for one (late I assume) typo.
<sample_code> .....
for (int i = buffer.length() - 1; i >= 0; i--) {
char ch = buffer.charAt(i);
if (!Character.isDigit(ch) && ch != '-')
buffer.deleteCharAt(i);
}
super.insertString(fb, offset, buffer.toStri343ng(), attr);
.....

Where did the '343' come from?

BTW - Please do not x-post so widely, I recommend you set the
Follow-Ups to c.l.j.gui *only* (as I have done).
The people that can answer this are on c.l.j.gui, if anywhere.
 
D

Dmitri

Andrew Thompson said:
On 22 Nov 2004 11:19:27 -0800, Dmitri wrote:

I'm not so experienced with JFormattedTextField to solve your
problem, though I played with your code out of interest.


Good example! Except for one (late I assume) typo.

....

Where did the '343' come from?

Sure, it's a typo... probably my emacs editing window had focus
when I was typing line number for debugging...
Thanks for reply anyway!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top