Solved

Preventing a JButton from being clicked

Posted on 2004-04-26
21
505 Views
Last Modified: 2007-12-19
I have an application where I have to validate different fields. Before a field may lose the focus, the validation has to be performed and if it fails the field may not lose the focus. My problem is that whenever I have buttons on the form as well, these buttons can be clicked even though the validation failed and the button should not receive an actionEvent.
Is there a way to stop the button from receiving an actionPerformed event in the cases where the validation fails and the focus is not allowed to leave the edit field?
0
Comment
Question by:Calron
  • 9
  • 5
  • 4
  • +1
21 Comments
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
button.setEnabled(false);
0
 
LVL 5

Author Comment

by:Calron
Comment Utility
No, that will not work, take the case where the field validate correctly then the button has to be available to be pressed. The second thing is the visuals, I can't have all components painted gray while validating the component and once the validation is done enable all of them again ....

I'll specifiy more in detail what has to happen on the UI's that I am setting up.

every component that can receive the focus has three events:
boolean requestEnter()
boolean validate()
boolean requestExit()

Before a component is allowed to receive the focus the requestEnter event has to be called. If it returns true, the component may receive the focus. Before losing the focus, validate is called and if that is true, requestExit is called. If both of these return true then the component can lose the focus and the next component is focused.

Disabling components will not work, because they will not be available in the focus chain to receive the focus once the validate and requestEnter both returned true.
0
 
LVL 37

Expert Comment

by:zzynx
Comment Utility
>> Is there a way to stop the button from receiving an actionPerformed event
Isn't it enough to - if actionPerformed() is triggered in that specific case - just return
without performing the instructions you should normally perform in actionPerformed()?
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
>>No, that will not work, take the case where the field validate correctly then the button has to be available to be pressed.

Why not?

boolean fieldWasValid = ..... // (do the validation)
button.setEnabled(fieldWasValid);
0
 
LVL 5

Author Comment

by:Calron
Comment Utility
The proble is that I have to set up a system that will handle a whole range of UI's. I have no control over what the other programmers later add into their actionPerformed events.  They are just expecting the events that I described above, and if the actionPerformed is called, they of course expect that the validation and the other events executed correctly. (even the button can have a requestEnter event :(  )
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
See my last comment.

>>I can't have all components painted gray while validating the component and once the validation is done enable all of them again

That's not necessary.

a. Only the button that you need to disable needs to be affected
b. It only gets disabled (grayed out) if the validation fails and not otherwise
0
 
LVL 5

Author Comment

by:Calron
Comment Utility
>>  a. Only the button that you need to disable needs to be affected

I have no idea which button will be pressed, since any range of UI's have to work with this system I have no idea how many buttons are on that UI without actually getting all components and filtering out the buttons. Also I would have to filter out all JComboBoxes too, since if a field validation fails I can't allow a user to choose a new setting in a COmbobox either, etc.

>>  b. It only gets disabled (grayed out) if the validation fails and not otherwise

once again impractical. It may work disabling all the buttons if a validation fails, but what if the user then corrects the mistake and attempts to leave the field?I then have to go and enable all the buttons and everything else that should not have been activated.
0
 
LVL 86

Accepted Solution

by:
CEHJ earned 350 total points
Comment Utility
You can use the pane layering of the container. For instance you could use the glass pane to intercept events. Examples at http://java.sun.com/docs/books/tutorial/uiswing/components/rootpane.html
0
 
LVL 37

Expert Comment

by:zzynx
Comment Utility
Read my comment?

What about the idea:

boolean b = myButton.validate()

public void actionPerformed( ... ) {
    if (!b) return;

    // Perform the other stuff
}
0
 
LVL 5

Author Comment

by:Calron
Comment Utility
zzynx: yes, I read your comment, and no, that is not an option, since I have to set up a system that other programmers will use and thus I can't interfere with the code that they put into their actionPerformed staements .....

CEHJ: I'll look into that. I have not heard about pane layering. I'll post again when I tried it out.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 37

Assisted Solution

by:zzynx
zzynx earned 50 total points
Comment Utility
>>For instance you could use the glass pane to intercept events
Right indeed.
Performing

                       MouseAdapter myAdapter = new MouseAdapter() {};
                       addMouseListener( myAdapter );

