Java JavaFX - ein Programm und einige Fragen

SparkMonkay

Commander
Registriert
Feb. 2013
Beiträge
2.337
Moinsen,
ich habe mir aus der ULB ein Buch zu JavaFX ausgeliehen und auch mit den Tutorials von Oracle gelernt.

Sehr schöne API, ohne eine IDE währe ich da aufgeschmissen, wegen den ganzen Importen. Ist aber nicht das Thema, ich habe ein Programm geschrieben, welches insgesamt einen Textfeld hat und insgesamt 10 Felder, 0-9 halt.

Mein Ziel ist es einen kleinen Taschenrechner zu schreiben. Da soll vorerst nur Addition und Subtraktion, die anderen beiden Grundrechenarten kommen dann noch, vielleicht wird daraus sogar noch was gemacht womit ich mir nächstes Semeseter bei meinen Übungsaufgaben nervige Sachen spare, wie Konvergenz, Ableitungen, Integrale usw. mal schauen, zuerst soll da jetzige hier gescheit laufen.

Erstmals der Code und dann die Fragen ;)
Code:
package helloworld;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;


public class HelloWorld extends Application {
    int count;
    String stringCount="";
    
    @Override
    public void start(Stage primaryStage) {
        
        /*
        This is the Grid Pane
        */
        GridPane grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(5);
        grid.setVgap(5);
        grid.setPadding(new Insets(0, 1, 1, 2));
       
        /*
        Label
        */
        Label label=new Label(stringCount);
     
        /*
        The buttons
        */
        Button numbers[]=new Button[10];
     
        numbers[0]=new Button();
        numbers[0].setText("0");
        numbers[0].setOnAction((ActionEvent event) -> 
        {
    
            stringCount=stringCount+String.valueOf(0);
            label.setText(stringCount);
        });

        numbers[1]=new Button();
        numbers[1].setText("1");
        numbers[1].setOnAction((ActionEvent event) -> 
        {
            stringCount=stringCount+String.valueOf(1);
            label.setText(stringCount);
        });

        numbers[2]=new Button();
        numbers[2].setText("2");
        numbers[2].setOnAction((ActionEvent event) -> 
        {
            stringCount=stringCount+String.valueOf(2);
            label.setText(stringCount);
        });
        
        numbers[3]=new Button();
        numbers[3].setText("3");
        numbers[3].setOnAction((ActionEvent event) -> 
        {
            stringCount=stringCount+String.valueOf(3);
            label.setText(stringCount);
        });
        
        numbers[4]=new Button();
        numbers[4].setText("4");
        numbers[4].setOnAction((ActionEvent event) -> 
        {
            stringCount=stringCount+String.valueOf(4);
            label.setText(stringCount);
        });
        
        numbers[5]=new Button();
        numbers[5].setText("5");
        numbers[5].setOnAction((ActionEvent event) -> 
        {
            stringCount=stringCount+String.valueOf(5);
            label.setText(stringCount);
        });
        
        numbers[6]=new Button();
        numbers[6].setText("6");
        numbers[6].setOnAction((ActionEvent event) -> 
        {
            stringCount=stringCount+String.valueOf(6);
            label.setText(stringCount);
        });
        
        numbers[7]=new Button();
        numbers[7].setText("7");
        numbers[7].setOnAction((ActionEvent event) -> 
        {
            stringCount=stringCount+String.valueOf(7);
            label.setText(stringCount);
        });
        
        numbers[8]=new Button();
        numbers[8].setText("8");
        numbers[8].setOnAction((ActionEvent event) -> 
        {
            stringCount=stringCount+String.valueOf(8);
            label.setText(stringCount);
        });
        
        numbers[9]=new Button();
        numbers[9].setText("9");
        numbers[9].setOnAction(new EventHandler<ActionEvent>() 
        {
            @Override
            public void handle(ActionEvent event) {
                stringCount=stringCount+String.valueOf(9);
                label.setText(stringCount);
            }
        });
        
        /*
        Into the layout
        */       
        grid.add(label     , 0, 0);
        grid.add(numbers[1], 0, 1);
        grid.add(numbers[2], 1, 1);
        grid.add(numbers[3], 2, 1);
        grid.add(numbers[4], 0, 2);
        grid.add(numbers[5], 1, 2);
        grid.add(numbers[6], 2, 2);
        grid.add(numbers[7], 0, 3);
        grid.add(numbers[8], 1, 3);
        grid.add(numbers[9], 2, 3);
        grid.add(numbers[0], 1, 4);
        
        
        /*
        These here are the settings for the window.
        */
        Scene scene = new Scene(grid, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Calculator");
        primaryStage.show();

    }

    public static void main(String[] args)
    {
        launch(args);
    } 
}
Fragen:
  1. Wenn der ein oder andere den Abschnitt mit den Buttons sieht, stehen dem die Haare zu bergen. Ich habe es schon mit einer for-Schleife versucht, aber dann hat jeder Button den Wert "10" gehabt und nicht von 0 bis 9 hochgezählt....
  2. Das Textlabel wird ja breiter je mehr da Zahlen sich in dem Label befinden, bzw,je größer die Zahl ist. Ein Screenshot zeigt was ich will. ;)
    Das Bildchen zu meinem Problem:
    1.PNG
    Ich möchte einfach, das das Feld eine feste größe hat und nicht, durch eine so lange Zahl die Spaltenlücken vergrößert .
  3. Lambda Expressions. Der 10. Button ist ohne Lambda Expression, die anderen mit, NetBeans will das ich es mit mache und weist mich nett darauf hin, auf Oracle und in meine Buch ist es ohne, was jetzt?
  4. Da war was ich habe es nur vergessen...

