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) {
}
}
I want to globally listen for CTRL + v in SWT. I can successfully listen for CTRL + c but paste seems to be handled differently in SWT. The following Listener shows how it works for copy and how it does not work for paste:
display.addFilter(SWT.KeyDown, new Listener() {
private final int CTRL = SWT.MOD1;
private boolean checkNextEventForPaste = false;
#Override
public void handleEvent(Event event) {
if(event.stateMask == CTRL && event.keyCode == 'c'){
System.out.println("copy: this works!");
}
else if(event.stateMask == CTRL && (event.keyCode == 'v'
|| event.keyCode == 'V'
|| event.keyCode == 0x16
|| event.keyCode == 118)){
System.out.println("paste: does not work!");
}
else if (event.keyCode == CTRL){
//control for paste is fired first
checkNextEventForPaste = true;
}
else if(checkNextEventForPaste){
if(event.keyCode == 65536){
System.out.println("custom solution: seems to not only apply for paste");
}
checkNextEventForPaste = false;
}
}
});
I debugged the paste case and created a custom solution. The paste keyboard short cut creates the following event sequence:
first event with stateMask = 0 and keyCode = CTRL
second event with stateMask = 0 and keyCode = 65536
The problem is that the custom paste solution seems to apply for other shortcuts too. For example the copy shortcut creates the following event sequence:
first event with stateMask = 0 and keyCode = CTRL
second event with stateMask = CTRL and keyCode = 'c'
third event with stateMask = 0 and keyCode = 65536
Why does SWT handle the paste shortcut in a different way? Is it possible that the paste shortcut is already consumed by an other control? Or does anybody know how I can identify the paste shortcut? A VerifyListener is not applicable in my use case. I have implemented a more or less complex UI with custom selection, as you can see here.
The code below works just fine for both Ctrl+c and Ctrl+v
public static void main(String[] args)
{
final Display d = new Display();
Shell s = new Shell(d);
d.addFilter(SWT.KeyDown, e ->
{
if (((e.stateMask & SWT.CTRL) == SWT.CTRL) && (e.keyCode == 'c'))
{
System.out.println("copy");
}
else if (((e.stateMask & SWT.CTRL) == SWT.CTRL) && (e.keyCode == 'v'))
{
System.out.println("paste");
}
});
s.pack();
s.open();
while (!s.isDisposed())
{
if (!d.readAndDispatch())
d.sleep();
}
d.dispose();
}
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 making a blackjack game and was wondering if I could make it so that I had two different actions on a single button.
This is what I have so far on the hit button, but instead of having the second card show on a double click, I want it to show the second card when you press the button again.
public void hit(MouseEvent event) {
if (event.getClickCount() == 1) {
card5 = deck.dealCard();
pcard3.setImage(card5.getImage());
}
if (event.getClickCount() == 2) {
card6 = deck.dealCard();
pcard4.setImage(card6.getImage());
}
}
You can have an iterator whose value can be increased on each click. And for different values set different functionalities. See the code
int i =0;
public void hit(MouseEvent event) {
if (i%2== 0) {
card5 = deck.dealCard();
pcard3.setImage(card5.getImage());
} else if (i%2 == 1) {
card6 = deck.dealCard();
pcard4.setImage(card6.getImage());
}
i++;
}