0

In my Example I am trying to make a counter;

It starts with 0 and everytime i click the button it must be increase one more.

I add a PREFIX and than my increaseNumber() method have to function but it doesn't work.

Did I create my EventHandler false?

Here are my classes:

import java.util.Observable;

public class Number extends Observable {
    int number = 0;

    public int getZahl() {
        return number;
    }

    public void setZahl(int number) {
        this.number = number;
    }

    public void increaseTheNumber() {
        int oldNumber = number;
        number++;
        setChanged();
        notifyObservers(oldNumber);
    }

    public String toString() {
        return number + " ";
    }
}
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class NumberGUI extends Application {

    private Button btn;
    private Label lbl;
    private Label lbl2;
    private Number num;
    private static String PREFIX = "The new number is: ";

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void init() throws Exception {
        num = new Number();
        initButton();
        initLabels();

    }

    private void initButton() {
        btn = new Button();
        btn.setText("Click to Increase");
        btn.setPrefHeight(50);
        btn.setPrefWidth(200);
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent arg0) {
                num.increaseTheNumber();
            }
        });

    }

    private void initLabels() {
        lbl2=new Label(PREFIX+num.getZahl());

    }

    private Parent createSceneGraph() { 
        BorderPane root = new BorderPane();
        root.setCenter(lbl);
        root.setBottom(lbl2);
        GridPane grid = new GridPane();
        grid.addColumn(0,btn);
        root.setCenter(grid);
        return root;
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Counter!");       
        primaryStage.setScene(new Scene(createSceneGraph(),300,250));
        primaryStage.show();

    }

}
public class Main {
    public static void main(String[] args) {
        Number num = new Number();
        ObserveNumber on = new ObserveNumber();
        num.addObserver(on);
        num.increaseTheNumber();
    }

}
fabian
  • 80,457
  • 12
  • 86
  • 114
  • 1
    Why reinvent the wheel? JavaFX already has observable properties: there is no need to use `Observer` and `Observable`. Just make `num` an `IntegerProperty` and then you can bind the label's text to it directly. See http://www.oracle.com/pls/topic/lookup?ctx=javase80&id=JFXBD107 – James_D Jan 24 '17 at 17:59
  • I must do like this :( –  Jan 24 '17 at 18:07

2 Answers2

1

If you print your stored number every time you invoke increaseTheNumber method you will see that the number is indeed being increased.

public void increaseTheNumber() {
    int oldNumber = number;
    number++;
    setChanged();
    notifyObservers(oldNumber);
    System.out.println(number);
}

Your label doesn't change because you set its content only once, when the number is still zero.

lbl2=new Label(PREFIX+num.getZahl());

Since your Number is an observable, you can add an Observer to it that will update the label every time it's been notified.

num.addObserver((o, arg) -> {
    lbl2.setText(PREFIX+num.getZahl());
});
Dth
  • 1,916
  • 3
  • 23
  • 34
  • Hello, Thank you very much but i tried it and its still not working. and when i write; `num.addObserver((o, arg) -> { lbl2.setText(PREFIX+num.getZahl()); });` I get hell of a Exceptions @Dth –  Jan 24 '17 at 18:04
  • What kind of exceptions? Do you use Java 8? Have you put it in the `init()` method? I actually compiled it and it works as expected. – Dth Jan 24 '17 at 18:19
  • I get this Exception: Exception in thread "JavaFX Application Thread" java.lang.NullPointerException at...at.. very long I am adding this to `num.addObserver((o, arg) -> { lbl2.setText(PREFIX+num.getZahl()); });` initLabels() And yes I am using java 8 –  Jan 24 '17 at 18:52
  • Oh, I guess you've removed the `lbl2=new Label(PREFIX+num.getZahl());` line? It was actually necessary to initialize the `Label`, but this alone won't keep updating it with new values. Bring it back and it will work. If not, then the `num = new Number();` must be missing for some reason. – Dth Jan 24 '17 at 19:07
1

This becomes much easier, if you use JavaFX properties, like IntegerProperty, since this allows you to simply bind the text property:

@Override
public void start(Stage primaryStage) {
    Label label = new Label();
    IntegerProperty property = new SimpleIntegerProperty(1);
    Button btn = new Button("Increment");
    btn.setOnAction((ActionEvent event) -> {
        // increment the property
        property.set(property.get()+1);
    });

    // format the property by prepending the prefix string
    label.textProperty().bind(property.asString("The new number is: %d"));

    Scene scene = new Scene(new VBox(label, btn));

    primaryStage.setScene(scene);
    primaryStage.show();
}
fabian
  • 80,457
  • 12
  • 86
  • 114