This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Restricting JTextField input to Integers
Detecting JTextField “deselect” event
i need to validate a JTextField by allowing the user to input only integer values in it if user enters any char other than numbers a JOptionPane.show messagebox should appear showing that the value entered are incorrect and only integer numbers are allowed. I have coded it for a digit values but i also need to discard the alphabets
public void keyPressed(KeyEvent EVT) {
String value = text.getText();
int l = value.length();
if (EVT.getKeyChar() >= '0' && EVT.getKeyChar() <= '9') {
text.setEditable(true);
label.setText("");
} else {
text.setEditable(false);
label.setText("* Enter only numeric digits(0-9)");
}
}
Instead of using a JFormattedTextField, you may write a custom JTextField with a document that allows only integers. I like formatted fields only for more complex masks...
Take a look.
import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
/**
* A JTextField that accepts only integers.
*
* #author David Buzatto
*/
public class IntegerField extends JTextField {
public IntegerField() {
super();
}
public IntegerField( int cols ) {
super( cols );
}
#Override
protected Document createDefaultModel() {
return new UpperCaseDocument();
}
static class UpperCaseDocument extends PlainDocument {
#Override
public void insertString( int offs, String str, AttributeSet a )
throws BadLocationException {
if ( str == null ) {
return;
}
char[] chars = str.toCharArray();
boolean ok = true;
for ( int i = 0; i < chars.length; i++ ) {
try {
Integer.parseInt( String.valueOf( chars[i] ) );
} catch ( NumberFormatException exc ) {
ok = false;
break;
}
}
if ( ok )
super.insertString( offs, new String( chars ), a );
}
}
}
If you are using NetBeans to build your GUI, you just need to put regular JTextFields in your GUI and in the creation code, you will specify the constructor of IntegerField.
There is a componant for that: formatted textfield:
http://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html
Use JFormattedTextField capabilities. Have a look at example.
Related
For a school project I am writing a program where I need to retrieve user input from a JTextField. I've tried using the getText() method, but it is returning an empty string error.
String s = input.getText();
if(changeNum.equals("")){
firstNum = s;
}
if(!changeNum.equals("")){
secondNum = s;
}
firstNum and secondNum are both strings. The error that is being returned is:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: empty String
It's being returned at this line:
Double firstN = Double.parseDouble(firstNum);
What do I do? Thank you!
Edit: Forgot to add that input is the name of my JTextField, in case that is confusing.
Change all your varibles to double (firstNum etc.) and change your code like :
Note : if you not using negatIive numbers
double s = null;
try{
s = Double.parseDouble(input.getText());
}catch(NumberF... e){e.getMesssge();}
if(s > 0){
if(changeNum >= 0){
firstNum = s;
}
else {
secondNum = s;
}
}
//if you have to convert it to String use :
String str =String.valueOf(your double variable);
This is how I like to do it (in a general sense). Let's say I have a panel with three text boxes and I want to get the value of each one (each represents a different type). This is what I'd do:
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.BoxLayout;
public class Panel extends JPanel
{
JTextField textBox;
JTextField intBox;
JTextField floatBox;
JTextField dblBox;
public Panel()
{
textBox = new JTextField("Hello");
intBox = new JTextField("10");
floatBox = new JTextField("3");
dblBox = new JTextField("3.14");
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.add(textBox);
this.add(intBox);
this.add(floatBox);
this.add(dblBox);
}
public String getText()
{
return textBox.getText();
}
public int getInt()
{
try
{
return Integer.parseInt( intBox.getText() );
}
catch(NumberFormatException execp) { }
return -1;
}
public float getFloat()
{
try
{
return Float.parseFloat( floatBox.getText() );
}
catch(NumberFormatException execp) { }
return -2.0f;
}
public double getDouble()
{
try
{
return Double.parseDouble( dblBox.getText() );
}
catch(NumberFormatException execp) { }
return -2.0;
}
}
Another option is to make Panel implement ActionListener, and dblBox.addActionListener(this). Then you can get your JTextField to call a method from your parent whenever you change a number, parse the data, and write error messages in a JLabel if the casting throws an exception, or to private members if it succeeded. Then use getters to read the private members.
I have a JFrame that displays the current movies that are stored on my computer. It displays the names of the files as Strings in a JTextArea.
What I want to do is to double-click a particular String (which represents an actual file on my computer) and that file would be opened.
The opening part and double-click part is already solved, but when I double-click on the String in my JTextArea only a part of that String will be selected. (I'm using JTextArea.getSelectedText()).
What I want is that the whole String is selected and that I can retrieve the String. I need to do this since some of my movie files have similar names and the wrong file would be opened.
Is there any already implemented method that can extend the selection to a whole line? I've tried to Google the problem but nothing will select the whole line of text.
An example:
http://i47.tinypic.com/wvol6a.png
Thank you all for the input and I'm sorry that i was unclear regarding the JTextArea, the JTextArea was mandatory.
I have now a solution to my problem and I thank Hovercraft Full Of Eels for this.
Your best bet is to use a JList as has been recommended by many above. If you have to use a JTextArea, then this can be done, but you will need to use JTextArea's viewToModel(Point p) method to translate the mouse press location's Point to the offset location in your text. You can then use the javax.swing.text.Utilities class's static utility methods, getRowStart(...) and getRowEnd(...) to find the start and end of the selected row. For example, my SSCCE:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import javax.swing.text.Utilities;
public class GetLineFromTextArea {
private static final int MIN_CHARS = 4;
private static final int MAX_CHARS = 8;
private static final int WORDS_PER_LINE = 10;
private static final int ROWS = 30;
public static void main(String[] args) {
Random random = new Random();
final JTextArea textArea = new JTextArea(20, 50);
JScrollPane scrollpane = new JScrollPane(textArea);
StringBuilder sb = new StringBuilder();
for (int row = 0; row < ROWS ; row++) {
sb = new StringBuilder();
for (int words = 0; words < WORDS_PER_LINE; words++) {
int maxChars = random.nextInt(MAX_CHARS - MIN_CHARS) + MIN_CHARS;
for (int charsPerWord = 0; charsPerWord < maxChars; charsPerWord++) {
char c = (char) (random.nextInt('z' - 'a' + 1) + 'a');
sb.append(c);
}
sb.append(" ");
}
textArea.append(sb.toString() + "\n");
}
textArea.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
if (e.getClickCount() != 2) {
return;
}
int offset = textArea.viewToModel(e.getPoint());
try {
int rowStart = Utilities.getRowStart(textArea, offset);
int rowEnd = Utilities.getRowEnd(textArea, offset);
String selectedLine = textArea.getText().substring(rowStart, rowEnd);
System.out.println(selectedLine);
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}
});
JOptionPane.showMessageDialog(null, scrollpane);
}
}
Consider using a JList instead of JTextArea. JList allows you to select an element out of some set. So you just fill this set with whatever strings you need abd let the user choose.
i think a JList would be more appropriate for your needs.
simple example: http://www.cs.cf.ac.uk/Dave/HCI/HCI_Handout_CALLER/node143.html
Or is there a need to use a JTextArea?
Basically, you'd need to extract the line from that JTextArea.
But I recommend you switch to a component, which is more appropriate for your use case:
http://docs.oracle.com/javase/6/docs/api/javax/swing/JList.html
Anyway, you could try a quick and dirty hack like this:
public static String getLineOfSelectionStart(JTextArea textArea) {
String contents = textArea.getText();
int selStart = textArea.getSelectionStart();
if (selStart >= 0) {
int selEnd = selStart; // don't use getSelectionEnd(), since one
// could select multiple lines;
while (selStart > 0) {
switch (contents.charAt(selStart)) {
case '\r':
case '\n':
break;
default:
--selStart;
continue;
}
break;
}
while (selEnd < contents.length()) {
switch (contents.charAt(selEnd)) {
case '\r':
case '\n':
break;
default:
++selEnd;
continue;
}
break;
}
return contents.substring(selStart, selEnd);
}
return null;
}
But really, twiddling around with String when listing a large amount of files will not perform so well.
Use a JList and to retrieve the selected option use the getSelectedIndex() to retrieve the index or use the getSelectedValue() to get the value.
See here: see on getSelectedIndex() method
So I've been trying to figure this out but to no avail. I have to convert JTextField to an int array while having two exceptions, NumberFormatException, and ArrayIndexOutOfBoundsException. I was able to find a method to convert it, but it wont throw the NumberFormatException when I enter letters.
try {
int j=0;
String str = "" + numbersField.getText();
char digit[] = str.toCharArray();
for (int i=0; i<digit.length; i++) {
if (Character.isDigit(digit[i])) {
array[j]=Character.getNumericValue(digit[i]);
System.out.print(array[j] + " "); //Checking if it works
++j;
}
}
} catch (NumberFormatException e1) {
System.err.println("NumberFormatException: Array can only hold integers");
} catch (ArrayIndexOutOfBoundsException e1) {
System.err.println("ArrayIndexOutOfBoundsException: Array can only hold up to 10 elements");
}
Personally, I believe it's not throwing the NumberFormatException because it converts JTextField to char, but I could be totally wrong. Any help is appreciated.
EDIT: I only included part of the program since it's kinda lengthy in my opinion. Array is initialized way before this. The ultimate goal of this portion of the program is to have the user input a limit of 10 numbers while throwing an exception if a letter is inputted or if it exceeds 10 numbers. This is my first time using exceptions so I'm still relatively new to it, so please excuse me for any mistakes I've done.
You can check if whole text has only digits, then convert text to int and then put all digits to array.
Try an alternative:
String str = numbersField.getText();
try {
int value = Integer.parseInt(str);
int[] array = new int[str.lenght - 1];
j = array.length - 1;
while (value > 0) {
array[j] = value % 10;
value /= 10;
--j;
}
} catch (NumberFormatException ex) {
System.out.println("Enter only digits!")
}
UPD: also you need to check if value < 0 and show an error (if you don't accept minus sign) and use str.trim() before converting to int
Hmmm well maybe this could help, maybe not the most efficient but does its job:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class JTextFieldIntToArrayValidation extends JFrame {
private int[] integerArray;
private JButton button;
private JTextField tf;
public JTextFieldIntToArrayValidation() {
createAndShowUI();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JTextFieldIntToArrayValidation test = new JTextFieldIntToArrayValidation();
test.setVisible(true);
}
});
}
private void createAndShowUI() {
setTitle("Converting JTextField to an int array with exceptions");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
addComponentsToPane();
addListeners();
pack();
tf.grabFocus();
}
private void addComponentsToPane() {
button = new JButton("Convert JTextfield to array");
tf = new JTextField(10);
getContentPane().add(tf, BorderLayout.EAST);
getContentPane().add(button, BorderLayout.WEST);
}
private void addListeners() {
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
String tmp = tf.getText();
char[] chars = tmp.toCharArray();
integerArray = new int[chars.length];
try {
if (integerArray.length > 10) {//if digits entered are greater then 10. This however only allows for single digits!!!
throw new ArrayIndexOutOfBoundsException("Array cannot be larger then 10: " + integerArray.length);
}
for (int i = 0; i < tmp.length(); i++) {
if (!Character.isLetter(chars[i])) {//if its not a letter
integerArray[i] = Integer.parseInt(chars[i] + "");//stops java handling chars as ints
} else {//its a letter
throw new NumberFormatException("Only valid integers must be entered no letters: " + chars[i]);
}
}
printArray();
} catch (NumberFormatException | ArrayIndexOutOfBoundsException ex) {
JOptionPane.showMessageDialog(getContentPane(), ex.getMessage());
}
}
});
}
private void printArray() {
for (int i : integerArray) {
System.out.println(i);
}
}
}
Hello everyone my first question on stack overflow
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
public class TI extends JFrame implements ActionListener
{
static int count=0;
String ct;
JTextField word;
JTextArea tohide;
public static void main(String arg[])
{
TI ti=new TI();
}
public TI()
{
JPanel j=new JPanel();
JLabel def=new JLabel("Enter the text to be encrypted");
word=new JTextField("",20);
tohide=new JTextArea("",5,20);
JButton jb=new JButton("COUNT");
tohide.setBorder(BorderFactory.createLoweredBevelBorder());
j.add(def);
j.add(tohide);
j.add(word);
j.add(jb);
add(j);
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
jb.addActionListener(this);
}
public void actionPerformed(ActionEvent ae)
{
String txt=tohide.getText();
StringTokenizer stk=new StringTokenizer(txt," ");
while(stk.hasMoreTokens())
{
String token=stk.nextToken();
count++;
}
ct=Integer.toString(count);;
word.setText(ct);
}
}
I want to count the number of words that are being typed in the textarea.There is a logical error.As I keep clicking the count button the word count increases.
You never reset the count to 0 before recalculating the number of words. There doesn't seem to be a need for count to be a class variable. Making that change would make this kind of mistake impossible.
Use javax.swing.text.Utilities which has
public static final int getWordStart(JTextComponent c, int offs)
public static final int getWordEnd(JTextComponent c, int offs)
Separating by spaces is not enough. The separator could be also tab, \n etc. chars
public void actionPerformed(ActionEvent ae) {
word.setText(String.valueOf(tohide.getText().split("\\s").length));
}
I am using the following code to do the task. The idea behind it is that each pair of words is separated by a space. hence using space to split seems straight forward. if words contain carriage return, then, replacing the carriage return with empty string has to be done before counting. I hope that it helps
public int WordCount(String Words){
//Initiate Result
String s = Words+" "; //Add space after the received string
String result ="";
int i = 0;
int count = s.length();
try {
for (i = 0; i <= count - 1; i++) {
if (count - i > 1) {
String tempString = s.substring(0, s.indexOf(" "));
if (s.contains(" ") && (!s.isEmpty())) {
s = s.substring(s.indexOf(" ") + 1, s.length());
//get substring between " " and lenght ;
} else {
if(!s.isEmpty()) {
//output nothing
}
}
} else {
//output nothing;
}
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return i;
}
I have two textfield in my swing component. In one text field i need to have only numbers
(no string,empty spaces,special charaters allowed) and in another textfield i need to have only string(no numbers,empty spaces,special charaters allowed). How can i implement that..???
You can use the Pattern Class (Regular Expressions) to validate the input. A short tutorial is available here.
I am pretty sure that the basic tutorial covers all this...
"^//d+$" //The text must have at least one digit, no other characters are allowed
"^[a-zA-Z]+$" //The text must have at least one letter, no other characters are allowed
You have two choices, you can validate the text in the fields either 1) on entry or 2) when the user performs an action such as clicks a confirmation button.
For 2) npinti's answer should steer you in the right direction, just get the value of the field and validate it with a regular expression.
For 1) you might want to write a KeyListener that intercepts key presses and only allows the correct type of character for the field.
You can extend javax.swing.text.PlainDocument class, and call setDocument method textfield. Here is one of the example ;
package textfield;
import java.awt.Toolkit;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
public class LimitedValuePositiveIntegerDocument extends PlainDocument {
int maxValue;
int maxLength;
Toolkit toolkit;
/**
* Constructor for the class.
* #param max maximum value of the number
*/
public LimitedValuePositiveIntegerDocument(int max){
maxValue = max;
maxLength = (""+max).length();
toolkit = Toolkit.getDefaultToolkit();
}
/**
* Inserts the input string to the current string after validation.
* #param offs offset of the place where the input string is supposed to be inserted.
* #param str input string to be inserted
* #param a attribute set
*/
#Override
public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {
if(str == null)return;
String currentText = getText(0,getLength());
String resultText = new String();
int i;
boolean errorFound = false;
boolean deleteFirstZero = false;
int accepted=0;
for (i = 0; (i<str.length())&&(!errorFound); i++) {
if (Character.isDigit(str.charAt(i))) { /* if it is digit */
if (offs==currentText.length()) { /* calculates the resultant string*/
resultText = currentText+str.substring(0,i+1);
} else if (offs==0) {
resultText = str.substring(0,i+1)+currentText;
} else {
resultText = currentText.substring(0, offs)+str.substring(0,i+1)+currentText.substring(offs,currentText.length());
}
if (Integer.parseInt(resultText) > maxValue) {
errorFound = true;
toolkit.beep();
} else {
if ( resultText.length() == maxLength+1) {
deleteFirstZero = true;
}
accepted++;
}
} else {
errorFound = true;
toolkit.beep();
}
}
if ( accepted>0 ) { /* insert string */
super.insertString(offs, str.substring(0,accepted), a);
if (deleteFirstZero) {
super.remove(0,1);
}
}
}
/**
* Removes a part of the current string.
* #param offs offset of the place to be removed.
* #param len length to be removed
*/
#Override
public void remove(int offs, int len) throws BadLocationException{
super.remove(offs, len);
}
/**
* Returns max value of the number.
* #return max value
*/
public int getMaxValue() {
return maxValue;
}
/**
* Sets max value of the number.
* #param max maximum value of the number
*/
public void setMaxValue(int max) {
this.maxValue = max;
}
} // end of class
EDIT :
and its usage;
LimitedValuePositiveIntegerDocument doc = new LimitedValuePositiveIntegerDocument(999);
JTextField numberField = new JtextField();
numberField.setDocument(doc);
You can only enter positive numbers less than 1000, and it check while you are pressing the key..