How to iterate through all components of a panel except one - java

I have a question about java / swing.
I have build an input form with some JTextFields and JComboBoxes.
And I have two Buttons. Save and Abort.
If you click Save, I check all fields for inputs. So if you miss one field an error appears.
Which works fine.
On Abort I want two cases. First case is, if something in the field is changed a JOptionPane appears with the question "Do you really want to close? Data loss blabla".
But if no inputs are made, it should just close without this message.
To check if something is changed I have this:
private boolean isFormularChanged() {
boolean isChanged = false;
for (Component c : WeinDatenPanel.getComponents()){
if (!isChanged && c instanceof JTextField) {
isChanged = !((JTextField) c).getText().isEmpty();
} else if (!isChanged && c instanceof JComboBox) {
isChanged = isComboBoxChanged;
}
}
return isChanged;
}
The problem is, that my first JTextField has a MaskFormatter and Placeholders. So the .getText().isEmpty() doesnt work for this field. And isChanged is always true because of this.
Can I somehow iterate trough all the fields without my MaskFormatter field?
An ugly solution would be to do this by hand and check all my fields by hand execpt my first one. But maybe theres another, cleaner solution?

Related

Android Studio If statement with || and && operator

I'm creating an application which updates users on the score of a football match either in real time or as a final result. At least one score must be inputted in order for the TextView to be updated and the relevant score to be displayed. I'm checking that at least 1 of a pair of EditText fields is not empty using the following code:
if(!(et_current.getText().toString().isEmpty())||(!(et_final.getText().toString().isEmpty()))
&& (!(et_current2.getText().toString().isEmpty())||(!(et_final2.getText().toString().isEmpty()))){
if(!(et_final.getText().toString().isEmpty()))
tv_final.setText(et_final.getText().toString());
else
tv_current.setText(et_current.getText().toString());
if(!(et_final2.getText().toString().isEmpty()))
tv_final2.setText(et_final2.getText().toString());
else
tv_current2.setText(et_current2.getText().toString());
}
I want to be able to set the correct TextView so I have another if statement inside the original if statement to see ensure the correct score is being updated.
When I run the code, I do not seem to be getting past the first if statement. Am I using the correct format or is there an better way to complete these checks?
Thanks!
For readabilities sake, get some variables going
boolean currentEmpty = et_current.getText().toString().isEmpty();
boolean current2Empty = et_current2.getText().toString().isEmpty();
boolean finalEmpty = et_final.getText().toString().isEmpty();
boolean final2Empty = et_final2.getText().toString().isEmpty();
And then your code can be much cleaner. Something like
if( (!currentEmpty || !finalEmpty) || (!current2Empty || !final2Empty)) {
if(finalEmpty) {
tv_current.setText(et_current.getText());
}
else {
tv_final.setText(et_final.getText());
}
if(final2Empty) {
tv_current2.setText(et_current2.getText());
}
else {
tv_final2.setText(et_final2.getText());
}
}
I'm not sure if that is completely correct as the requirement is not entirely clear to me, but it should atleast be a good start to follow what's going on.

TicTacToe win conditions problems

New programmer here, writing a Tictactoe game using Java on Eclipse.
I have problems with my win conditions I think. It comes up with the error:
Exception in thread "main" java.lang.NullPointerException
at Game.NoughtsCrosses.(NoughtsCrosses.java:106)
at Game.Main.main(Main.java:5)
Here is my win conditions bit. It's not well made imo, but I'm having problems when compiling. Can anyone spot why? Ty!!
I have squares set up in a 3x3 grid, 0 -> 8. Each button has its own text which is set to X or O when clicked by each player.
winconditions code:
if (square[0].getText().equals(square[1].getText()) && square[1].getText().equals(square[2].getText()) != square[0].getText().isEmpty()) {
win = true;
}
Full Pastebin of code
Thanks again :) Any questions, I can elaborate :D
It looks like one of the squares text is null. One thing that is important to remember is that an empty string is not the same thing as null. In java, if you haven't specifically assigned a value to a String then it will be null. To fix this, you will want to explicitly set each squares text to "" (an empty string) when you set up your game board.
Well I took the code that you provided and after significant finagling was able to make a fully functioning Tic-Tac-Toe game. You were mostly on the right track with what you were doing you just needed to first begin with a design.
In my NoughtsCrosses class I have the following:
class Action implements ActionListener
This has a JButton attribute that I pass in through a constructor
In the actionPerformed
set the text
disable the button
increment the counter
check if someone wins
If there is a winner or draw game ends set the "Play again?" text
else call the changeTurn function
class Reset implements ActionListenter
This has a JButton attribute that I pass in through a constructor
In the actionPerformed
I call the resetGame function
function changeTurn
function resetGame
function checkForWinners
as a hint, this is my implementation of the Action class and an example of the constructor I mentioned
class Action implements ActionListener{
private JButton button;
public Action(JButton button){
this.button = button;
}
public void actionPerformed(ActionEvent e) {
button.setText(letter);
button.setEnabled(false);
counter++;
boolean gameOver = checkForWinners();
if(!gameOver)
changeTurn();
else{
newgame.setText("Play again?");
newgame.addActionListener(resetButton);
}
}
}
a call like new Action(square[i]) is what you need to make this work.
Note: the resetButton is of the Reset class I mention above much like the Action class it has the same construct that I passed newgame into.
It seems like your win-condition check is not within your actionPerformed code, but on the class level, hence it is possibly called before the window is populated with your buttons.
Try placing the check inside the actionPerformed like this: http://pastebin.com/xRViSUzy
What is the scope (most simply, which curly braces) is the problematic line inside of?
It was a bit tricky to tell based on your indentation, but it appears to me that your "if" was not inside a method (e.g. the constructor). I would guess that you intended this line and the ones around them to be executed after the lines in the body of your constructor where the squares are initialized. Instead, these lines are being run beforehand and therefore the call to "new" haven't been run yet.
I think that if you do some restructuring to move these conditions into your constructor or into another method that you call after construction then things will look a lot better.
Hope that helps.
If you're going to implement this type of solution, then simplify the job for yourself. Based on the tiny snippet of code I see above, it looks like you're really over-complicating the job you have to do.
char cell0 = //get that char, be it X or O
char cell1 = //
...
char cell8 = //
Now you can compare cells one by one to determine a victory. Your board game is set up as follows:
0 1 2
3 4 5
6 7 8
So you can just go in order:
Horizontal Solutions:
(cell0 == cell1 && cell0 == cell2)
(cell3 == cell4 && cell3 == cell5)
(cell6 == cell7 && cell6 == cell8)
Vertical Solutions
(cell0 == cell3 && cell0 == cell6)
//And so on
Cross Solutions:
(cell0 == cell4 && cell0 == cell8)
(cell2 == cell4 && cell2 == cell6)
This will check for your victory conditon.
The problem is that you have a surplus of braces in your code so that the statements in the question actually appear in an instance initializer block of the class NoughtsCrosses but none of the JButton components have been initialized yet as instance initializers are invoked before constructors which is where the JButton instantiated exist (but never called). When you attempt to invoke getText on the first element of the array square, a
NullPointerException is thrown.
To fix remove the additional braces to that the code is enclosed in the preceding ActionListener
class Action implements ActionListener {
public void actionPerformed(ActionEvent e) {
// existing code here
/// } remove
//} remove
// { remove
// win conditions. if true, set win==true; else set win
// here is where the compilation error is, next line
if (square[0].getText() == square[1].getText() ...) {
win = true;
} //etc
} <-- add this

How to get the blank jtextfield?

I am building a calculator (gas law calculator) which has four text fields, and I need three fields to be filled by numbers to calculate the fourth value. The equation is v1/p1 = v2/p2. But the problem is I don't know which three values the user will fill. So I need to find an algorithm to check each text field and determine which is empty. I am using swing classes. Jut give me direction.
Thank you!
DocumentListener
to try to avoiding KeyListener
possible way could be FocusListener also, notice Focus is asynchronous
Well, what do you expect the value of the "empty" field to be?
Of course it will be the empty string, "".
So just test for which fields contents equal the empty string (or have a length of 0).
How about this?
private boolean validateField(JComponent component)
{
if (component.getText().trim().length() == 0){
return false;
}
else{
return true;
}
}
If you want to check if JTextField is empty you just do it as follows:
Example(sudo code):
-> JTextField field = new JTextField("v1:");
-> if(field.getText().isEmpty == true){...}
else{...}

Using Boolean True/False with JOptionPane.YES_NO_OPTION

I have a series of four yes/no choices in four separate dialog boxes, the cumulative results of which will lead to one of twelve separate links (e.g., Yes/Yes/Yes/No -> link A, Yes/No/No/Yes -> link B, etc). The branching logic uses boolean values.
Here's what I have so far...just the first dialog box and printing the results for validation.
public class OutageGuideSelector{
public static void main(String[] args){
boolean contactServerUp;
boolean vistaUp;
boolean stormOutage;
boolean vistaCSUp;
//
int contactServerEntry = JOptionPane.showConfirmDialog(null,
"Is the contact server up", "Please select",
JOptionPane.YES_NO_OPTION);
System.out.println("result from entry " + contactServerEntry);
if(contactServerEntry==1)
contactServerUp = true;
else
if(contactServerEntry==0)
contactServerUp = false;
/* System.out.println(contactServerUp); */
}}
Right now, the results of clicking YES reults in a 0 being returned, NO results in a 1. Is this normal, seems counterintuitive, and there's nothing at docs.oracle.java that shows a clear example of the output values except this which seems to suggest that the public static final int YES_NO_OPTION default in 0.
Additionally, the line System.out.println(contactServerUp); comes back with an error that the field contactServerUp might not have been initialized when I un-comment it, so I can't see if my convert-int-to-boolean is working.
First: It appears that JOptionPane method does not include any boolean returns...except getWantsInput() which returns the value of the wantsInput property...so I assume I'm already being the most efficient I can with this. I'd like to know if there's an easier way.
Second, what am I missing that prevents my console output statement from recognizing the contactServerUp? Where's my misplaced semicolon?
According to the javadoc, when one of the showXxxDialog methods returns an integer, the possible values are:
YES_OPTION
NO_OPTION
CANCEL_OPTION
OK_OPTION
CLOSED_OPTION
You should test against those constants:
contactServerUp = (contactServerEntry == JOptionPane.YES_OPTION);
The value returned by the the JOptionPane dialogs are values defined as constant fields in the class.
Although, indeed, one could assume that 0 means false and 1 means true, the values are more ids for the different buttons a dialog can have.
To know if the user pressed yes or no, you can compare the return value to the constant fields described here. For example, in your case :
contactServerUp = (contactServerEntry == JOptionPane.YES_OPTION);
Since a dialog a JOptionPane can have more than two possible 'answers' a boolean would be a poor representation. You are forgetting about the YES, NO and CANCEL option, or what about just a OK answer.
If it would have been written today, I suspect a Enum would have been used instead of an int.
As for the second question, the compiler does not allow access to uninitialized variables.
When you do the following, there is a chance that the variable might not be initialized:
if(contactServerEntry==1)
contactServerUp = true;
else
if(contactServerEntry==0)
contactServerUp = false;
What if, for example, contactServerEntry == JOptionPane.CLOSED_OPTION? In that case, your boolean value is never initialized.
You need to add an else clause at the end of your if-else chain, or initialize contactServerUp value to a default value in the beginning.

Get boolean from a JTextField

I am trying to take the values from the text fields below to use with parent.addNewRoom(roomNo,roomEnSuite); but roomEnSuite is a Boolean value in the parent class. What is the correct procedure to get a Boolean from a JTextField?
public void actionPerformed( ActionEvent ae)
{
String item = ae.getActionCommand();
if ( item.equals("Confirm"))
{
String roomNo = nameJTextField.getText();
String roomEnSuiteS = idJTextField.getText();
parent.addNewRoom(roomNo,roomEnSuite);
this.dispose();
}
else if ( item.equals("Cancel"))
{
parent.resetButtons();
this.dispose();
}
}
To give a full answer from my above comments:
Handling boolean input using a JTextField would not be a good way to go about things as there are many variations the user could type yes/no/true/false, etc. mispelling?
Using a JRadioButton (for single answers) or JCheckbox (for multiple answers) would be a better way to go about handling true or false input. I would suggest a JRadioButton as you wouldn't want the user checking true and false.
http://docs.oracle.com/javase/tutorial/uiswing/components/button.html
Assuming the user entered the string true or false, you can turn it into a boolean with:
boolean value = Boolean.parseBoolean(idJTextField.getText());
A JTextField is meant to provide Strings. So unless you want the user to type true or false in the textfield (or whatever string you will parse to a boolean), there are better options available
a JCheckBox, which is typically used for toggle settings, like true-false
JRadioButtons (one for each setting, so two in this case)
And here a link to the corresponding Swing tutorial with examples on how to use these buttons
But if you really want to got with a textfield, then you should get the text from it and parse it by using for example Boolean.valueOf
As long as the value entered is always going to be true or false you can get a Boolean using;
boolean value = Boolean.parseBoolean(enSuiteJTextField.getText());

Categories