How can I enable a text field when a button is clicked? - java

before I start, I'm a beginner programmer.
How can I enable a text field when a button is clicked.
I have two frames, one that has the JFields and the other for the exception.
When the exception occurs > setEditable(false)
but what statement should I make to enable the JFields once the user click on okay button -that i've made in the exception-?
I've tried to add static boolean to exception frame, and inside the action performed of this class I initialized that boolean to true.
in the other class, I added an if statment, if that boolean is true, then setEditable(true)
-========-
The point of this program, that when the exception occurs the user cannot enter anything in the fields until he closes the exception window.
I wish you'd help me.
With all love, programmers.
The code of action performed for THE EXCEPTION WINDOW FRAME ( having Okay button. )
public void actionPerformed(ActionEvent e){
{
allow=true; //static boolean
Container TheFrame = OKButton.getParent();
do TheFrame = TheFrame.getParent();
while (!(TheFrame instanceof JFrame));
((JFrame) TheFrame).dispose();
}
The code of action performed for THE MAIN PROGRAM (having three fields, an exception will occur once the user enters non digits )
I added some comments to clarify.
public void actionPerformed(ActionEvent event) {
try{
r =Double.parseDouble(RField.getText());
s=Double.parseDouble(SField.getText());
h=Double.parseDouble(HField.getText());
Cone C = new Cone(r,s,h);//class cone
if (event.getSource() instanceof JButton) {
JButton clickedButton = (JButton) event.getSource();
if (clickedButton == VolumeButton) {
Result.append("VOLUME = "+C.volume()+ "\n");
ifV= true;//this's for clearing the fields for new entries.
}
if (clickedButton == AreaButton) {
Result.append("SURFACE AREA = "+C.surfaceArea()+ "\n");
ifA= true;//this's for clearing the fields for new entries.
}
if(ifA&&ifV){ // clearing the fields for new entries.
SField.setText(CLEAR);
HField.setText(CLEAR);
RField.setText(CLEAR);
ifV=false; ifA= false;}
}
SList.addShape(C);
}
catch(NumberFormatException e){
//Object of type "Exception__" already created
Ex.setVisible(true);//class "Exception__" is the one i've made for Exception window
SField.setText(CLEAR);
HField.setText(CLEAR);
RField.setText(CLEAR);
SField.setEditable(false);
HField.setEditable(false);
RField.setEditable(false);
}/*here, if the user clicked on -that okay in Exception window-
and variable allow initialized to "true" those statements should extend. I guess?
- everything worked correctly except for this ?*/
if(Ex.allow){
SField.setEditable(true);
HField.setEditable(true);
RField.setEditable(true); }
}
THANK YOU ALL IT FINALLY WORKED.
I added
Ex.allow(SField,HField,RField);
to the catch.
and added this method in class Exception__:
public void allow(JTextField js,JTextField jh,JTextField jr){
HField =jh;
SField =js;
RField =jr;
}
finally, to the action performed of class Exception__:
SField.setEditable(true);
HField.setEditable(true);
RField.setEditable(true);
WOHOOOO. It feels so awesome lol. Thanks all. should I delete my question or leave it for others who might face the same problem as mine? :P

Your question needs a lot more detail. But if all you want to to show an 'exception window' and allow the user to do anything else only after she dismisses this window, I think all you need is a MessageDialog:
See JOptionPane
If you need more details to be displayed you can create your own modal JDialog.
See How to Make Dialogs

Make the text field hiden by writing:
jTextfield.setVisible(fasle);
in the constructor of your form code. than use the button event " Action -> Action Performed " and write the code:
jTextfield.setVisible(true);
and thus your text field will be visible only after the button will be clicked.

Related

Java if two buttons have the same icons increase score and if not display "wrong match"

Creating a really basic Memory game using Java Swing. I created my GUI with a list of blank buttons where I set the icon property to none.
My code for some of the buttons is:
private void tbtnCard3ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card3Logo.png")));
if(tbtnCard5.isSelected()){
score++;
lblScore.setText(""+score);
}
}
private void tbtnCard4ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card7EWaste.png")));
if(tbtnCard7.isSelected()){
score++;
lblScore.setText(""+score);
}
}
private void tbtnCard5ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card3Logo.png")));
if(tbtnCard3.isSelected()){
score++;
lblScore.setText(""+score);
}
}
I have about 20 toggle buttons and for example the code above works and the scores go up by 1 when a match is found. So for tbtnCard3, if tbtnCard5 is selected the score goes up by 1. Now my question is how would I make it so that if tbtnCard3 is selected but tbtnCard 5 is not selected, display "Wrong Match". Since im using if Selected I'm not too sure how to display "wrong match" when the case is false. It doesn't make sense to say else ifSelected as no parameters can be put either....
In my opinion, the OPs suggestion is not a good approach. You do not want the listener of one button to be "aware" of some other component unnecessarily. Suppose you have an 8-by-8 grid with toggle buttons. You don't want each toggle button listener to be aware of the other 63 toggle buttons.
I believe there is a much simpler (and cleaner) approach. What you want is for the toggle button listener to register and deregister the toggle when the state of the button changes. Let say, you add the toggle button to or remove from a list (most likely a custom class) where you can trigger some logic when the list size reaches two. Then, depending on the outcome of the comparison, it will count a match (and disable these two toggle buttons in the current state), or will display some message like "Try again" and then toggle the buttons to hide the image.
In pseudocode, this will look something like this:
public class ToggleListener implements ItemListener {
public void actionPerformed (ItemEvent event) {
JToggleButton button = (JToggleButton) event.getSource();
if (event.getStateChange()==ItemEvent.SELECTED) {
// TODO Add the button to your list..
} else {
// remove button
}
}
}
In your Swing application, you can create a single instance of the above listener and add it to every single toggle button. And, as you can see, this listener is only responsible to register and unregister the component associated with the triggered event.
The "List Listener" on the other hand, is responsible to trigger the comparison logic when the size of the list reaches two. So, if you click on the same toggle button over and over again, the only thing the button listener will do is add or remove the button from the list depending on the button's current state. However, once a second button is toggled to reveal its image, the list listener will trigger the comparison logic. I am not 100% sure, but I think you could use JavaFX ObservableList interface or one of its implementing classes to do this. If the ListChangeListener.Change class is not suitable to figure out the size of the list to trigger the logic, you will have to implement this on your own. Regardless, in pseudocode, you need to do something like this:
public void onListChange(Event event) {
if (list.size() == 2 && btn1.getIconName().equals(btn2.getIconName())) {
displayMatchMessage();
btn1.setEnabled(false);
btn2.setEnabled(false);
list.clear(); // you should remove matched items from list manually
} else {
displayMismatchMessage();
btn1.setSelected(false); // flip the card
btn2.setSelected(false); // flip the card
// list.clear(); // you should not need this because the setSelected should trigger the Item Listener which should remove item from list.
}
}
Doing something like this is a much cleaner implementation where the button listener have a single job to do and the "list listener" has another job to do. Neither one encroaches on the other's job.

