Multiple Jtextfields to be filled before Jbutton enable - java

Hi I badly need some help I already search about Jtextfield to be filled before jbutton enables, DocumentListener most people use to determined if Jtextfield is being populated. I tried DocumentListener and it works but all I want is all Jtextfield must be not empty before the Jbutton enables here is my code.
Ftext.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent e) {
change();
}
#Override
public void removeUpdate(DocumentEvent e) {
change();
}
#Override
public void changedUpdate(DocumentEvent e) {
change();
}
private void change(){
if (Ftext.getText().equals("") && Mtext.getText().equals("") && Ltext.getText().equals("") && Addtext.getText().equals("")) {
SaveButton.setEnabled(false);
} else {
SaveButton.setEnabled(true);
}
}
});

if (Ftext.getText().equals("") && Mtext.getText().equals("") && Ltext.getText().equals("") && Addtext.getText().equals(""))
Means that all the fields must be empty. Some times you need to read this logic aloud...
"if field is empty AND field is empty AND field is empty..."
If you used || (or) instead, it would mean that if any one of the fields was empty the statement would be true for example...
if (Ftext.getText().equals("") ||
Mtext.getText().equals("") ||
Ltext.getText().equals("") ||
Addtext.getText().equals("")) {...
You should also consider using .getText().isEmpty() or .getText().trim().isEmpty() if the fields shouldn't contain just spaces.
You might also consider writing a single DocumentListener implementation instead of creating a new anonymous class for each field
public class FieldValidationHandler implements DocumentListener() {
private List<JTextField> monitorFields;
public FieldValidationHandler(JTextField... fields) {
monitorFields = Arrays.asList(fields);
for (JTextField field : monitorFields) {
field.getDocument().addDocumentListener(this);
}
}
#Override
public void insertUpdate(DocumentEvent e) {
change();
}
#Override
public void removeUpdate(DocumentEvent e) {
change();
}
#Override
public void changedUpdate(DocumentEvent e) {
change();
}
private void change(){
boolean enabled = true;
for (JTextField field : monitorFields) {
if (field.getText().trim().isEmpty()) {
enabled = false;
break;
}
}
SaveButton.setEnabled(enabled);
}
}
Then you'd just create a single instance...
FieldValidationHandler handler = new FieldValidationHandler(Ftext, Mtext, Ltext, Addtext);
Now, this approach is a little sneaky, in that it adds the DocumentListener to the fields you specify via the constructor automatically.
Another approach might be to have some kind "Validation" controller, that you would pass to this handler and it would call some kind of "validate" method when change was called.
This would separate the listener from the fields, but this is all a matter of context at the time.
I would personally have a "register" and "unregister" process which would allow you to add or remove fields as you need to

Related

button doesn't turn disabled when textArea is empty

I added a documentListener to a jTextArea, which should set a button disabled whenever the textArea is empty.
This works just at the starting point when the textArea is empty, but when I type something and then delete all the text until textArea.getText() == "", the button still doesn't turn disabled again.
This is what I wrote:
textArea.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent e) {
if (textArea.getText() == null) {
disableButton();
} else {
enableButton();
}
}
#Override
public void removeUpdate(DocumentEvent e) {
if (textArea.getText() == null) {
disableButton();
} else {
enableButton();
}
}
#Override
public void changedUpdate(DocumentEvent e) {
if (textArea.getText() == null) {
disableButton();
} else {
enableButton();
}
}
public void enableButton() {
clearModelMenuItem.setEnabled(true);
discardModel.setEnabled(true);
increaseFontSize.setEnabled(true);
decreaseFontSize.setEnabled(true);
incMenuItem.setEnabled(true);
decMenuItem.setEnabled(true);
}
What is the problem here?
Thanks for helping!
It's because you're not actually checking whether the text is empty; you're checking whether it's null. There's a difference between a String that's empty and a String that's null.
You need to be checking
if ("".equals(textArea.getText())) ...
if you want to check whether it's empty.
(You might also want to check for null.)

