cathalmchale
asked on
Text validation
Hi,
Could someone point me in the right direction here please?
What is the best way to validate a text field which is for filenames? Should I just wait for entry confirmation and then validate or is it nice to create a general class which could be added as a listener to all appropriate text fields?
Also - in Eclipse when you create a new class it validates the filename on-the-fly -> you must enter a valid file/class name which doesnt already exist. Perhaps I would like to implement this - HOW??
Thanks,
Cathal.
Could someone point me in the right direction here please?
What is the best way to validate a text field which is for filenames? Should I just wait for entry confirmation and then validate or is it nice to create a general class which could be added as a listener to all appropriate text fields?
Also - in Eclipse when you create a new class it validates the filename on-the-fly -> you must enter a valid file/class name which doesnt already exist. Perhaps I would like to implement this - HOW??
Thanks,
Cathal.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
So in insertString() you do your validation (e.g. checking if the file already exists)
According to the validation you "accept" the entered character(s) or not.
According to the validation you "accept" the entered character(s) or not.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Use JFileChooser
I agree with objects that using JFileChooser is the best. That's what it is made for eventually.
Just don't know how thight you're bound to the use of a text field however.
Just don't know how thight you're bound to the use of a text field however.
ASKER
Well its actually a Wizard similiar to the new class wizard in eclipse. so i dont think the file-chooser would be appropriate
Then I'd use the document approach
> so i dont think the file-chooser would be appropriate
why not?
why not?
ASKER
>> why not?
perhaps it is? note that selecting an appropriate file name is step 1 of 5 in the wizard - is it easy to extend and personalise the file-chooser?? Any examples close to what i am looking much appreciated
perhaps it is? note that selecting an appropriate file name is step 1 of 5 in the wizard - is it easy to extend and personalise the file-chooser?? Any examples close to what i am looking much appreciated
Don't know if it possible with JFileChooser to avoid that the user chooses a filename that already exists...
>>What is the best way to validate a text field which is for filenames?
Why not create a File and then call the appropriate methods on it?
Why not create a File and then call the appropriate methods on it?
ASKER
>> Why not create a File and then call the appropriate methods on it?
I have a new file object with the name the user wants to give it. is the only way to test if its a valid file(name) to create the file and then check if it exists - this seems a little "expensive", also if it is this way should i use the create tempory file method??
I have a new file object with the name the user wants to give it. is the only way to test if its a valid file(name) to create the file and then check if it exists - this seems a little "expensive", also if it is this way should i use the create tempory file method??
>> if it is this way should i use the create tempory file method??
No.
Use createNewFile():
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist.
No.
Use createNewFile():
Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist.
>> is the only way to test if its a valid file(name) to create the file and then check if it exists
Forget the previous. You can simply call exists() on the File object to check if it exist already
(See http://javaalmanac.com/egs/java.io/Exists.html)
Forget the previous. You can simply call exists() on the File object to check if it exist already
(See http://javaalmanac.com/egs/java.io/Exists.html)
ASKER
>> Forget the previous. You can simply call exists() on the File object to check if it exist already
I check for 2 things:
Problem 1: file already exists
Problem 2: invalid file identifier (user has typed a shitty name!!)
so its problem 2 thats the problem!! :) solution?? cheers
I check for 2 things:
Problem 1: file already exists
Problem 2: invalid file identifier (user has typed a shitty name!!)
so its problem 2 thats the problem!! :) solution?? cheers
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I now have a class
public class FilenameValidation extends PlainDocument
in another class i do
// the above document class
validation = new FilenameValidation(directo ry, Configuration.SUFFIX_XML, fileExists, invalidName);
validation.addDocumentList ener(this) ;
// set document of the textfield
titlePage.getNameField().s etDocument (validatio n);
so i have added this class as a document listener - thus i inherit the methods
public void insertUpdate(DocumentEvent e)
{
}
public void removeUpdate(DocumentEvent e)
{
}
public void changedUpdate(DocumentEven t e)
{
}
i just want the changes to occur -> like calling a super.insertUpdate .. or whatever! but obviously i'm not extending the class so cant!
Heres what im doing:
i add the FilenameValidation to the text field --> they can type whatever they want, but then i wanted the listener to check if file valid using my class FilenameValidation -> if its not valid then it will disable the next and finish buttons
public class FilenameValidation extends PlainDocument
in another class i do
// the above document class
validation = new FilenameValidation(directo
validation.addDocumentList
// set document of the textfield
titlePage.getNameField().s
so i have added this class as a document listener - thus i inherit the methods
public void insertUpdate(DocumentEvent
{
}
public void removeUpdate(DocumentEvent
{
}
public void changedUpdate(DocumentEven
{
}
i just want the changes to occur -> like calling a super.insertUpdate .. or whatever! but obviously i'm not extending the class so cant!
Heres what im doing:
i add the FilenameValidation to the text field --> they can type whatever they want, but then i wanted the listener to check if file valid using my class FilenameValidation -> if its not valid then it will disable the next and finish buttons
I doubt if you need a DocumentListener.
Shouldn't you just override insertString() in FilenameValidation
Shouldn't you just override insertString() in FilenameValidation
insertString() is triggered for every change that occurs in your textfield
ASKER
>> Shouldn't you just override insertString() in FilenameValidation
I have - here it is:
public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException
{
String fileName = this.getText(0, this.getLength());
if(extension != null)
fileName = fileName + extension;
// is this a valid file?
File file = new File(directory, fileName);
if(file.exists())
{
validFile = false;
problem = fileExists + ": '" + this.getText(0, this.getLength()) + "'";
}
else
{
try
{
file.createNewFile();
file.delete();
validFile = true;
problem = "";
}
catch (IOException ex)
{
************
validFile = false;
problem = invalidName + ": '" + this.getText(0, this.getLength()) + "'";
}
}
super.insertString(offset, str, attr);
}
so i thought a listener which could check each time the value of ******** validFile above -> then report the error / enable / diable Next button etc. ??
I have - here it is:
public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException
{
String fileName = this.getText(0, this.getLength());
if(extension != null)
fileName = fileName + extension;
// is this a valid file?
File file = new File(directory, fileName);
if(file.exists())
{
validFile = false;
problem = fileExists + ": '" + this.getText(0, this.getLength()) + "'";
}
else
{
try
{
file.createNewFile();
file.delete();
validFile = true;
problem = "";
}
catch (IOException ex)
{
************
validFile = false;
problem = invalidName + ": '" + this.getText(0, this.getLength()) + "'";
}
}
super.insertString(offset,
}
so i thought a listener which could check each time the value of ******** validFile above -> then report the error / enable / diable Next button etc. ??
Why not passing an instance of whatever object you need in the FilenameValidation constructor and then use it:
Some kind of:
catch (IOException ex) {
theObjectYouPassed.reportE xception(p roblem, ....);
}
Some kind of:
catch (IOException ex) {
theObjectYouPassed.reportE
}
...which can also perform additional things (like disabling buttons,...)
Have to go offline now.
See you.
See you.
ASKER
thanks ;-)
Why would you override insertString? Surely what you should do is to ask the user to choose a file name, then use it? The 'use it' stage is when you need to validate, which could be done by a button press, say.
ASKER
>> Why would you override insertString? Surely what you should do is to ask the user to choose a file name, then use it? The 'use it' stage is when you need to validate, which could be done by a button press, say.
I suggested looking at the Eclipse "new class" type wizard - check it out you'll see what im after
I suggested looking at the Eclipse "new class" type wizard - check it out you'll see what im after
ASKER
I have a further problem! When the user types a backspace things go wrong. all i need to know is
if String s is a backspace
how do i do : s.equals(**backspace**)
Cheers ;-)
if String s is a backspace
how do i do : s.equals(**backspace**)
Cheers ;-)
>>the Eclipse "new class" type wizard - check it out you'll see what im after
Ah - got a problem there - don't have it and no room on my machine to install it.
My point was centred around the fact that the insertString method is incremental. Therefore, unless you post a fully-formed file name into the text field, the method is going to be called every time you enter a single character, which is not appropriate
Ah - got a problem there - don't have it and no room on my machine to install it.
My point was centred around the fact that the insertString method is incremental. Therefore, unless you post a fully-formed file name into the text field, the method is going to be called every time you enter a single character, which is not appropriate
I didn't see your last before i posted my last - you can probably see the connection ;-)
(The incrementality works in reverse too)
(The incrementality works in reverse too)
ASKER
I want it called everytime they enter a character - the instant the filename becomes invalid (already exists / badly formed name) then the next and finish buttons are disabled and the warning displayed
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
>> you need to implement all 3 methods insertUpdate, removeUpdate, and changedUpdate.
so i'm back to using the listener again now!!
so i'm back to using the listener again now!!
>>/ badly formed name)
Wouldn't this, by virtue of the way you intend to do this, be the normal state?
Wouldn't this, by virtue of the way you intend to do this, be the normal state?
>> so i'm back to using the listener again now!!
Not at all.
>> I have a further problem! When the user types a backspace things go wrong
Sure your insertString() is triggered then? For me it isn't...
Not at all.
>> I have a further problem! When the user types a backspace things go wrong
Sure your insertString() is triggered then? For me it isn't...
ASKER
OK i use a validation class which extends PlainDocument, and you can see the insertString method posted above.
Perhaps instead i should just attach a default document to the textfield, then add a document listener and then do this insert string type validation locally??
does this sound more correct?????
Perhaps instead i should just attach a default document to the textfield, then add a document listener and then do this insert string type validation locally??
does this sound more correct?????
Adapt your insertString() code as follows:
Replace
>> String fileName = this.getText(0, this.getLength());
>> if(extension != null)
>> fileName = fileName + extension;
by
if (s == null || s.length() == 0)
return;
StringBuffer t = new StringBuffer(getLength() + s.length());
t.append(getText(0, index));
t.append(s);
t.append(getText(index, getLength() - index));
String fileName = t.toString();
if(extension != null)
fileName = fileName + extension;
Replace
>> String fileName = this.getText(0, this.getLength());
>> if(extension != null)
>> fileName = fileName + extension;
by
if (s == null || s.length() == 0)
return;
StringBuffer t = new StringBuffer(getLength() + s.length());
t.append(getText(0, index));
t.append(s);
t.append(getText(index, getLength() - index));
String fileName = t.toString();
if(extension != null)
fileName = fileName + extension;
Sorry replace "s" by "str" (2nd parameter)
ASKER
>> Sure your insertString() is triggered then? For me it isn't...
actually no it isnt, thats the problem! so they type an invalid name - warning shown - they hit backspace to make it valid again, but because insertString not called i do not recognise this
actually no it isnt, thats the problem! so they type an invalid name - warning shown - they hit backspace to make it valid again, but because insertString not called i do not recognise this
This code makes it even work when you copy/paste some characters in the middle of the name you already typed:
e.g.
1) You have: MyName
2) You copy "File" to the clipboard
3) You put the cursor before the 'N'
4) You paste
5) You become "MyFileName"
e.g.
1) You have: MyName
2) You copy "File" to the clipboard
3) You put the cursor before the 'N'
4) You paste
5) You become "MyFileName"
>> actually no it isnt, thats the problem!
I see. (Nevertheless I think the above changes are needed)
Thinking...
I see. (Nevertheless I think the above changes are needed)
Thinking...
ASKER
I dont fully understand your code - what is the variable "index" ?? and then of course this backspace problem, perhaps i do need to follow the listener idea?
>> what is the variable "index" ??
Oh, another one to replace, that's your offset (the 1st argument)
>> perhaps i do need to follow the listener idea?
Maybe yes indeed.
Oh, another one to replace, that's your offset (the 1st argument)
>> perhaps i do need to follow the listener idea?
Maybe yes indeed.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Typo:
>> public DocumentListener()
should have been
public MyDocListener()
>> public DocumentListener()
should have been
public MyDocListener()
ASKER
Yup the document listener was certainly the way to go!! (and then i even had access to the textField.getText() !!!)
thanks EVERYONES help.
1 last question - i add a label (with icon) to display any problems
If no problem then icon and label = "" and null
This makes the overall content pane "jump around" - whats the best way to solve this? just fix size?- inwhich case i just want to fix the height and not width!
How should i do this?
i shall have to deliberate as to how to distribut points,
cheers ;-)
thanks EVERYONES help.
1 last question - i add a label (with icon) to display any problems
If no problem then icon and label = "" and null
This makes the overall content pane "jump around" - whats the best way to solve this? just fix size?- inwhich case i just want to fix the height and not width!
How should i do this?
i shall have to deliberate as to how to distribut points,
cheers ;-)
>> This makes the overall content pane "jump around" - whats the best way to solve this?
Chosing such a layout in which you don't have that phenomenon ;°)
e.g. Place the label in the south of a (wide enough) panel having the borderlayout
>>i shall have to deliberate as to how to distribut points
Award all comments that *really* helped you and you're done.
Chosing such a layout in which you don't have that phenomenon ;°)
e.g. Place the label in the south of a (wide enough) panel having the borderlayout
>>i shall have to deliberate as to how to distribut points
Award all comments that *really* helped you and you're done.
ASKER
>> Chosing such a layout in which you don't have that phenomenon ;°)
I wish!!
not so easy in this case - the label can either be 16*16 icon and some text, or no icon no text (invisible!)
i could place it north but doesnt help!
JPanel content = new JPanel(new BorderLayout());
// file already exists / invalid name label
JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT ));
fileProblem = new JLabel();
labelPanel.add(fileProblem );
content.add(labelPanel, BorderLayout.NORTH);
// the title page content
content.add(titlePage, BorderLayout.CENTER);
//JideSwingUtilities.setOp aqueRecurs ively(titl ePage, false);
return content;
I wish!!
not so easy in this case - the label can either be 16*16 icon and some text, or no icon no text (invisible!)
i could place it north but doesnt help!
JPanel content = new JPanel(new BorderLayout());
// file already exists / invalid name label
JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT
fileProblem = new JLabel();
labelPanel.add(fileProblem
content.add(labelPanel, BorderLayout.NORTH);
// the title page content
content.add(titlePage, BorderLayout.CENTER);
//JideSwingUtilities.setOp
return content;
Don't understand:
If your titlePage which is in the center has the preferred width of let's say 400,
your panel in the north will have 400 pixels available too. (That's how a BorderLayout works)
Then, the label placed in the north (no matter if it has icon/text or not) always has 400 pixels to use.
Then why should there be jumping around?
If your titlePage which is in the center has the preferred width of let's say 400,
your panel in the north will have 400 pixels available too. (That's how a BorderLayout works)
Then, the label placed in the north (no matter if it has icon/text or not) always has 400 pixels to use.
Then why should there be jumping around?
>> always has 400 pixels to use.
always has 400 pixels available to use.
always has 400 pixels available to use.
ASKER
>> Then why should there be jumping around?
the width aint the problem its the height
the width aint the problem its the height
And this doesn't help?
fileProblem.setPreferredSi ze( new Dimension(100, 17) );
fileProblem.setMinimumSize ( new Dimension(10, 17) );
fileProblem.setMaximumSize ( new Dimension(Integer.MAX_VALU E, 17) );
fileProblem.setPreferredSi
fileProblem.setMinimumSize
fileProblem.setMaximumSize
Maybe you'll have to repeat those lines after each occurrence of
fileProblem.setIcon(...);
fileProblem.setText(...);
fileProblem.setIcon(...);
fileProblem.setText(...);
ASKER
yeah for sure it does but a number of times in the past i would have liked to have been able to specify 1 and allow the other to be chosen by the component itself:
i tried this but it didnt work:
JPanel content = new JPanel(new BorderLayout());
// file already exists / invalid name label
JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT ))
{
public Dimension getMinimumSize()
{
return new Dimension(fileProblem.getW idth(), 17);
}
};
fileProblem = new JLabel();
labelPanel.add(fileProblem );
content.add(labelPanel, BorderLayout.NORTH);
// the title page content
content.add(titlePage, BorderLayout.CENTER);
//JideSwingUtilities.setOp aqueRecurs ively(titl ePage, false);
return content;
i tried this but it didnt work:
JPanel content = new JPanel(new BorderLayout());
// file already exists / invalid name label
JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT
{
public Dimension getMinimumSize()
{
return new Dimension(fileProblem.getW
}
};
fileProblem = new JLabel();
labelPanel.add(fileProblem
content.add(labelPanel, BorderLayout.NORTH);
// the title page content
content.add(titlePage, BorderLayout.CENTER);
//JideSwingUtilities.setOp
return content;
Try
public class MyLabel extends JLabel {
public Dimension getMinimumSize() {
return new Dimension(super.getMinimum Size().wid th, 17);
}
public Dimension getMaximumSize() {
return new Dimension(super.getMaximum Size().wid th, 17);
}
public Dimension getPreferredSize() {
return new Dimension(super.getPreferr edSize().w idth, 17);
}
}
Have to go ofline again. Sorry.
Success
public class MyLabel extends JLabel {
public Dimension getMinimumSize() {
return new Dimension(super.getMinimum
}
public Dimension getMaximumSize() {
return new Dimension(super.getMaximum
}
public Dimension getPreferredSize() {
return new Dimension(super.getPreferr
}
}
Have to go ofline again. Sorry.
Success
ASKER
actually this works, thanks:
JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT ))
{
public Dimension getMinimumSize()
{
return new Dimension(fileProblem.getW idth(), 25);
}
public Dimension getPreferredSize()
{
return getMinimumSize();
}
};
JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT
{
public Dimension getMinimumSize()
{
return new Dimension(fileProblem.getW
}
public Dimension getPreferredSize()
{
return getMinimumSize();
}
};
Thanks for accepting
ASKER
Sorry, what?? you mean extend JTextField or something?