Java multiple message dialogs at the same time with focusLost event

The problem is that when i click on the surname field when the name field is empty both messages appear because the focus is lost even from surname when the message dialog appears. Is there anything i can do to make the program show the name message and the focus to stay on the name field?
I tried the .requestFocus() but it didn't work.
private void NameFieldFocusLost(java.awt.event.FocusEvent evt) {
if (NameField.getText().equals('smth')) {
JOptionPane.showMessageDialog(null, "Please put a name!","Error!", JOptionPane.INFORMATION_MESSAGE);
}
}
private void SurnameFieldFocusLost(java.awt.event.FocusEvent evt) {
if (SurnameField.getText().equals("smth")) {
JOptionPane.showMessageDialog(null, "Please put a surname!","Error!", JOptionPane.INFORMATION_MESSAGE);
}
}
First off, in the NameFieldFocusLost event: if (NameField.getText().equals('smth')) { doesn't fly. The equals() method requires a String: if (NameField.getText().equals("smth")) { or better yet...since you want to ensure a name is actually provided:
if (NameField.getText().trim().equals("")) {
There must be something we're not being shown. I don't understand why both MessageBoxes would be displaying when focus is taken away from the nameFieldFocusLost event. This shouldn't happen unless you have code somewhere moving focus around especially before your form is actually visible. The requestFocus() method should work as well and should be called directly after you display the MessageBox, for example:
private void nameFieldFocusLost(java.awt.event.FocusEvent evt) {
if (nameField.getText().trim().equals("")) {
JOptionPane.showMessageDialog(this, "Please put a name!","Error!", JOptionPane.INFORMATION_MESSAGE);
nameField.setText(""); // Clear the JTextField in case a white-space was placed there.
nameField.requestFocus(); // Force focus back onto the JTextField.
}
}
If you are moving focus to a JTextField before the parent container is visible (Form / JDialog) then you could possibly experience your particular problem.
EDIT:
Ahhh...I see the problem, thank you for the comment. Here are a few ways you can get around this dilemma:
Add a condition within the focusLost event for the next
JTextField to be in focus which will force an exit of that event
should the validation of the previously focused JTextField fail.
In your case you have a First Name text field and a Last Name text
field. In the focusLost event for the Last Name field you would have
the very first line of code being:
if (nameField.getText().trim().equals("")) { return; }
This way the remaining event code doesn't get run in the Surname
Lost Focus event unless validation for Name field is successful. The
entire Surname event code may look like this:
private void surnameFocusLost(java.awt.event.FocusEvent evt) {
if (nameField.getText().trim().equals("")) { return; }
if (surnameField.getText().trim().equals("")) {
JOptionPane.showMessageDialog(this, "Please put a last name!","Error!", JOptionPane.INFORMATION_MESSAGE);
surnameField.setText(""); // Clear the JTextField in case a white-space was placed there.
surnameField.requestFocus(); // Force focus back onto the JTextField.
}
}
An other way would be to utilize the InputVerifier
Class.
There is good example of its use in this SO
post.
Don't use the JTextField's Focus Events at all. If there is a button
that will be selected to further processing with the inputted data
then check the validation for all your JTextFields there (in the button's actionPerformed event) and force a
focus upon the field that fails (nameField.requestFocus();) for proper input.

How can I set visible to hide the jDialog (inside if condition) that is set visible shown (outside if loop)?

Here I want to open a DialogFrame containing an error message when a buttonGroup is not active & the search button is clicked. So inside the ActionEvent I have made the DialogFrame to setVisible(true). But when the button group is active & I click the search button (inside the if condition), the setVisible(false) doesn't seem to work, in other word the DialogFrame still pop ups!
How can I turn the visibility off of the DialogFrame inside the if condition?
private void jButtonSearchActionPerformed(java.awt.event.ActionEvent evt) {
SrchEMsg sem = new SrchEMsg(this);
sem.setVisible(true);
sem.setLocationRelativeTo(null);
sem.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
if (bgGroup.getSelection() != null) {
sem.setVisible(false); //doesn't work.
SrchResult sr = new SrchResult();
sr.setVisible(true);
sr.pack();
sr.setLocationRelativeTo(null);
sr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.dispose();
}
}
I would recommend not to manipulate the visibility but simply not to create sem at all if some condition is met:
if (bgGroup.getSelection() == null) {
// only handle `sem`
SrchEMsg sem = new SrchEMsg(this);
sem.setVisible(true);
sem.setLocationRelativeTo(null);
sem.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
} else {
// only handle `sr`
SrchResult sr = new SrchResult();
sr.setVisible(true);
sr.pack();
sr.setLocationRelativeTo(null);
sr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.dispose();
}
Keep it simple. Get rid of
sem.setVisible(true);
and instead simply do
sem.setVisible(bgGroup.getSelection() == null);
only set it visible if need be
If instead your wish to set the dialog invisible when the user makes a selection, then you can't do this in dialog creation code, but rather need to respond to the appropriate event, such as an ActionListener or ItemListener added to your JRadioButtons.

Making a program wait until a button is clicked

I have a problem that probably has a simple fix but I can't seem to get it to work.
I need my program to pause or wait until the user selects either the skip button, or the positive/negative feedback button, before moving on.
I assume this is going to require basic threading, but I'm not sure how to implement it. Any help will be appreacited.
The gui is displayed in a separate class(GUI) and the rest is another class.
The code is sort of messy as it was coded for a Hackfest in 12 hours.
EDIT: Solved it on my own by removing button listeneers and making the variables static.
public void onStatus(Status status) {
//this is a listener from the Twitter4J class. Every time new Tweet comes in it updates.
for (int i = 0; i <= posWords.length; i++) {
if (status.getText().toLowerCase().contains(gui.sCrit.getText())
&& (status.getText().toLowerCase().contains(posWords[i].toLowerCase()))) {
//If the tweet matches this criteria do the following:
String tweet;
Status tempStoreP;
System.out.println("Flagged positive because of " +posWords[i].toLowerCase()+" " + i);
tempStoreP = status;
tweet = tempStoreP.getUser().getName() + ":" + tempStoreP.getText() + " | Flagged as positive \n\r";
gui.cTweet.setText(tweet);
//Write to log
try {
wPLog.append("~" + tweet);
} catch (IOException e) {
}
//Add action listeneer to gTweet.
//here is my problem. I want it to wait until a user has clicked one of these buttons before moving on and getting the next Tweet. It has to pause the thread until a button is clicked then it can only move on to getting another Tweet.
//the problem is that the button listener uses local variables to work.
gui.gTweet.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (gui.pTweet.getText().equalsIgnoreCase("")) {
gui.pTweet.setText("Please type a response");
} else if (gui.pTweet.getText().equalsIgnoreCase("Please type a response")) {
gui.pTweet.setText("Please type a response");
} else {
try {
Status sendPTweet = twitter
.updateStatus("#" + tempStoreP.getUser().getScreenName() + " "
+ gui.pTweet.getText());
} catch (TwitterException e1) {
}
}
gui.gTweet.removeActionListener(this);
}
});
//add Aaction listert to sTweet
gui.sTweet.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
wPLog.append("Skipped \n\r");
} catch (IOException e1) {
}
gui.sTweet.removeActionListener(this);
}
});
}
Thank you for any help. On a side note, if anyone can tell me why when the button is clicked, it loops and spams people with the same message, it will be helpful. Thank you.
I thought about the multithreading thing and i think it isn't easy enough.
If i were you i would disable all controls except the button that is to click.
Example:
JButton button = new JButton( "Test );
button.setEnabled( false );
The user won't be able to click the button until you use button.setEnabled( true );, if you just disable all controls but the button that should be fine.
In my understand of your problem you can use Multithreading like this:
try{
while(!isSkipClicked){
//your multithreading code
}
//code to move...
}
or
you can use dispose method if you have 2 JFrame.
or
you can use multiple JPanel like while skip button clicked hide pnl1 and show pnl2 using method
pnl1.setvisible(false);
pbl2.setVisible(true);
I assume this is going to require basic threading,
Not true at all.
You say you want your program to "wait." That word doesn't actually mean much to a Swing application. A Swing application is event driven. That is to say, your program mostly consists of event handlers that are called by Swing's top-level loop (a.k.a., the Event Dispatch Thread or EDT) in response to various things happening such as mouse clicks, keyboard events, timers, ...
In an event driven program, "Wait until X" mostly means to disable something, and then re-enable it in the X handler.
Of course, Swing programs sometimes create other threads to handle input from sources that the GUI framework does not know about and, to perform "background" calculations. In that case, "Wait until X" might mean to signal some thread to pause, and then signal it to continue its work in the X handler.

Problems with KeyEvent

I have a panel just with a Jtextfield that only accept numbers. So, when I press enter will load a user profile. this is just to see his profile.
What I want: When I press ENTER again all the profile will be cleared, and when I press the numbers and press ENTER again and load the profile again and again...
My problem: I pressed enter and the profile is cleared (Ok all fine), but when I enter the number and press the ENTER, The numbers are cleared and nothing happens, it is like a loop in matriculaTxt.addKeyListener(new KeyAdapter() { ... }
Sorry for my bad English.
private void matriculaTxtActionPerformed(java.awt.event.ActionEvent evt)
{
String matricula = matriculaTxt.getText().trim();
if (!matricula.matches("[0-9]+")) {
matriculaTxt.setText("");
} else {
fc = new FrequenciaController();
matriculaTxt.setEditable(false);
matriculaTxt.requestFocus();
fc.checkinManual(Integer.parseInt(matricula));
}
// the problem is here.
matriculaTxt.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
nomeTxt.setText("");
statusTxt.setText("");
imageLb.setIcon(null);
acessoLabel.setText("");
matriculaTxt.setText("");
observacaoTxt.setText("");
System.err.println("ENTER");
PendenciasTableModel ptm = new PendenciasTableModel();// vazio
pendenciasTabela.setModel(ptm);
matriculaTxt.setEditable(true);
matriculaTxt.requestFocus();
}
}
});
}
What I wanted to do was simple. The user types in the text field their numbers, pressing ENTER: their data are loaded. requestFocus() into the text field and it will not be editable anymore, because when I press Enter again the field will be editable but everything will be deleted, and so on.
First off, you should never use a KeyListener for this sort of thing. Consider instead using either a JFormattedTextField or using a DocumentFilter to prevent non-numeric entry. Next, you should use an ActionLIstener to have the JTextField accept and react to the user's pressing the Enter key.
Edit
You state:
my exact requirements is, when i press ENTER again all data will be cleaned for a new data be inserted.
Why not simply have in your JTextField's ActionLIstener:
#Override
public void actionPerformed(ActionEvent e) {
// get the text
JTextComponent textComp = (JTextComponent) e.getSource();
String text = textComp.getText();
// do what you want with text here
// clear the text
textComp.setText("");
}
Again, you should not use a KeyListener for any of this stuff.
Edit 2
If you want a multi-state action listener, one that reacts differently depending on the state of the program, then give it some if blocks to allow it to react to the state of the JTextField. If the field is empty, do one thing, if it has numbers, do another, if it has text, show a warning and clear it:
#Override
public void actionPerformed(ActionEvent e) {
// get the text
JTextComponent textComp = (JTextComponent) e.getSource();
String text = textComp.getText().trim(); // trim it to rid it of white space
if (text.isEmpty()) {
// code to show a profile
return; // to exit this method
}
// if we're here, the field is not empty
if (!text.matches("[0-9]+")) {
// show a warning message here
} else {
// numeric only data present
// do action for this state
}
// clear the text
textComp.setText("");
}
The key again is to not use a KeyListener, but rather to "listen" for the enter key press with the ActionListener only, but to react differently depending on the state of the program, here likely being depending on what content is present in the JTextField.
I think that your problem that the KeyListener it'll not trigger, it will not execute the code inside it, because whenever you press ENTER it will trigger the matriculaTxtActionPerformed then declared the KeyLister, so the ENTER will effect it.

Categories

Resources