java enable the second textfield if the first textfield is not empty

I have 2 textfields in my project. The first textfield is txtNumA and the second is txtNumB. I disabled txtNumB. When txtNumA is not empty, txtNumB will be enabled.
Well, this is part of code I've tried:
private void txtNumKeyTyped(java.awt.event.KeyEvent evt) {
if(!(txtNumA.getText().trim().equals(""))){
txtNumB.setEnabled(true);
}
else {
txtNumB.setText(null);
txtNumB.setEnabled(false);
}
}
Actually it works, but not perfect. It works only if I typed 2 or more characters in txtNumA. What I need is when I typed one character and more, txtNumB will be enabled.
What's wrong with my code?
What is happening here is,
In case of KeyTyped and KeyPressed events the input is not still given to the TextField.That's why it is not working and works after you type the second character and by that time first character must have reached the TextField.So use KeyReleased method to handle this case.
t is the first TextField and t1 is second.
t.addKeyListener(new KeyListener(){
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
JTextField bt = (JTextField)e.getSource();
if(bt.getText().trim().length()>0){
t1.setEnabled(true);
}
else
t1.setEnabled(false);
}
});
The correct way is to add a DocumentListener to the Document of your JTextField:
public final class TextFieldListener implements DocumentListener {
public static void main(final String... args) {
SwingUtilities.invokeLater(() -> new TextFieldListener().go());
}
private final JFrame frame = new JFrame();
private final JTextField field = new JTextField();
private final JTextField field2 = new JTextField();
private TextFieldListener() {
field.getDocument().addDocumentListener(this);
frame.setLayout(new GridLayout(2, 0));
frame.add(field);
frame.add(field2);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
onFieldUpdated();
}
private void go() {
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void onFieldUpdated() {
setField2Enabled(!field.getText().isEmpty());
}
private void setField2Enabled(final boolean enabled) {
field2.setEnabled(enabled);
}
#Override
public void insertUpdate(final DocumentEvent e) {
onFieldUpdated();
}
#Override
public void removeUpdate(final DocumentEvent e) {
onFieldUpdated();
}
#Override
public void changedUpdate(final DocumentEvent e) {}
}
It is not correct to add a KeyListener to your text field if you are interested in changes to its content.
Further reading:
JTextComponent
Document
Text Component Features
How to Use Text Fields
How to Write a Document Listener
I think the problem with this working for 2 characters is because getText() method returns not updated value, i.e. it returns the value BEFORE the change. What you need to do is somehow update that value before you compare it to empty string.
You may need to investigate KeyEvent to see if user adds another character or is it e.g. backspace...

DocumentListener Validation Error in MVC Application

I am making a swing MVC application , to know the intricacies of GUI design using the Swing Framework . My JDK Version is 7 and I have a simple application that contains a dialog having a textfield for storing the path to a file , a browse button , 2 textfields for user id and password and 2 buttons for Update and Cancel functionalities.
Clicking on these buttons simply shows a dialog with either Update or Cancel message on it.
I planned to use DocumentListener to validate the textfield components.
In the UI i have the following code to create the 2 textfields :
public JPasswordField getMyPasswordField() {
if(myPasswordField == null)
{
myPasswordField = new JPasswordField();
myPasswordField.setBounds(133, 93, 163, 21);
myPasswordField.getDocument().putProperty("Owner", "myPasswordField");
}
return myPasswordField;
}
public JTextField getMyUserNameField() {
if(myUserNameField== null)
{
myUserNameField = new JTextField();
myUserNameField.setBounds(133, 66, 163, 21);
myUserNameField.getDocument().putProperty("Owner", "myUserNameField");
}
return myUserNameField;
}
In the controller I used the following code :
myReferenceUI.getMyUserNameField().getDocument().addDocumentListener(this);
myReferenceUI.getMyPasswordField().getDocument().addDocumentListener(this);
And in the method implementation I wrote the following :
public void insertUpdate(DocumentEvent e) {
Object owner = e.getDocument().getProperty("Owner");
changed(owner);
}
#Override
public void removeUpdate(DocumentEvent e) {
Object owner =e.getDocument().getProperty("Owner");
changed(owner);
}
#Override
public void changedUpdate(DocumentEvent e) {
Object owner =e.getDocument().getProperty("Owner");
changed(owner);
}
public void changed(Object e)
{
System.out.println(e.toString());
if( e.toString().equals("myUserNameField"))
{
if(myReferenceUI.getMyUserNameField().getText().equals("") )
{
myReferenceUI.getMyUpdateButton().setEnabled(false);
return ;
}
}
if( e.toString().equals("myPasswordField"))
{
if(myReferenceUI.getMyPasswordField().getText().equals("") )
{
myReferenceUI.getMyUpdateButton().setEnabled(false);
return ;
}
}
myReferenceUI.getMyUpdateButton().setEnabled(true);
}
My intent was to enable the update button only if the 2 textboxes for username and password have non null values.
The listener events fire properly and the update button is disabled in case of null entry in the username / password fields.
But after entering any value in these fields , if i press backspace and erase the text , the update button remains disabled.
What can i do to get rid of this condition ?
Use a DocumentListener that is aware of both the documents that you want to follow. For example:
private static class PasswordValidator implements DocumentListener {
private final Document[] documents;
private final JComponent component;
PasswordValidator(JComponent component, Document... docs) {
this.component = component;
documents = docs;
for (Document doc : docs) {
doc.addDocumentListener(this);
}
validate();
}
#Override
public void insertUpdate(DocumentEvent e) {
validate();
}
#Override
public void removeUpdate(DocumentEvent e) {
if (e.getDocument().getLength() == 0) {
component.setEnabled(false);
}
}
#Override
public void changedUpdate(DocumentEvent e) {
// Attribute change - ignore
}
private void validate() {
for (Document doc : documents) {
if (doc.getLength() == 0) {
component.setEnabled(false);
return;
}
}
component.setEnabled(true);
}
}
That particular implementation would then be used something like:
new PasswordValidator(myReferenceUI.getMyUpdateButton(), myReferenceUI.getMyUserNameField().getDocument(), myReferenceUI.getMyPasswordField().getDocument());
I got around my troubles by attaching PropertyChangedListeners to both my username and password fields and the following bit of code :
public void setUpdateButtonState()
{
if((myReferenceUI.getMyUserNameField().getText().equalsIgnoreCase("")
|| String.valueOf(myReferenceUI.getMyPasswordField().getPassword())
.equalsIgnoreCase("") ))
{
myReferenceUI.getMyUpdateButton().setEnabled(false);
}
else
{
myReferenceUI.getMyUpdateButton().setEnabled(true);
}

Why is cancelCellEditing() not called when pressing escape while editing a JTable cell?

I have an editable JTable and have set a DefaultCellEditor like so:
colModel.getColumn( 1 ).setCellEditor( new DefaultCellEditor( txtEditBox ) {
// ...
#Override
public void cancelCellEditing() {
super.cancelCellEditing();
// handling the event
}
// ...
}
However, when pressing escape while editing a cell in this column, though the editing mode is finished, this method is not called. Any ideas why? Am I doing something wrong? Is there a way to handle this (other than manually adding a KeyListener that is)?
The official way: You can register a CellEditorListener: AbstractCellEditor.addCellEditorListener(...). If the editing is canceled, editingCanceled(ChangeEvent e) should be called. Due to a SUN bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6788481, editingCanceled is not called :(
As workaround you can register your own action for the ESCAPE key and handle it yourself. But it will not work for resize events.
Another solution (quick and dirty;-)): Overwrite the methode JTable.removeEditor() and insert your code after the super call.
I had this problem too. I wrote another workaround that involves ActionListener and FocusListener. This is it:
public class TableEditorListenerHelper {
// dealing with events
private final EventListenerList listeners = new EventListenerList();
private ChangeEvent changeEvent;
// cell editor that we're helping
private CellEditor editor;
// transient state
private boolean editing = false;
private JTable table;
public TableEditorListenerHelper(CellEditor editor, JTextField field) {
this.editor = editor;
field.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
});
field.addFocusListener(new FocusListener() {
#Override public void focusGained(FocusEvent e) {
editing = true;
}
#Override public void focusLost(FocusEvent e) {
JTable table = TableEditorListenerHelper.this.table;
if (editing && isEditing(table)) {
fireEditingCanceled();
}
}
private boolean isEditing(JTable table) { // a hack necessary to deal with focuslist vs table repaint
return table != null && table.isEditing();
}
});
}
public void setTable(JTable table) {
this.table = table;
}
public void addCellEditorListener(CellEditorListener l) {
listeners.add(CellEditorListener.class, l);
}
public void removeCellEditorListener(CellEditorListener l) {
listeners.remove(CellEditorListener.class, l);
}
public CellEditorListener[] getCellEditorListeners() {
return listeners.getListeners(CellEditorListener.class);
}
protected void fireEditingCanceled() {
for (CellEditorListener l : getCellEditorListeners()) {
l.editingCanceled(getOrCreateEvent());
}
resetEditingState();
}
protected void fireEditingStopped() {
for (CellEditorListener l : getCellEditorListeners()) {
l.editingStopped(getOrCreateEvent());
}
resetEditingState();
}
private void resetEditingState() {
table = null;
editing = false;
}
private ChangeEvent getOrCreateEvent() {
return changeEvent = changeEvent == null ? new ChangeEvent(editor) : changeEvent;
}
Here you can find a little more complete solution.
Another way fix this bug:
jTable.addPropertyChangeListener("tableCellEditor", e -> {
Object o = e.getOldValue();
if (o instanceof DefaultCellEditor) {
((DefaultCellEditor) o).cancelCellEditing();
}
});