on the glasspane avoids all mousevents to be "seen"/captured.

Performing

                      removeMouseListener(myAdapter);

restores the original situation
0
 
LVL 5

Author Comment

by:Calron
Comment Utility
The glasspane is certainly looking good. I will run some more tests tomorrow and get back to you. Thanks
0
 
LVL 86

Expert Comment

by:CEHJ
Comment Utility
OK
0
 
LVL 92

Assisted Solution

by:objects
objects earned 100 total points
Comment Utility
the glasspane won't intercept actionevents.
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
How do you know which fields need to be valid for a button to be enabled?
0
 
LVL 5

Author Comment

by:Calron
Comment Utility
>> the glasspane won't intercept actionevents.

I saw that too, so the only way to work using glasspanels would be trapping the keyboard events and the mouse click events :(  not really a nice thing.

>>  How do you know which fields need to be valid for a button to be enabled?

As I described above. a component, lets say a textfield, has the focus, the suer is entering something and then leaves the field either through keyboardnavigation or through mouse navigation (clicking somewhere else). The framework I have to set up then has to call validate() on the textfield and if that method returns true, call requestExit() and if that is true the focus change and whatever activity the change effected can be executed.


I have had a version that seemed to work more or less. I solved it by subclassing all the relevant J... component classes and having our own look and feel. Both of these things were not only done because of this framework.
Whenever a button would receive a click event, I would trap it in the OurButtonUI class and set a flag. If the button then received the focus I would check that flag and if something was set, I would trigger actionPerformed. I did have one problem with this, one is that non-focusable buttons are never triggered (these are now requested for things like tool panels) and if a programmer used a normal JButton by mistake, it has to be clicked twice to be triggered.

That's the reason I am looking for better, i.e.. simpler ways to solve this
0
 
LVL 5

Author Comment

by:Calron
Comment Utility
Using the glasspane to capture the events will probably work. I does add quite a lot of overhead to the whole thing though .... but then again, who said that life was easy :)

Seriously, I am currently trying to set up this system on a small scale to see if I can get the glasspane event trapping idea to work with what I have to set up. It does take a bit of time though....
0
 
LVL 92

Expert Comment

by:objects
Comment Utility
Have u tried using FocusListeners?
0
 
LVL 5

Author Comment

by:Calron
Comment Utility
Yes, what I did in a first version is overreide the addFocusListener() method on all our UI components.In the constructor I would then add a listener to a manager class that did the whole controlling of this event stuff. There I would check the what component would get the focus fire the events and then depending on the results of the events I owuld then fire the focusListeners that the programmers themselves added to the components.
The problem with this solution was the following:

Let's say that the focus is on textfield a, textfield b would be the next to receive the focus but is currently disabled. Leaving textfield a with tab, prompts my manager class and I see that textfield a has lost the focus and the focus went to textfield c. But, in the validate() call of textfield a, textfield b is enabled. This menas that textfield b should be getting the focus and not really textfield c. To solve that I used an internal list of components to determine which component would be the next component to receive the focus and send the focus to that field if possible (the event requestEnter() returned true).
The problem with solving it this way is that in some cases the FocusTraversalPolicy had a different component order than I had in my internal list and that definitely screwed up the whole thing.

What I am looking at now is creating my own KeyboardFocusManager where I handle this passing back and forth of the focus and calling the events. But of course I still have the problem with the buttons ....  that's why I posted here to see what possibilities there are to solve something like this, since I would like to ditch the version I described above with setting a flag on the button ....
0
 
LVL 5

Author Comment

by:Calron
Comment Utility
In the end I found a way to solve this without using glasspanes (passing on the intercepted events to their specific targets would be more of a pain than it's worth). What I am doing now is in my subclass of JAButton, I overwrite the addActionListener method and hook up the actionListeners to a separate class. Now I can handle the actionevents in an internal class and only pass on the valid action events.

Thanks all for your input.
I'll be splitting the points between the three of you.
0
 
LVL 37

Expert Comment

by:zzynx
Comment Utility
Glad you found a solution at last.
Illustration of "In coding everything is possible."
;°)

Thanks for accepting.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now