Danke für hilfreiche Antworten ;)
 
SparkMonkay schrieb:
Wenn der ein oder andere den Abschnitt mit den Buttons sieht, stehen dem die Haare zu bergen. Ich habe es schon mit einer for-Schleife versucht, aber dann hat jeder Button den Wert "10" gehabt und nicht von 0 bis 9 hochgezählt....

Dann hast Du was falsch gemacht...

SparkMonkay schrieb:
Das Textlabel wird ja breiter je mehr da Zahlen sich in dem Label befinden, bzw,je größer die Zahl ist. Ein Screenshot zeigt was ich will.

Du musst einfach für das Label einen ColumnSpan setzen, damit es über alle drei Spalten reicht.

SparkMonkay schrieb:
Lambda Expressions. Der 10. Button ist ohne Lambda Expression, die anderen mit, NetBeans will das ich es mit mache und weist mich nett darauf hin, auf Oracle und in meine Buch ist es ohne, was jetzt?

Dein Buch wird noch nicht die Java 8-Features berücksichtigen. Nutzt man Java 8, vereinfachen btw. ermöglichen Lambda-Expressions so manches. Muss man nicht nutzen, aber wenn man kann, macht es Sinn.
 
Moin, danke für die Antworten :)

@soares
-@loop
Wahrscheinlich, finde den code abschnitt aber nirgends den ich mir extra beiseite getan habe.
-@ColumnSpan
Onkel Googel wird da helfen, danke für das Stichwort.
-@LambdaExpressions
Gut, werde mich da noch etwas einlesen und mir mein eigenes Bild davon machen.

@Grantig
ich habe mir eine Variable =0 definiert und damit eine for loop gebastelt, mit count<buttons.length, also 0<10 was äquivalent zu 0<=9 ist, aber danke für den Lesestoff, besser als Zeit mit anderen Unsinn zu verbringen ;)

@black90
-@loop
Wenn ich die finde werde ich es machen ansonsten noch einmal programmieren.
-@Stichwort
danke sehr
-@Link
Danke sehr :)

Post wird gleich nochmals editiert um die loop zu posten.

So den nicht so schönen Abschnitt mit den Buttons durch diesen hier ersetzen:

Code:
        Button numbers[]=new Button[10];
        while(count<numbers.length)
        {
        numbers[count]=new Button();
        numbers[count].setText(String.valueOf(count));
        numbers[count].setOnAction(new EventHandler<ActionEvent>() 
        {
            @Override
            public void handle(ActionEvent event) 
            {
                stringCount=stringCount+String.valueOf(String.valueOf(count));
                label.setText(stringCount);
            }
        });
        count++;
        }
und oben die variable count=0 setzen.

Das resultat: Ein Knopfdruck eine "10"...

ich experimentiere mal weiter.
 
Zuletzt bearbeitet:
Du hast meinen Link anscheinend nicht richtig gelesen, denn du machst genau den dort angesprochenen Fehler ;)