How to make JTable cells default to overwrite mode

JTable cells by default are in append mode when the cell is double clicked on.
Is there a way to make the cell default to overwrite mode instead, IOW, select the contents of the cell so that if the user started typing the old text would be replaced by the new text without having to manually erase it?
You should be able to do this by creating your own TableCellEditor, which can be assigned to the parent table using setCellEditor(). This object is a factory that is called by the JTable whenever the user starts editing a cell, to create the field used to do the actual editing. You can return your own JTextField, and simply avoid setting the old value to achieve what your asking. You'll also have to attach a listener to the text field to update the value in the table when the user has finished typing.
You might find the Table Select All Editor helpful.
I have implemented the following method [addDeletePreviousOnEditBehavior] that works fine! Note that you need to use some TableCellEditor. To do so add the following code:
JTable table=new JTable();
JTextField field=new JTextField();
addDeletePreviousOnEditBehavior(field);
table.setCellEditor(new DefaultCellEditor(field));
The method is:
public static void addDeletePreviousOnEditBehavior(final JComponent field) {
field.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent fe) {
field.putClientProperty(DELETE_ON_EDIT, true);
}
#Override
public void focusLost(FocusEvent fe) {
}
});
field.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent ke) {
}
#Override
public void keyPressed(KeyEvent ke) {
if ((!(ke.isActionKey()
|| isSpecial(ke.getKeyCode())))
&& ((Boolean) field.getClientProperty(DELETE_ON_EDIT))) {
System.out.println("Key:" + ke.getKeyCode() + "/" + ke.getKeyChar());
field.putClientProperty(DELETE_ON_EDIT, false);
if (field instanceof JFormattedTextField) {
((JFormattedTextField) field).setValue(null);
}
if (field instanceof JTextComponent) {
((JTextComponent) field).setText(null);
}
}
}
#Override
public void keyReleased(KeyEvent ke) {
// do nothing
}
});
}

Categories

Resources