Hi I am trying to add a sort of option window to my application using JOptionPane. If you click yes, a boolean is true. If you click no, a boolean is false and if you click the last button, I want another boolean to say false. And whenever that last button is clicked, I want that window to never be popped up again.
This is my code at the moment.
if (Configuration.LOGIN_MUSIC) {
Object[] options = {"Yes",
"No",
"No, don't ask me again!"};
int n = JOptionPane.showOptionDialog(null,
"Would you like to play the login music?",
"Login music",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[2]);
if (n == 0) {
Configuration.LOGIN_MUSIC = true;
} else if (n == 1){
Configuration.LOGIN_MUSIC = false;
} else {
Configuration.LOGIN_MUSIC_NEVER = true;
Configuration.LOGIN_MUSIC = false;
System.out.println("cancel");
System.out.println(Configuration.LOGIN_MUSIC_NEVER);
}
}
}
public static void main(String args[]) {
try {
if (Configuration.LOGIN_MUSIC_NEVER == false) {
checkForLoginMusic();
}
//System.out.println("The login music has been " + (Configuration.LOGIN_MUSIC ? "enabled" : "disabled"));
nodeID = 10;
portOff = 0;
setHighMem();
signlink.startpriv(InetAddress.getLocalHost());
clientSize = 0;
instance = new Client();
instance.createClientFrame(clientWidth, clientHeight);
//instance = new Jframe(args, clientWidth, clientHeight, false); uncomment if i want to add back the menu bar at top
} catch (Exception exception) {
}
}
Related
I am creating a matching card application. That only allows the user to select two cards per round.
Where you see the bricks are where the buttons are and so i have added them to an arraylist, but im not sure how to make it so that they can only press 2 buttons until they press the guess button where it checks if they are a match.
https://pastebin.com/65NqJ0GK
private void card1ButtonActionPerformed(java.awt.event.ActionEvent evt) {
String temp = cards.get(0);
if (temp.equals("0")) {
card1Button.setIcon(a);
} else if (temp.equals("1")) {
card1Button.setIcon(b);
} else if (temp.equals("2")) {
card1Button.setIcon(c);
} else if (temp.equals("3")) {
card1Button.setIcon(d);
} else if (temp.equals("4")) {
card1Button.setIcon(e);
} else if (temp.equals("5")) {
card1Button.setIcon(f);
} else if (temp.equals("6")) {
card1Button.setIcon(g);
} else if (temp.equals("7")) {
card1Button.setIcon(h);
}
count++;
if (count == 1) {
c1 = Integer.parseInt(temp);
change[0] = 0;
} else if (count == 2) {
c2 = Integer.parseInt(temp);
change[0] = 0;
}
}
^^Here is an example of a button code.
Could someone show me some way to do it.
I've found this ugly piece of code from some time ago:
#FXML
private void buttSellAction(ActionEvent event){
InfoTip infoTip = new InfoTip();
if(comboPizza.getValue() != null){
if(comboPizzaSize.getValue() != null){
PizzaData selectedPizza = getPizzaData(comboPizza.getValue());
PizzaSizeData selectedPizzaSize = getPizzaSizeData(comboPizzaSize.getValue());
Date date = new Date();
Timestamp timestamp = new Timestamp(date.getTime());
if( selectedPizza != null ){
if(groupDelivery.getSelectedToggle().equals(radioNo)){ // sale without delivery
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirm");
alert.setHeaderText("Total cost: " + String.format("%.2f", selectedPizza.getPrice() + selectedPizzaSize.getPrice()));
alert.setContentText("Proceed with sale?");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK){
insertSale(timestamp, currentUser.getLogin(), selectedPizza.getID(),
selectedPizzaSize.getSize(), false, selectedPizza.getPrice() + selectedPizzaSize.getPrice());
infoTip.getInfoTip().setId("greenInfoTip");
infoTip.showTip((Button)event.getSource(), " Saved ");
}
}else{ //Sale with delivery
String adress = textFAdress.getText();
String clientName = textFClientName.getText();
String telephone = textFTelephone.getText();
String deliveryCost = textFCost.getText();
boolean isAdressOK = ((adress.length() < 51) && (adress.isEmpty() == false))? true: false;
boolean isClientNameOK = (clientName.length() < 36)? true: false;
boolean isTelephoneOK = ((telephone.length() < 21) && (telephone.isEmpty() == false))? true: false;
boolean isCostOK;
try{ Double.valueOf(deliveryCost); isCostOK = true; }
catch(NumberFormatException exception){ isCostOK = false; }
if(isAdressOK == true){
if(isClientNameOK == true){
if(isTelephoneOK == true){
if(isCostOK == true){
double totalCost = selectedPizza.getPrice() + selectedPizzaSize.getPrice() + Double.valueOf(deliveryCost);
//everything is okey
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirm");
alert.setHeaderText("Total cost: " + totalCost);
alert.setContentText("Proceed with sale?");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK){
int id = insertSale(timestamp, currentUser.getLogin(), selectedPizza.getID(),
selectedPizzaSize.getSize(), true, selectedPizza.getPrice() + selectedPizzaSize.getPrice());
insertDelivery(id, adress, clientName, telephone, Double.valueOf(deliveryCost));
infoTip.getInfoTip().setId("greenInfoTip");
infoTip.showTip((Button)event.getSource(), " Saved ");
} else {
// ... user chose CANCEL or closed the dialog
}
}else{ //cost not ok
infoTip.showTip(textFCost, "keep right format e.g. 4.35");
}
}else{ //telephone not ok
infoTip.showTip(textFTelephone, "max 20 characters, not empty");
}
}else{ //client name not ok
infoTip.showTip(textFClientName, "max 35 characters");
}
}else{ //adress not ok
infoTip.showTip(textFAdress, "max 50 characters, not empty");
}
}
}else{ //couldnt found selected pizza in pizzaList(which should not be possible)
ExceptionDialog exceptionDialog = new ExceptionDialog("Error when searching for selected pizza", new Exception());
exceptionDialog.showAndWait();
}
}else{ //pizza size not choosen
infoTip.showTip(comboPizzaSize, "select pizza size");
}
}else{ //pizza not choosen
infoTip.showTip(comboPizza, "select pizza");
}
}
I know now it has few major flaws:
method is doing too much and its too long,
it has too many conditional statements so it is easy to get lost,
unnecessary comments making code less readable.
repeated code,
possibly mixed levels of complexity.
testing it would be horrible.
something else??
How can I refactor it to make it clean and simple?
I'd take a slightly different approach to the other answer. I'd separate the validation from the other logic in the method. This means that you don't have to read lots of if statements to see the core logic of the method and if you want to change the validation you only need to update one statement in one place. eg for the first section, add a private method:
private PizzaSizeData getAndVerifySelectedPizza() {
if (comboPizza.getValue() == null) {
infoTip.showTip(comboPizza, "select pizza");
return null;
}
if (comboPizzaSize.getValue() == null) {
infoTip.showTip(comboPizzaSize, "select pizza size");
return null;
}
PizzaData selectedPizza = getPizzaData(comboPizza.getValue());
if (selectedPizza == null) {
ExceptionDialog exceptionDialog = new ExceptionDialog("Error when searching for selected pizza", new Exception());
exceptionDialog.showAndWait();
return null;
}
return getPizzaSizeData(comboPizzaSize.getValue());
}
You could return optionals instead of null but this illustrates the mechanism.
And then call the new method:
private void buttSellAction(ActionEvent event){
InfoTip infoTip = new InfoTip();
PizzaSizeData selectedPizzaSize = getAndVerifySelectedPizza();
if (selectedPizzaSize == null) {
return;
}
// Carry on with the method....
Putting validation at the start of a method with an early return statement is a common pattern so the multiple returns aren't going to confuse anyone and they allow each validation rule to be written separately.
you can use ladder if else in your code. like this
if(isAdressOK == true && isClientNameOK == true && isTelephoneOK == true && isCostOK == true){
double totalCost = selectedPizza.getPrice() + selectedPizzaSize.getPrice() + Double.valueOf(deliveryCost);
//everything is okey
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirm");
alert.setHeaderText("Total cost: " + totalCost);
alert.setContentText("Proceed with sale?");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK){
int id = insertSale(timestamp, currentUser.getLogin(), selectedPizza.getID(),
selectedPizzaSize.getSize(), true, selectedPizza.getPrice() + selectedPizzaSize.getPrice());
insertDelivery(id, adress, clientName, telephone, Double.valueOf(deliveryCost));
infoTip.getInfoTip().setId("greenInfoTip");
infoTip.showTip((Button)event.getSource(), " Saved ");
} else {
// ... user chose CANCEL or closed the dialog
}
}else if(!isAdressOK == true){
infoTip.showTip(textFAdress, "max 50 characters, not empty");
}else if(!isClientNameOK == true){
infoTip.showTip(textFClientName, "max 35 characters");
}else if(!isTelephoneOK == true){
infoTip.showTip(textFTelephone, "max 20 characters, not empty");
}else{
infoTip.showTip(textFCost, "keep right format e.g. 4.35");
}
same for other if else condition.
This is the code I'm using to process the input of an integer :
public static int getIntInput(String message) {
String numberStr = JOptionPane.showInputDialog(message);
while (!StringUtils.isNumeric(numberStr) || Integer.parseInt(numberStr) == 0) {
numberStr = JOptionPane.showInputDialog(message);
}
return Integer.parseInt(numberStr);
}
It works fine, except when I want to press "cancel" or close button on the JOption window. When I do that, the JOptionPane window shows up again.
How can I correctly close a JOptionPane window when the cancel or close button is pushed?
while (!StringUtils.isNumeric(numberStr) || Integer.parseInt(numberStr) == 0) {
if (numberStr == null) {
return 0;
}
else {
numberStr = JOptionPane.showInputDialog(message);
}
}
This does the trick.
I am trying to have it so once my mouse is pressed its gets fired once and only once. However, it keeps getting fired twice. I am not sure if this is because I am going through a for loop, but I want the mouse listener to catch what index of the array that I am clicking on. That is why I assign it to each index in the 2d array, I am not sure if theres a better way of doing this.
Code:
public boolean firstClick = false;
public boolean secondClick = false;
for (int i = 7; i >= 0; i--) {
for (int j = 0; j < 8; j++) {
int tempi = i;
int tempj = j;
pnlCells[i][j].add(getPieceObject(str[(7 - i)][j]), BorderLayout.CENTER);
pnlCells[i][j].validate();
pnlCells[i][j].addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
try {
if (firstClick == false || secondClick == false) {
if (firstClick == false) {
mouseX = tempj;
mouseY = 7 - tempi;
System.out.println("First You pressed" + mouseX + ", " + mouseY);
firstClick = true;
sourceColor = pnlCells[mouseX][mouseY].getForeground();
pnlCells[mouseX][mouseY].setForeground(Color.yellow);
pnlCells[mouseX][mouseY].repaint();
pnlBoard.repaint();
pnlMain.repaint();
} else if (secondClick == false) {
newMouseX = tempj;
newMouseY = 7 - tempi;
System.out.println("Second You pressed" + newMouseX + ", " + newMouseY);
secondClick = true;
}
if (firstClick == true && secondClick == true) {
firstClick = false;
secondClick = false;
pnlCells[mouseX][mouseY].setForeground(sourceColor);
pnlCells[mouseX][mouseY].repaint();
pnlBoard.repaint();
pnlMain.repaint();
PlayerMove pM = turn(); //send turn to server
objectOut.writeObject(pM); //send turn to server
System.out.println(name + ": sent move to server");
s.suspend();
}
}
} catch (IOException ex) {
Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
//System.out.println(j+", "+(i)+":"+v.str[(7-i)][j]);
}
}
Once I click the mouse once it always prints
First You pressed xcoord1, ycoord1
Second You pressed xcoord2, ycoord2
I am assuming that Both firstClick and secondClick are false at the init. Then when we go in the loop, the firstClick will always fire and then you set it to true. In the next iteration, the secondClick will always fire because it is false and firstClick will not fire because it is true now.
Set Both firstClick and secondClick to true once any of these fire.
I am working on a project in which I create a simple game of Ping Pong. If a player wins, I would like that a JOptionPane pop up asking if the user would like to play a new Game or stop playing. When I add the JOptionPane, the method does not wait for the user to select a button, but keeps going and keeps creating JOptionPanes until it returns a Stack Overflow Error. The code that controls it is
int rightMinLeft = Right_Player_Score.getNumber()-Left_Player_Score.getNumber();
boolean rightWon = Right_Player_Score.getNumber() > 20 && rightMinLeft > 1;
if(rightWon)
{
Object[] options = {"New Game", "Finish"};
int i = JOptionPane.showOptionDialog(null, "Right Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
if(i == 0)
{
reset();
}
else
{
GameOver = true;
}
}
else if(Left_Player_Score.getNumber() > 20 && Left_Player_Score.getNumber()-Right_Player_Score.getNumber()>1)
{
Object[] options = {"New Game", "Finish"};
int i = JOptionPane.showOptionDialog(null, "Right Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
if(i == 0)
{
reset();
}
else
{
GameOver = true;
}
}
Any suggestions?
Edit:
Here is the full method:
public void update(Graphics window)
{
paint(window);
}
public void paint(Graphics window)
{
try{
if(pause)
{
Right_Player_Score.draw("Right Player Score", window, 600, 20);
Left_Player_Score.draw("Left Player Score", window, 0, 20);
leftPaddle.draw(window);
rightPaddle.draw(window);
if(U.LELatch(keys[4]))
{
pause = false;
}
}
else
{
ball.moveAndDraw(window);
leftPaddle.draw(window);
Right_Player_Score.draw("Right Player Score", window, Color.WHITE, 600, 20);
Left_Player_Score.draw("Left Player Score", window, Color.WHITE, 0, 20);
int LeftPaddleBottom = leftPaddle.getY()+(leftPaddle.getHeight());
int RightPaddleBottom = rightPaddle.getY()+(rightPaddle.getHeight());
int LeftPaddleTop = leftPaddle.getY();
int RightPaddleTop = rightPaddle.getY();
boolean inRangeLeft = ball.getY() > LeftPaddleTop && ball.getY() < LeftPaddleBottom;
boolean inRangeRight = ball.getY() > RightPaddleTop && ball.getY() < RightPaddleBottom;
if(ball.getX()<=10)
{
ball.setXSpeed(-ball.getXSpeed());
Right_Player_Score.increment();
}
else if(ball.getX()>=790)
{
ball.setXSpeed(-ball.getXSpeed());
Left_Player_Score.increment();
}
else if((inRangeLeft && ball.getX()<=leftPaddle.getX()+leftPaddle.getWidth()))
{
ball.setXSpeed(-ball.getXSpeed());
numTimes ++;
}
else if(inRangeRight && ball.getX()>=rightPaddle.getX())
{
ball.setXSpeed(-ball.getXSpeed());
numTimes ++;
}
if(!(ball.getY()>=10 && ball.getY()<=450))
{
ball.setYSpeed(-ball.getYSpeed());
}
if(keys[0] == true)
{
leftPaddle.moveUpAndDraw(window);
}
else if(keys[1] == true)
{
leftPaddle.moveDownAndDraw(window);
}
else
{
leftPaddle.draw(window);
}
if(keys[2] == true)
{
rightPaddle.moveUpAndDraw(window);
}
else if(keys[3] == true)
{
rightPaddle.moveDownAndDraw(window);
}
else
{
rightPaddle.draw(window);
}
int rightMinLeft = Right_Player_Score.getNumber()-Left_Player_Score.getNumber();
boolean rightWon = Right_Player_Score.getNumber() > 20 && rightMinLeft > 1;
if(rightWon)
{
Object[] options = {"New Game", "Finish"};
int i = JOptionPane.showOptionDialog(frame, "Right Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
//window.setColor(Color.BLACK);
//window.drawString("Right Player has won",200,400);
//Thread.currentThread().sleep(2000);
//int i = 1;
if(i == 0)
{
reset();
}
else
{
GameOver = true;
}
}
else if(Left_Player_Score.getNumber() > 20 && Left_Player_Score.getNumber()-Right_Player_Score.getNumber()>1)
{
Object[] options = {"New Game", "Finish"};
int i = JOptionPane.showOptionDialog(frame, "Left Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
//window.setColor(Color.BLACK);
//window.drawString("Left Player has won",200,400);
//Thread.currentThread().sleep(2000);
//int i = 1;
if(i == 0)
{
reset();
}
else
{
GameOver = true;
}
}
Right_Player_Score.draw("Right Player Score", window, 600, 20);
Left_Player_Score.draw("Left Player Score", window, 0, 20);
if(numTimes == 10)
{
numTimes = 0;
if(ball.getXSpeed() == Math.abs(ball.getXSpeed()))
{
ball.setXSpeed(ball.getXSpeed() + 1);
}
else
{
ball.setXSpeed(ball.getXSpeed() - 1);
}
if(ball.getXSpeed()>MAXSPEED)
{
ball.setXSpeed(MAXSPEED);
}
}
pause = U.LELatch(keys[4]);
}
}
catch(Exception e)
{
}
}
This is used in "public class GUI_Controller extends Canvas implements KeyListener, Runnable"
Note: The commented portions are a stopgap way of getting the user to at least see something.
The behavior you are seeing is because you are overloading the paint(Graphics g) method.
From the paint(Graphics g) JavaDoc
This method is called when the contents of the component should be painted; such
as when the component is first being shown or is damaged and in need
of repair.
In your case, what is likely happening is the call to JOptionPane.showOptionDialog() results in a JDialog showing over your Canvas which triggers another call to paint(). That in turn causes another call to JOptionPane.showOptionDialog() triggering another a call to paint() and so on... This will continue until you get a StackOverflowError or OutOfMemoryError.
In practice, paint() gets called quite frequently so it should be very efficient. Typically only your custom drawing should be done in the paint() method.
Other logic should live in different methods. You should move the logic for your scoring and user interaction outside of the paint() method and leave just the drawing in place.
Edit: Without seeing more of the code I can't give you a specific recommendation of where to move the logic which is not directly concerned with painting. You might find it helpful to review the Java Swing tutorial section on Performing Custom Painting.
It might help to give the JOptionPane your current frame as the first parameter instead of null.