Ich hab mal deinen Code ausgebessert und kommentiert:
Code:
Button numbers[] = new Button[10];

while(count < numbers.length)
{
    // extra Variable innerhalb der Schleife deklarieren,
    // damit für jedes Closure ein eigener Kontext erstellt wird.
    int num = count;
    
    numbers[count] = new Button();
    numbers[count].setText(String.valueOf(count));
    numbers[count].setOnAction(new EventHandler<ActionEvent>()
    {
        @Override
        public void handle(ActionEvent event)
        {
            // wird erst ausgeführt, sobald du auf den Button klickst.
            // Dann ist die Schleife aber schon komplett durchgelaufen - ergo count == 10
            
            // falsch:
            // stringCount = stringCount + String.valueOf(String.valueOf(count));
            
            // richtig:
            stringCount = stringCount + String.valueOf(String.valueOf(num));
            
            label.setText(stringCount);
        }
    });
    count++;
}
Ungetestet und ich hab in Java noch nie mit Closures hantiert. Kann also sein, dass es nicht klappt.
 
Zuletzt bearbeitet: (typos)
Ok, also lag es an dem Teil, um ehrlich zu sein, habe ich nur fix, die schleife gemacht, die ich vorher hatte und ich musste danach direkt weg :s

@soares
hast du ein simples Beispiel mit dem CellSpan?
Oder muss ich das wie ich es im Internet gefunden habe nochmals neu schreiben?
 
Zuletzt bearbeitet:
Wenn es nur um das oben geschilderte Problem geht, ist das ein zusätzlicher Methodenaufruf bzw. (besser) eine kleine Änderung. Neu schreiben geht natürlich auch. Ich bin ein Freund von MigLayout.

GridPane hat mehrere Methoden, die es einem erlauben anzugeben, über welche Felder sich eine Node erstrecken soll. Das Stichwort habe ich ja bereits genannt. Schau Dir doch bitte die API-Doku an. Dort finden sich alle entsprechenden Methoden aufgeführt.
 
Ja bin ich.
http://docs.oracle.com/javafx/2/api/javafx/scene/layout/GridPane.html
dann erstmals Strg+f und nach "span" suchen.

Voila, setRowSpan(...);

Wenn ich jetzt ganz links oben (0,0) habe und sage mein Wert befindet sich bei (0/3) (3/0) aber beim GridPane sind irgendwie die Variablen vertauscht. Nvm.

Ich setzte da rein:
setRowSpan(label, 2);
aber damit ist es nicht getan. Welche Instanz des GridPanes wendet es an?
Daraus folgt: grid.setRowSpan(label, 2);

Was erwarte ich? Das jetzt mein Label 2 Reihen breit ist.
Nöp, ich versuche es mit der Colum variante, siehe da:
Unbenannt.PNG

Danke ;)

Jetzt kommt + und - damit will ich aber selber zurecht kommen :D
 
Zuletzt bearbeitet:
Grantig schrieb:
Ungetestet und ich hab in Java noch nie mit Closures hantiert. Kann also sein, dass es nicht klappt.

Klappt nicht mit Java 7 (da fehlt ein final). Mit Java 8 geht es. Dein Beispiel verwendet allerdings keine Closure. Damit geht das ganze dann etwas kürzer:

Code:
for (int i = 0; i < buttons.length; i++)
{
    String number = String.valueOf(i);
    buttons[i] = new Button(number);
    buttons[i].setOnAction(event -> {
        input.appendText(number);
    });
}
Ergänzung ()

SparkMonkay schrieb:
Was erwarte ich? Das jetzt mein Label 2 Reihen breit ist.

Seltsame Erwartungshaltung ;) Jede Methode ist doch ausführlich erklärt. Rows steht für Zeilen, nicht für Spalten. Ich würde allerdings keine extra Methode verwenden, sondern einfach

Code:
 grid.add(label, 0, 0, 3, 1);

Du hast übrigens immer noch das Problem, dass es die Buttons verschiebt, wenn die Eingabe größer wird. Ich würde anstatt ein Label ein TextField verwenden.
 
Zuletzt bearbeitet:
ok, danke sehr, werde mich weiter ran machen!
 
@Grantig
Ich muss mich da teilweise korrigieren. Mit Java 8 ist kein final notwendig. Mit Java 7 (oder früher) benötigt man ein final.
 
Zurück
Oben