I'm stuck on figuring out how to add a decimal place function to a very simple calculator gui I am building. The current implementation I have for the makeDecimalButton function throws an error at runtime. Should I not be parsing the decimal to a double? Maybe I should be using BigDecimal? Any help is appreciated.
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import java.util.HashMap;
import java.util.Map;
public class Calculator extends Application {
private static final String[][] template = {
{ "7", "8", "9", "/" },
{ "4", "5", "6", "*" },
{ "1", "2", "3", "-" },
{ "0", "C", "=", "+", "." } };
private final Map<String, Button> accelerators = new HashMap<>();
private DoubleProperty stackValue = new SimpleDoubleProperty();
private DoubleProperty value = new SimpleDoubleProperty();
private enum Operation {
NOOP, ADD, SUBTRACT, MULTIPLY, DIVIDE
}
private Operation curOp = Operation.NOOP;
private Operation stackOp = Operation.NOOP;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
final TextField screen = createScreen();
final TilePane buttons = createButtons();
stage.setTitle("Calculator");
stage.initStyle(StageStyle.UTILITY);
stage.setResizable(false);
stage.setScene(new Scene(createLayout(screen, buttons)));
stage.show();
}
private VBox createLayout(TextField screen, TilePane buttons) {
final VBox layout = new VBox(20);
layout.setAlignment(Pos.CENTER);
layout.setStyle("-fx-background-color: black; -fx-padding: 20; -fx-font-size: 20;");
layout.getChildren().setAll(screen, buttons);
handleAccelerators(layout);
screen.prefWidthProperty().bind(buttons.widthProperty());
return layout;
}
private void handleAccelerators(VBox layout) {
layout.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent keyEvent) {
Button activated = accelerators.get(keyEvent.getText());
if (activated != null) {
activated.fire();
}
}
});
}
private TextField createScreen() {
final TextField screen = new TextField();
screen.setStyle("-fx-background-color: white;");
screen.setAlignment(Pos.CENTER_RIGHT);
screen.setEditable(false);
screen.textProperty().bind(Bindings.format("%f", value));
return screen;
}
private TilePane createButtons() {
TilePane buttons = new TilePane();
buttons.setVgap(7);
buttons.setHgap(7);
buttons.setPrefColumns(template[0].length);
for (String[] r : template) {
for (String s : r) {
buttons.getChildren().add(createButton(s));
}
}
return buttons;
}
private Button createButton(final String s) {
Button button = makeStandardButton(s);
if (s.matches("[0-9]")) {
makeNumericButton(s, button);
} else {
final ObjectProperty<Operation> triggerOp = determineOperand(s);
if (triggerOp.get() != Operation.NOOP) {
makeOperandButton(button, triggerOp);
} else if ("C".equals(s)) {
makeClearButton(button);
} else if ("=".equals(s)) {
makeEqualsButton(button);
} else if (".".equals(s)) {
makeDecimalButton(button);
}
}
return button;
}
private void makeDecimalButton(Button button) {
button.setStyle("-fx-base: mistyrose;");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
value.set(value.get() + Double.parseDouble("."));
}
});
}
private ObjectProperty<Operation> determineOperand(String s) {
final ObjectProperty<Operation> triggerOp = new SimpleObjectProperty<>(Operation.NOOP);
switch (s) {
case "+":
triggerOp.set(Operation.ADD);
break;
case "-":
triggerOp.set(Operation.SUBTRACT);
break;
case "*":
triggerOp.set(Operation.MULTIPLY);
break;
case "/":
triggerOp.set(Operation.DIVIDE);
break;
}
return triggerOp;
}
private void makeOperandButton(Button button, final ObjectProperty<Operation> triggerOp) {
button.setStyle("-fx-base: lightgray;");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
curOp = triggerOp.get();
}
});
}
private Button makeStandardButton(String s) {
Button button = new Button(s);
button.setStyle("-fx-base: beige;");
accelerators.put(s, button);
button.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
return button;
}
private void makeNumericButton(final String s, Button button) {
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
if (curOp == Operation.NOOP) {
value.set(value.get() * 10 + Integer.parseInt(s));
} else {
stackValue.set(value.get());
value.set(Integer.parseInt(s));
stackOp = curOp;
curOp = Operation.NOOP;
}
}
});
}
private void makeClearButton(Button button) {
button.setStyle("-fx-base: mistyrose;");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
value.set(0);
}
});
}
private void makeEqualsButton(Button button) {
button.setStyle("-fx-base: ghostwhite;");
button.setOnAction(new EventHandler<ActionEvent>() {
#SuppressWarnings("incomplete-switch")
#Override
public void handle(ActionEvent actionEvent) {
switch (stackOp) {
case ADD:
value.set(stackValue.get() + value.get());
break;
case SUBTRACT:
value.set(stackValue.get() - value.get());
break;
case MULTIPLY:
value.set(stackValue.get() * value.get());
break;
case DIVIDE:
value.set(stackValue.get() / value.get());
break;
}
}
});
}
}
from the documentation:
parseDouble(String s)
Returns a new double initialized to the value represented by the specified String, as performed by the valueOf method of class Double.
so you are trying to parse a double from the string "." which isn't a valid decimal number.
Related
I have a ListView with with a custom CheckBox Item called CheckBoxListItem. Everthing looks good but now I need to implement Drag and Drop for easier sorting.
I know that I have to use a custom CellFactory and set the Drag and Drop Events to the cell itself. My Problem is that I already have a CellFactory and dont know how to add the Events.
The commented code is what I think could be the way to do it but the updateItem method doesn't worked.
My main class:
public class Main extends Application{
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
ListView<CheckBoxListItem> listView = new ListView<>();
ScrollPane scrollPane = new ScrollPane(listView);
scrollPane.setFitToHeight(true);
scrollPane.setFitToWidth(true);
for(int i=1; i<15; i++) {
listView.getItems().add(new CheckBoxListItem("Value"+i));
}
listView.setCellFactory(CheckBoxListCell.forListView(CheckBoxListItem::selectedProperty, new StringConverter< CheckBoxListItem>() {
#Override
public String toString(CheckBoxListItem object) {
return object.getName();
}
#Override
public CheckBoxListItem fromString(String string) {
return null;
}
}));
/*
ObjectProperty<CheckBoxListCell<CheckBoxListItem>> dragSource = new SimpleObjectProperty<>();
listView.setCellFactory(lv -> {
CheckBoxListCell<CheckBoxListItem> cell = new CheckBoxListCell<CheckBoxListItem>(){
#Override
public void updateItem(CheckBoxListItem item , boolean empty) {
super.updateItem(item, empty);
if (item == null) {
setGraphic(null);
}else {
setGraphic(?????);
}
}
};
cell.setOnDragDetected(event -> {
//TODO
});
cell.setOnDragOver(event -> {
//TODO
});
cell.setOnDragDropped(event -> {
//TODO
});
return cell ;
});
*/
Scene scene = new Scene(scrollPane, 350, 450);
stage.setScene(scene);
stage.show();
}
#Override
public void stop() {
System.exit(0);
}
}
and CheckBoxListItem.java:
public class CheckBoxListItem {
private ReadOnlyStringWrapper name = new ReadOnlyStringWrapper();
private BooleanProperty selected = new SimpleBooleanProperty(false);
public CheckBoxListItem(String name) {
this.name.set(name);
}
public CheckBoxListItem(String name, boolean selected) {
this.name.set(name);
this.selected.set(selected);
}
public String getName() {
return name.get();
}
public BooleanProperty selectedProperty() {
return selected;
}
public boolean isSelected() {
return selected.get();
}
public void setSelected(boolean selected) {
this.selected.set(selected);
}
}
The solution is something you have to combine both your approaches. You can merely mimic what CheckBoxListCell.forListView() internally does. i.e, creating a new CheckBoxListCell with the observableProperty and converter. I just remodified your demo to below and it works as expected.
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.cell.CheckBoxListCell;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
ListView<CheckBoxListItem> listView = new ListView<>();
ScrollPane scrollPane = new ScrollPane(listView);
scrollPane.setFitToHeight(true);
scrollPane.setFitToWidth(true);
for (int i = 1; i < 15; i++) {
listView.getItems().add(new CheckBoxListItem("Value" + i));
}
// listView.setCellFactory(CheckBoxListCell.forListView(CheckBoxListItem::selectedProperty, new StringConverter< CheckBoxListItem>() {
// #Override
// public String toString(CheckBoxListItem object) {
// return object.getName();
// }
//
// #Override
// public CheckBoxListItem fromString(String string) {
// return null;
// }
// }));
ObjectProperty<CheckBoxListCell<CheckBoxListItem>> dragSource = new SimpleObjectProperty<>();
listView.setCellFactory(lv -> {
CheckBoxListCell<CheckBoxListItem> cell = new CheckBoxListCell<>(CheckBoxListItem::selectedProperty, new StringConverter<CheckBoxListItem>() {
#Override
public String toString(CheckBoxListItem object) {
return object.getName();
}
#Override
public CheckBoxListItem fromString(String string) {
return null;
}
});
cell.setOnDragDetected(event -> {
System.out.println("Detected fired...");
});
cell.setOnDragOver(event -> {
System.out.println("DragOver fired...");
});
cell.setOnDragDropped(event -> {
System.out.println("DragDropped fired...");
});
return cell;
});
Scene scene = new Scene(scrollPane, 350, 450);
stage.setScene(scene);
stage.show();
}
#Override
public void stop() {
System.exit(0);
}
}
I am rewriting an application from swing to javafx.
I do not understand how to implement a double click event and a right click event on the same row of a tableview.
Separately they work ok.
Thi is my code for right click behaviour.
words_table.setRowFactory(
new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() {
#Override
public TableRow<WordsToFind> call(TableView<WordsToFind> tableView) {
final TableRow<WordsToFind> row = new TableRow<>();
final ContextMenu rowMenu = new ContextMenu();
MenuItem removeItem = new MenuItem("Delete");
removeItem.setOnAction(e -> {
int wordid = words_table.getSelectionModel().getSelectedItem().getWordToFindId();
deleteWord(wordid);
words_table.getItems().remove(row.getItem());
});
rowMenu.getItems().addAll(removeItem);
row.contextMenuProperty().bind(
Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(rowMenu)
.otherwise((ContextMenu)null));
return row;
}
});
This is my code for double click behaviour
words_table.setRowFactory(
new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() {
#Override
public TableRow<WordsToFind> call(TableView<WordsToFind> tableView) {
final TableRow<WordsToFind> row = new TableRow<>();
row.setOnMouseClicked(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent event){
if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
some code here .....
}
}
});
return row;
}
});
Thanks Alb
Just put the row.setOnMouseClicked call in the call() method of the first row factory.
words_table.setRowFactory(tableView -> {
final TableRow<WordsToFind> row = new TableRow<>();
final ContextMenu rowMenu = new ContextMenu();
MenuItem removeItem = new MenuItem("Delete");
removeItem.setOnAction(e -> {
int wordid = words_table.getSelectionModel().getSelectedItem().getWordToFindId();
deleteWord(wordid);
words_table.getItems().remove(row.getItem());
});
rowMenu.getItems().addAll(removeItem);
row.contextMenuProperty().bind(
Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(rowMenu)
.otherwise((ContextMenu)null));
row.setOnMouseClicked(event -> {
if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
// some code here .....
}
});
return row;
});
(I converted the anonymous inners classes to lambda expressions for readability.)
Here is a complete example that demonstrates this working:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
public class RowFactoryExample extends Application {
#Override
public void start(Stage primaryStage) {
TableView<Item> table = new TableView<>();
table.getColumns().add(column("Item", Item::nameProperty));
table.getColumns().add(column("Value", Item::valueProperty));
table.getItems().setAll(createData());
table.setRowFactory(tableView -> {
final TableRow<Item> row = new TableRow<>();
final ContextMenu rowMenu = new ContextMenu();
MenuItem removeItem = new MenuItem("Delete");
removeItem.setOnAction(e -> {
table.getItems().remove(row.getItem());
});
rowMenu.getItems().addAll(removeItem);
row.contextMenuProperty().bind(
Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(rowMenu)
.otherwise((ContextMenu)null));
row.setOnMouseClicked(event -> {
if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
System.out.println("Double click on "+row.getItem().getName());
}
});
return row;
});
Scene scene = new Scene(table, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private <S,T> TableColumn<S,T> column(String text, Function<S, ObservableValue<T>> prop) {
TableColumn<S,T> col = new TableColumn<>(text);
col.setCellValueFactory(cellData -> prop.apply(cellData.getValue()));
return col ;
}
private List<Item> createData() {
Random rng = new Random();
List<Item> data = new ArrayList<>();
for (int i = 1 ; i <= 100; i++) {
data.add(new Item("Item "+i, rng.nextInt(1000))) ;
}
return data ;
}
public static class Item {
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty value = new SimpleIntegerProperty();
public Item(String name, int value) {
setName(name);
setValue(value);
}
public final StringProperty nameProperty() {
return this.name;
}
public final String getName() {
return this.nameProperty().get();
}
public final void setName(final String name) {
this.nameProperty().set(name);
}
public final IntegerProperty valueProperty() {
return this.value;
}
public final int getValue() {
return this.valueProperty().get();
}
public final void setValue(final int value) {
this.valueProperty().set(value);
}
}
public static void main(String[] args) {
launch(args);
}
}
You can add both events to the row by doing row.setOnMouseClicked(..) itself as shown below
words_table.setRowFactory(
new Callback<TableView<WordsToFind>, TableRow<WordsToFind>>() {
#Override
public TableRow<WordsToFind> call(TableView<WordsToFind> tableView) {
final TableRow<WordsToFind> row = new TableRow<>();
row.setOnMouseClicked(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent event){
if (event.getClickCount() == 2 && (! row.isEmpty()) ) {
//double click code here
}
else if(event.isSecondaryButtonDown()){
//right click code here
}
}
});
return row;
}
});
I have created this app with many other classes and it seems to run okay. However, when I finish the quiz, I cant add a button to restart the quiz? I have tried Jbutton and Jframe but I have no idea how to do it? Is there a simple code to add?
package sample;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import javafx.event.ActionEvent;
import javafx.stage.Stage;
import javax.xml.bind.JAXBException;
public class Controller implements Initializable{
static int count = 1;
static int score=0;
static int multiplayerCounter = 1;
static int scoreOfComputer = 0;
static int scoreOfHuman = 0;
static String level;
static XmlToObject ob = new XmlToObject();
static List<String[]> questionsList = ob.readQuestionsAndAnswers("easy");
static boolean isCheatSet;
static boolean isSkipSet;
static String username;
public static String getLevel() {
return level;
}
public static void setLevel(String level) {
Controller.level = level;
}
#FXML
public RadioButton rdEasy;
#FXML
public RadioButton rdHard;
#FXML
public TextField txtAnswer;
#FXML
private Label lblMessage;
#FXML
private TextField txtUsername;
#FXML
private PasswordField txtPassword;
#FXML
private ListView lstHistoryScore;
#FXML
private Button btnNext;
#FXML
private Button btnCheat;
#FXML
private Button btnSkip;
#FXML
private Button btnStart;
#FXML
private Label headerCaption;
#FXML
private Label quizCaption;
#FXML
public Label question;
#FXML
public RadioButton optionOne;
#FXML
public RadioButton optionTwo;
#FXML
public Button btnPass;
#FXML
public RadioButton rdSinglePlayer;
#FXML
public ToggleGroup answerGroup;
#Override
public void initialize(URL location, ResourceBundle resources) {
}
#FXML
private void btnLoginAction(ActionEvent actionEvent) throws IOException {
List<String[]> loginList = ob.readUserLogins();
for(String[] s:loginList ){
if(txtUsername.getText().equals(s[0]) && txtPassword.getText().equals(s[1])){
lblMessage.setText("Success");
((Node) (actionEvent.getSource() )).getScene().getWindow().hide();
Parent parent = FXMLLoader.load(getClass().getResource("/sample/Start.fxml"));
username = txtUsername.getText();
Stage stage = new Stage();
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.show();
}else{
lblMessage.setText("Invalid username or password");
}
}
}
public void btnNextAction(ActionEvent actionEvent) throws IOException, JAXBException {
Stage stage = (Stage) ((Node)actionEvent.getSource()).getScene().getWindow();
int index = count - 1;
String[] criteria = questionsList.get(index);
if(getLevel().equals("hard")){
if (criteria[2].toLowerCase().equals(txtAnswer.getText().toLowerCase()) && !isCheatSet && !isSkipSet) {
score++;
}
if(count == 10) {
quizCaption.setText("Over");
question.setText("Your Score: " + score);
txtAnswer.setVisible(false);
btnNext.setVisible(false);
btnCheat.setVisible(false);
btnSkip.setVisible(false);
lstHistoryScore.setVisible(true);
lstHistoryScore.setItems(new XmlToObject().readXml());
ObjectToXML obx = new ObjectToXML();
obx.saveToXml(score);
}else {
txtAnswer.setText("");
String[] cr = questionsList.get(count);
quizCaption.setText("Quiz " + (count + 1));
question.setText(cr[1]);
isCheatSet = false;
isSkipSet = false;
count++;
}
}else {
RadioButton selectedRadio = (RadioButton) answerGroup.getSelectedToggle();
optionOne.setSelected(false);
optionTwo.setSelected(false);
if(!isSkipSet) {
if (getAnswer(criteria[4], selectedRadio.getText()) && !isCheatSet) {
score++;
}
}
if(count == 10) {
quizCaption.setText("Over");
question.setText("Your Score: " + score);
optionOne.setVisible(false);
optionTwo.setVisible(false);
btnNext.setVisible(false);
btnCheat.setVisible(false);
btnSkip.setVisible(false);
lstHistoryScore.setVisible(true);
lstHistoryScore.setItems(new XmlToObject().readXml());
ObjectToXML obx = new ObjectToXML();
obx.saveToXml(score);
}else {
String[] cr = questionsList.get(count);
quizCaption.setText("Quiz " + (count + 1));
question.setText(cr[1]);
optionOne.setText(cr[2]);
optionTwo.setText(cr[3]);
isCheatSet = false;
isSkipSet = false;
count++;
}
}
}
public void btnCheatAction(ActionEvent actionEvent) throws IOException, JAXBException {
isCheatSet = true;
int index = count -1;
if(getLevel().equals("hard")){
txtAnswer.setText(getCheatAnswerForHardLevel(index));
}else {
if(getCheatAnswer(index) == 1){
optionOne.setSelected(true);
}else {
optionTwo.setSelected(true);
}
}
Task<Void> sleeper = new Task<Void>() {
#Override
protected Void call() throws Exception {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
return null;
}
};
sleeper.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
try {
btnNextAction(actionEvent);
} catch (IOException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
}
}
});
new Thread(sleeper).start();
}
public void btnSkipAction(ActionEvent actionEvent) throws IOException, JAXBException {
isSkipSet = true;
btnNextAction(actionEvent);
}
public void setName(String name) {
quizCaption.setText(name);
}
public void btnStartAction(ActionEvent actionEvent) throws IOException, JAXBException {
if(rdSinglePlayer.isSelected()){
((Node) (actionEvent.getSource())).getScene().getWindow().hide();
if(rdHard.isSelected()) {
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/sample/SinglePlayerHardLevel.fxml"));
questionsList = ob.readQuestionsAndAnswers("hard");
String[] criteria = questionsList.get(0);
setLevel("hard");
loader.getNamespace().put("caption", ("Quiz"+ criteria[0]) );
loader.getNamespace().put("quiz", criteria[1]);
Parent root = loader.load();
Stage stage = new Stage();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}else {
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/sample/SinglePlayerEasyLevel.fxml"));
String[] criteria = questionsList.get(0);
loader.getNamespace().put("caption", ("Quiz" + criteria[0]));
loader.getNamespace().put("quiz", criteria[1]);
loader.getNamespace().put("one", criteria[2]);
loader.getNamespace().put("two", criteria[3]);
Parent root = loader.load();
setLevel("easy");
Stage stage = new Stage();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}else{
((Node) (actionEvent.getSource())).getScene().getWindow().hide();
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/sample/Multiplayer.fxml"));
String[] criteria = questionsList.get(0);
loader.getNamespace().put("player", "Human");
loader.getNamespace().put("caption", ("Quiz" + criteria[0]));
loader.getNamespace().put("quiz", criteria[1]);
loader.getNamespace().put("one", criteria[2]);
loader.getNamespace().put("two", criteria[3]);
Parent root = loader.load();
Stage stage = new Stage();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
public void btnPassAction(ActionEvent actionEvent) {
RadioButton selectedRadio = (RadioButton) answerGroup.getSelectedToggle();
optionOne.setSelected(false);
optionTwo.setSelected(false);
int index = multiplayerCounter - 1;
if (multiplayerCounter == 10) {
question.setText("Computer score: " + scoreOfComputer);
quizCaption.setText("Your Score: " + scoreOfHuman);
optionOne.setVisible(false);
optionTwo.setVisible(false);
btnPass.setVisible(false);
}else {
String[] criteria = questionsList.get(index);
if (multiplayerCounter % 2 == 0) {
headerCaption.setText("Human");
optionOne.setDisable(false);
optionTwo.setDisable(false);
if (getAnswer(criteria[4], selectedRadio.getText())) {
scoreOfComputer++;
}
} else {
headerCaption.setText("Computer");
int ans = findRandomAnswer(Math.random());
if (ans == 1) {
optionOne.setSelected(true);
optionTwo.setDisable(true);
} else {
optionTwo.setSelected(true);
optionOne.setDisable(true);
}
if (getAnswer(criteria[4], selectedRadio.getText())) {
scoreOfHuman++;
}
}
String[] cr = questionsList.get(multiplayerCounter);
quizCaption.setText("Quiz " + cr[0]);
question.setText(cr[1]);
optionOne.setText(cr[2]);
optionTwo.setText(cr[3]);
multiplayerCounter++;
}
}
public boolean getAnswer(String answer, String quizOption){
if(answer.equals(quizOption)){
return true;
}else{
return false;
}
}
public int findRandomAnswer(double rand){
if(rand <= 0.7){
return 1;
}else{
return 2;
}
}
public int getCheatAnswer(int quizNumber){
String[] criteria = questionsList.get(quizNumber);
if(criteria[4].equals(criteria[2])){
return 1;
}else{
return 2;
}
}
public String getCheatAnswerForHardLevel(int quizNumber){
String[] criteria = questionsList.get(quizNumber);
return criteria[2];
}
public void rdSelectSinglePlayer(ActionEvent actionEvent) {
rdEasy.setVisible(true);
rdHard.setVisible(true);
btnStart.setDisable(false);
}
public void rdSelectMultiPlayer(ActionEvent actionEvent) {
rdEasy.setVisible(false);
rdHard.setVisible(false);
btnStart.setDisable(false);
}
}
I have a Javafx TableView where I can add new Rows by double Click on an empty Row at the End of my "filled" / Textfield filled Rows.
My Problem is,if i add some Rows ,Java don't give me more of the empty Rows I could double click to add some Rows.
Edit:removed some unnessary log
To see what i mean, here is the Code:
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TextArea;
import javafx.util.Callback;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
interface inside_table
{
public void Select_Row_by_Col(int index);
}
public class Supermain extends Application {
ObservableList<myTextRow> data;
#Override
public void start(Stage primaryStage) {
ArrayList myindizes=new ArrayList();
final TableView<myTextRow> table = new TableView<>();
table.setEditable(true);
table.setStyle("-fx-text-wrap: true;");
//Table columns
TableColumn<myTextRow, String> clmID = new TableColumn<>("ID");
clmID.setMinWidth(160);
clmID.setCellValueFactory(new PropertyValueFactory<>("ID"));
TableColumn<myTextRow, String> clmtext = new TableColumn<>("Text");
clmtext.setMinWidth(160);
clmtext.setCellValueFactory(new PropertyValueFactory<>("text"));
clmtext.setCellFactory(new TextFieldCellFactory("text"));
TableColumn<myTextRow, String> clmtext2 = new TableColumn<>("Text2");
clmtext2.setMinWidth(160);
clmtext2.setCellValueFactory(new PropertyValueFactory<>("text2"));
clmtext2.setCellFactory(new TextFieldCellFactory("text2"));
//Add data
data = FXCollections.observableArrayList(
new myTextRow(5, "Lorem","bla"),
new myTextRow(2, "Ipsum","bla")
);
table.getColumns().addAll(clmID, clmtext,clmtext2);
table.setItems(data);
table.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
if (mouseEvent.getClickCount() == 2 && mouseEvent.getY()>24) {
data.add(new myTextRow(td_get_biggest_ID() + 1,"",""));
table.selectionModelProperty().get().select(data.size()-1);
}
}
}
});
HBox hBox = new HBox();
hBox.setSpacing(5.0);
hBox.setPadding(new Insets(5, 5, 5, 5));
Button btn = new Button();
btn.setText("Get Data");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
for (myTextRow data1 : data) {
System.out.println("data:" + data1.getText2());
}
}
});
hBox.getChildren().add(btn);
BorderPane pane = new BorderPane();
pane.setTop(hBox);
pane.setCenter(table);
primaryStage.setScene(new Scene(pane, 640, 480));
primaryStage.show();
class I_table implements inside_table{
#Override
public void Select_Row_by_Col(int index) {
table.getSelectionModel().select(index);
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public static class TextFieldCellFactory
implements Callback<TableColumn<myTextRow, String>, TableCell<myTextRow, String>> {
private String ColumnName;
public TextFieldCellFactory(String ColumnName){
this.ColumnName=ColumnName;
}
#Override
public TableCell<myTextRow, String> call(TableColumn<myTextRow, String> param) {
TextFieldCell textFieldCell = new TextFieldCell(this.ColumnName);
return textFieldCell;
}
public static class TextFieldCell extends TableCell<myTextRow, String> {
private TextArea textField;
private StringProperty boundToCurrently = null;
private String last_text;
private String ColumnName;
public TextFieldCell(String cname) {
textField = new TextArea();
textField.setWrapText(true);
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
last_text="";
this.ColumnName=cname;
this.setGraphic(textField);
textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
if(this.ColumnName=="text2"){
if(isNowFocused){last_text=textField.getText();System.out.println("NOW focus "+last_text);}
if (! isNowFocused && ! isValid(textField.getText())) {
textField.setText(last_text);
//textField.setText("00:00:00:00");
textField.selectAll();
System.out.println("blur");
}
}
});
}
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
// Show the Text Field
this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
// myindizes.add(getIndex());
// Retrieve the actual String Property that should be bound to the TextField
// If the TextField is currently bound to a different StringProperty
// Unbind the old property and rebind to the new one
ObservableValue<String> ov = getTableColumn().getCellObservableValue(getIndex());
SimpleStringProperty sp = (SimpleStringProperty) ov;
if (this.boundToCurrently == null) {
this.boundToCurrently = sp;
this.textField.textProperty().bindBidirectional(sp);
} else if (this.boundToCurrently != sp) {
this.textField.textProperty().unbindBidirectional(this.boundToCurrently);
this.boundToCurrently = sp;
this.textField.textProperty().bindBidirectional(this.boundToCurrently);
}
double height = real_lines_height(textField.getText(), this.getWidth(), 30, 22);
textField.setPrefHeight(height);
textField.setMaxHeight(height);
textField.setMaxHeight(Double.MAX_VALUE);
// if height bigger than the biggest height in the row
//-> change all heights of the row(textfields ()typeof textarea) to this height
// else leave the height as it is
//System.out.println("item=" + item + " ObservableValue<String>=" + ov.getValue());
//this.textField.setText(item); // No longer need this!!!
} else {
this.setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}//update
private boolean isValid(String s){
String splitArray[] = s.split(":");
if (splitArray.length != 4) {
System.out.println("false");
return false;
}
for (int i = 0; i < splitArray.length; i++) {
if (splitArray[i].length() != 2) {
System.out.println("false");
return false;
}
if (!splitArray[i].substring(0, 1).matches("[0-9]")) {
System.out.println("no number1");
return false;
}
if (!splitArray[i].substring(1, 2).matches("[0-9]")) {
System.out.println("no number2");
return false;
}
if (i < 3) {
int itest = Integer.parseInt(splitArray[i]);
if (itest > 59) {
System.out.println(itest + " ist zu groß!");
return false;
}
} else {
int itest2 = Integer.parseInt(splitArray[i]);
if (itest2 > Math.floor(25)) {
System.out.println(itest2 + " ist zu groß!");
return false;
}
//framerate!!!!!
}
System.out.println("splits: " + splitArray[i]);
//if( el.charAt(0).)
}
return true;
}
}
}
public class myTextRow {
private final SimpleIntegerProperty ID;
private final SimpleStringProperty text;
private final SimpleStringProperty text2;
public myTextRow(int ID, String text,String text2) {
this.ID = new SimpleIntegerProperty(ID);
this.text = new SimpleStringProperty(text);
this.text2 = new SimpleStringProperty(text2);
}
//setter
public void setID(int id) {
this.ID.set(id);
}
public void setText(String text) {
this.text.set(text);
}
public void setText2(String text) {
this.text2.set(text);
}
//getter
public int getID() {
return ID.get();
}
public String getText() {
return text.get();
}
public String getText2() {
return text2.get();
}
//properties
public StringProperty textProperty() {
return text;
}
public StringProperty text2Property() {
return text2;
}
public IntegerProperty IDProperty() {
return ID;
}
}
private static double real_lines_height(String s, double width, double heightCorrector, double widthCorrector) {
HBox h = new HBox();
Label l = new Label("Text");
h.getChildren().add(l);
Scene sc = new Scene(h);
l.applyCss();
double line_height = l.prefHeight(-1);
int new_lines = s.replaceAll("[^\r\n|\r|\n]", "").length();
// System.out.println("new lines= "+new_lines);
String[] lines = s.split("\r\n|\r|\n");
// System.out.println("line count func= "+ lines.length);
int count = 0;
//double rest=0;
for (int i = 0; i < lines.length; i++) {
double text_width = get_text_width(lines[i]);
double plus_lines = Math.ceil(text_width / (width - widthCorrector));
if (plus_lines > 1) {
count += plus_lines;
//rest+= (text_width / (width-widthCorrector)) - plus_lines;
} else {
count += 1;
}
}
//count+=(int) Math.ceil(rest);
count += new_lines - lines.length;
return count * line_height + heightCorrector;
}
private static double get_text_width(String s) {
HBox h = new HBox();
Label l = new Label(s);
l.setWrapText(false);
h.getChildren().add(l);
Scene sc = new Scene(h);
l.applyCss();
// System.out.println("FXMLDocumentController.get_text_width(): "+l.prefWidth(-1));
return l.prefWidth(-1);
}
public int td_get_biggest_ID() {
int biggest = 0;
for (int i = 0; i < data.size(); i++) {
if (((myTextRow) data.get(i)).getID() > biggest) {
biggest = ((myTextRow) data.get(i)).getID();
}
}
return biggest;
}
}
Just click anywhere else on the TableView but make sure it's at least 24 pixels from the top; This will work since you've added the event handler is added to the TableView...
If you only want to use the last row, then use a custom rowFactory and handle the events there.
Add a placeholder item to the TableView items that marks the row that is used for adding new elements (for some reason the selection model doesn't like null):
final myTextRow addPlaceHolder = new myTextRow(Integer.MIN_VALUE, null, null);
...
//Add data
data = FXCollections.observableArrayList(
new myTextRow(5, "Lorem", "bla"),
new myTextRow(2, "Ipsum", "bla"),
addPlaceHolder
);
make sure your TextFieldCells treat null values as empty rows:
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty && item != null) {
// Show the Text Field
this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
...
make sure the first column does not display anything for the placeholder
//Table columns
TableColumn<myTextRow, Number> clmID = new TableColumn<>("ID");
clmID.setMinWidth(160);
clmID.setCellValueFactory(cdf -> {
myTextRow item = cdf.getValue();
return item == addPlaceHolder ? Bindings.createObjectBinding(() -> null) : item.IDProperty();
});
and use the following rowFactory to handle adding the items (you don't need the updateItem part unless you need to add a style class to the TableRow; you need not extend TableRow in this case)
table.setRowFactory(tv -> new TableRow<myTextRow>() {
{
setOnMouseClicked(mouseEvent -> {
if (mouseEvent.getButton() == MouseButton.PRIMARY
&& mouseEvent.getClickCount() == 2
&& !isEmpty()
&& getItem() == addPlaceHolder) {
data.add(data.size() - 1, new myTextRow(td_get_biggest_ID() + 1, "", ""));
table.selectionModelProperty().get().select(data.size() - 1);
mouseEvent.consume();
}
});
}
#Override
protected void updateItem(myTextRow item, boolean empty) {
super.updateItem(item, empty);
// add style class for row containing addPlaceHolder
List<String> classes = getStyleClass();
final String clazz = "add-row";
if (item == addPlaceHolder) {
if (!classes.contains(clazz)) {
classes.add(clazz);
}
} else {
classes.remove(clazz);
}
}
});
Hey I'm a begginer at java and i've only been doing this for a short period of time, anyways for my final project in java basics i need to make a simple calculator with a gui, i thought it won't be that hard but i was kinda wrong :P i have managed to do the most (i think) but am stuck atm with the event handling for the operations and setting the value to calculate, here is my code and could you please give me suggestions or tips on how to do it :D
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.WritableObjectValue;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
public class Calculator extends Application {
private DoubleProperty value = new SimpleDoubleProperty();
#Override
public void start(Stage primaryStage) {
FlowPane pane = new FlowPane();
pane.setAlignment(Pos.CENTER);
pane.setPadding(new Insets ( 30 , 20 , 30 , 20));
pane.setHgap(5);
pane.setVgap(5);
pane.setMinWidth(400);
pane.setPrefWidth(400);
pane.setMaxWidth(400);
TextField Rezultat = new TextField();
Rezultat.setEditable(false);
Rezultat.setAlignment(Pos.CENTER);
Rezultat.setMinSize(336, 40);
Rezultat.textProperty().bind(Bindings.format("%.0f" , value));
pane.getChildren().add(Rezultat);
Button sedmica = new Button("7");
Button osmica = new Button("8");
Button devetka = new Button("9");
Button plus = new Button("+");
sedmica.setMinSize(80, 80);
osmica.setMinSize(80, 80);
devetka.setMinSize(80, 80);
plus.setMinSize(80, 80);
pane.getChildren().add(sedmica);
sedmicaHandler handler7 = new sedmicaHandler();
sedmica.setOnAction(handler7);
pane.getChildren().add(osmica);
osmicaHandler handler8 = new osmicaHandler();
osmica.setOnAction(handler8);
pane.getChildren().add(devetka);
devetkaHandler handler9 = new devetkaHandler();
devetka.setOnAction(handler9);
pane.getChildren().add(plus);
plusHandler handlerplus = new plusHandler();
plus.setOnAction(handlerplus);
Button cetvorka = new Button("4");
Button petica = new Button("5");
Button sestica = new Button("6");
Button minus = new Button("-");
cetvorka.setMinSize(80, 80);
petica.setMinSize(80, 80);
sestica.setMinSize(80, 80);
minus.setMinSize(80, 80);
pane.getChildren().add(cetvorka);
cetvorkaHandler handler4 = new cetvorkaHandler();
cetvorka.setOnAction(handler4);
pane.getChildren().add(petica);
peticaHandler handler5 = new peticaHandler();
petica.setOnAction(handler5);
pane.getChildren().add(sestica);
sesticaHandler handler6 = new sesticaHandler();
sestica.setOnAction(handler6);
pane.getChildren().add(minus);
minusHandler handlerminus = new minusHandler();
minus.setOnAction(handlerminus);
Button trica = new Button("3");
Button dvica = new Button("2");
Button jedinica = new Button("1");
Button puta = new Button("*");
trica.setMinSize(80, 80);
dvica.setMinSize(80, 80);
jedinica.setMinSize(80, 80);
puta.setMinSize(80, 80);
pane.getChildren().add(jedinica);
jedinicaHandler handler1 = new jedinicaHandler();
jedinica.setOnAction(handler1);
pane.getChildren().add(dvica);
dvicaHandler handler2 = new dvicaHandler();
dvica.setOnAction(handler2);
pane.getChildren().add(trica);
tricaHandler handler3 = new tricaHandler();
trica.setOnAction(handler3);
pane.getChildren().add(puta);
putaHandler handlerputa = new putaHandler();
puta.setOnAction(handlerputa);
Button nula = new Button("0");
Button jednako = new Button("=");
Button podijeljeno = new Button("/");
Button EE = new Button ("EE");
nula.setMinSize(80, 80);
jednako.setMinSize(80, 80);
podijeljeno.setMinSize(80, 80);
EE.setMinSize(80, 80);
pane.getChildren().add(EE);
EEHandler handlerEE = new EEHandler();
EE.setOnAction(handlerEE);
pane.getChildren().add(nula);
nulaHandler handler0 = new nulaHandler();
nula.setOnAction(handler0);
pane.getChildren().add(jednako);
jednakoHandler handlerjednako = new jednakoHandler();
jednako.setOnAction(handlerjednako);
pane.getChildren().add(podijeljeno);
podijeljenoHandler handlerpodijeljeno = new podijeljenoHandler();
podijeljeno.setOnAction(handlerpodijeljeno);
Scene scene = new Scene(pane);
primaryStage.setTitle("Calculator");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main (String[] args) {
Application.launch(args);
}
}
class nulaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
value.set(0);
}
}
class jedinicaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("1");
}
}
class dvicaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("2");
}
}
class tricaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("3");
}
}
class cetvorkaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("4");
}
}
class peticaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("5");
}
}
class sesticaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("6");
}
}
class sedmicaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("7");
}
}
class osmicaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("8");
}
}
class devetkaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("9");
}
}
class plusHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("+");
}
}
class minusHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("-");
}
}
class putaHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("*");
}
}
class podijeljenoHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("/");
}
}
class jednakoHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("=");
}
}
class EEHandler implements EventHandler<ActionEvent>{
#Override
public void handle(ActionEvent e){
System.out.println("EE");
}
}
My handlers are just basic ones, they print the number into the console so you can disregard them, i saw some examples with the value.set commands should i go with them or ? please help deadline is in 2 weeks. Thanks a lot
I will not do the homework for you, but just a few tips:
variable-names should start with a lowercase letter (TextField rezultat, not Rezultat)
think about what exactly you expect to happen when you press the buttons:
what should your calculator do, if you press 5 '-' '+' 55. should it subtract or add 55 from 5)
do you want to calculate more than one operation? (5+5+5+5/5)
what about decimal numbers? (you can not fill them in, at your current design)
And you do nearly the same thing for every button.(or at least for 10 buttons you have the same logic)
you can create your application in a loop:
public class Calculator extends Application {
private TextField textField = new TextField();
#Override
public void start(Stage primaryStage) {
List<String> buttons = Arrays.asList("7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "0", "=", "/", "EE");
FlowPane pane = new FlowPane();
pane.setAlignment(Pos.CENTER);
pane.setPadding(new Insets(30, 20, 30, 20));
pane.setHgap(5);
pane.setVgap(5);
pane.setMinWidth(400);
pane.setPrefWidth(400);
pane.setMaxWidth(400);
textField.setEditable(false);
textField.setAlignment(Pos.CENTER);
textField.setMinSize(336, 40);
// Rezultat.textProperty().bind(Bindings.format("%.0f", value));
pane.getChildren().add(textField);
for (String button : buttons) {
Button b = new Button(button);
b.setMinSize(80, 80);
pane.getChildren().add(b);
b.setOnAction((e) -> doSomething(b.getText()));
}
Scene scene = new Scene(pane);
primaryStage.setTitle("Calculator");
primaryStage.setScene(scene);
primaryStage.show();
}
private void doSomething(String text) {
if (text.equalsIgnoreCase("=")) {
// Calc
}
else if (text.equalsIgnoreCase("EE")) {
// EE
} else if (text.equalsIgnoreCase("+") || text.equalsIgnoreCase("-") || text.equalsIgnoreCase("*") || text.equalsIgnoreCase("/")) {
// + - * /
}
// ....
else {
// numeric
textField.appendText(text);
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
public class View extends Application{
public static void main(String[] args) {
launch(args);
}
public void start(Stage primaryStage){
primaryStage.setTitle("Calculator");
GridPane root = new GridPane();
Label textBox1 = new Label("Text1");
root.add(textBox1, 0, 0, 5, 1);
Label textBox2 = new Label("Text2");
root.add(textBox2, 0, 1, 5, 1);
textBox1.setId("lblTextBox1");
textBox2.setId("lblTextBox2");
Button btn0 = new Button("0");
Button btn1 = new Button("1");
Button btn2 = new Button("2");
Button btn3 = new Button("3");
Button btn4 = new Button("4");
Button btn5 = new Button("5");
Button btn6 = new Button("6");
Button btn7 = new Button("7");
Button btn8 = new Button("8");
Button btn9 = new Button("9");
btn0.setId("btn0");
btn1.setId("btn1");
btn2.setId("btn2");
btn3.setId("btn3");
btn4.setId("btn4");
btn5.setId("btn5");
btn6.setId("btn6");
btn7.setId("btn7");
btn8.setId("btn8");
btn9.setId("btn9");
Button btnDot = new Button(".");
Button btnPlus = new Button("+");
Button btnMinus = new Button("-");
Button btnTimes = new Button("*");
Button btnDivide = new Button("/");
Button btnEquals = new Button("=");
Button btnMC = new Button("MC");
Button btnMR = new Button("MR");
Button btnMS = new Button("MS");
Button btnMPlus = new Button("M+");
Button btnMMinus = new Button("M-");
Button btnBack = new Button("<=");
Button btnCE = new Button("CE");
Button btnC = new Button("C");
Button btnPlusOrMinus = new Button("+/-");
Button btnSqrt = new Button("sqrt");
Button btnPercentage= new Button("%");
Button btn1OverX = new Button("1/x");
btnPlus.setId("btnPlus");
btnTimes.setId("btnTimes");
btnDot.setId("btnDot");
btnEquals.setId("btnEquals");
btnC.setId("btnClear");
btn0.setMaxHeight(Double.MAX_VALUE);
btn0.setMaxWidth(Double.MAX_VALUE);
btn1.setMaxHeight(Double.MAX_VALUE);
btn1.setMaxWidth(Double.MAX_VALUE);
btn2.setMaxHeight(Double.MAX_VALUE);
btn2.setMaxWidth(Double.MAX_VALUE);
btn3.setMaxHeight(Double.MAX_VALUE);
btn3.setMaxWidth(Double.MAX_VALUE);
btn4.setMaxHeight(Double.MAX_VALUE);
btn4.setMaxWidth(Double.MAX_VALUE);
btn5.setMaxHeight(Double.MAX_VALUE);
btn5.setMaxWidth(Double.MAX_VALUE);
btn6.setMaxHeight(Double.MAX_VALUE);
btn6.setMaxWidth(Double.MAX_VALUE);
btn7.setMaxHeight(Double.MAX_VALUE);
btn7.setMaxWidth(Double.MAX_VALUE);
btn8.setMaxHeight(Double.MAX_VALUE);
btn8.setMaxWidth(Double.MAX_VALUE);
btn9.setMaxHeight(Double.MAX_VALUE);
btn9.setMaxWidth(Double.MAX_VALUE);
btnEquals.setMaxHeight(Double.MAX_VALUE);
btnEquals.setMaxWidth(Double.MAX_VALUE);
btnMC.setMaxHeight(Double.MAX_VALUE);
btnMC.setMaxWidth(Double.MAX_VALUE);
btnMMinus.setMaxHeight(Double.MAX_VALUE);
btnMMinus.setMaxWidth(Double.MAX_VALUE);
btnPlusOrMinus.setMaxHeight(Double.MAX_VALUE);
btnPlusOrMinus.setMaxWidth(Double.MAX_VALUE);
btnPercentage.setMaxHeight(Double.MAX_VALUE);
btnPercentage.setMaxWidth(Double.MAX_VALUE);
btnSqrt.setMaxHeight(Double.MAX_VALUE);
btnSqrt.setMaxWidth(Double.MAX_VALUE);
btn1OverX.setMaxHeight(Double.MAX_VALUE);
btn1OverX.setMaxWidth(Double.MAX_VALUE);
btnPlus.setMaxHeight(Double.MAX_VALUE);
btnPlus.setMaxWidth(Double.MAX_VALUE);
btnMinus.setMaxHeight(Double.MAX_VALUE);
btnMinus.setMaxWidth(Double.MAX_VALUE);
btnTimes.setMaxHeight(Double.MAX_VALUE);
btnTimes.setMaxWidth(Double.MAX_VALUE);
btnDivide.setMaxHeight(Double.MAX_VALUE);
btnDivide.setMaxWidth(Double.MAX_VALUE);
btnCE.setMaxHeight(Double.MAX_VALUE);
btnCE.setMaxWidth(Double.MAX_VALUE);
btnC.setMaxHeight(Double.MAX_VALUE);
btnC.setMaxWidth(Double.MAX_VALUE);
btnDot.setMaxHeight(Double.MAX_VALUE);
btnDot.setMaxWidth(Double.MAX_VALUE);
root.add(btnMC,0,1);
root.add(btnMR,1,1);
root.add(btnMS,2,1);
root.add(btnMPlus,3,1);
root.add(btnMMinus,4,1);
root.add(btnBack,0,2);
root.add(btnCE,1,2);
root.add(btnC,2,2);
root.add(btnPlusOrMinus,3,2);
root.add(btnSqrt,4,2);
root.add(btn7,0,3);
root.add(btn8,1,3);
root.add(btn9,2,3);
root.add(btnDivide,3,3);
root.add(btnPercentage,4,3);
root.add(btn4,0,4);
root.add(btn5,1,4);
root.add(btn6,2,4);
root.add(btnTimes,3,4);
root.add(btn1OverX,4,4);
root.add(btn1,0,5);
root.add(btn2,1,5);
root.add(btn3,2,5);
root.add(btnMinus,3,5);
root.add(btnEquals,4,5,1,2);
root.add(btn0,0,6,2,1);
root.add(btnDot,2,6);
root.add(btnPlus,3,6);
root.setVgap(5);
root.setHgap(5);
root.setPadding(new Insets(5,5,5,5));
primaryStage.setScene(new Scene(root));
primaryStage.show();
Controller controller = new Controller(primaryStage.getScene());
}
}
public class Model {
SimpleDoubleProperty totalResult = new SimpleDoubleProperty(0);
SimpleDoubleProperty curNumber = new SimpleDoubleProperty(0);
SimpleStringProperty stringDisplayed = new SimpleStringProperty();
String operatorPressed = "";
Boolean isDecimal = false;
int decimalCouter = 0;
public void plusOperator(){
calculate();
operatorPressed = "+";
}
public void calculate(){
switch (operatorPressed){
case "+" :
totalResult.set(totalResult.get()+ curNumber.get());
stringDisplayed.set(stringDisplayed.get()+" + " +curNumber.get());
break;
case "*" :
totalResult.set(totalResult.get()*curNumber.get());
stringDisplayed.set(stringDisplayed.get()+" * " +curNumber.get());
break;
default:
totalResult.set(curNumber.get());
stringDisplayed.set(curNumber.get()+"");
}
curNumber.set(0);
operatorPressed = "";
isDecimal = false;
decimalCouter = 0;
}
public void multiplyOperator(){
calculate();
operatorPressed = "*";
}
public void equalsOperator(){
calculate();
curNumber.setValue(totalResult.get());
totalResult.set(0);
}
public void clearOperator(){
totalResult.setValue(0);
curNumber.setValue(0);
stringDisplayed.set("");
decimalCouter = 0;
isDecimal = false;
}
public void pressedNumber(int number){
if(!isDecimal){
curNumber.setValue(curNumber.get()*10+number);
}
else{
decimalCouter++;
Double tempCurrentNum = curNumber.get();
tempCurrentNum = tempCurrentNum*Math.pow(10,decimalCouter);
tempCurrentNum = tempCurrentNum+number;
tempCurrentNum = tempCurrentNum*Math.pow(10,-decimalCouter);
curNumber.set(tempCurrentNum);
}
}
public void dotOperator(){
isDecimal = true;
}
}
public class Controller {
Model newModel = new Model();
Controller(Scene scene){
Button btnPlus, btnTimes, btnEquals, btnClear, btnDot;
Label textBox1, textBox2;
for(int ii=0;ii<=9;ii++){
Button button = (Button)scene.lookup("#btn"+ii);
int finalIi = ii;
button.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
pressedNumber(finalIi);
}
});
}
btnPlus = (Button)scene.lookup("#btnPlus");
btnTimes = (Button)scene.lookup("#btnTimes");
btnEquals = (Button)scene.lookup("#btnEquals");
btnDot = (Button)scene.lookup("#btnDot");
btnClear = (Button)scene.lookup("#btnClear");
textBox1 = (Label)scene.lookup("#lblTextBox1");
textBox2 = (Label)scene.lookup("#lblTextBox2");
btnPlus.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
plusOperator();
}
});
btnTimes.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
multiplyOperator();
}
});
btnEquals.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
equalsOperator();
}
});
btnClear.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
clearOperator();
}
});
btnDot.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
dotOperator();
}
});
textBox1.textProperty().bind(newModel.stringDisplayed);
textBox2.textProperty().bind(newModel.curNumber.asString());
}
public void pressedNumber(int number){
newModel.pressedNumber(number);
}
public void plusOperator(){
newModel.plusOperator();
}
public void multiplyOperator(){
newModel.multiplyOperator();
}
public void equalsOperator(){
newModel.equalsOperator();
}
public void clearOperator(){
newModel.clearOperator();
}
public void dotOperator(){
newModel.dotOperator();
}
}