Letní akce! Lákají tě IT školení C#, Javy a PHP v Brně? Přihlas se a napiš nám do zpráv kód "BRNO 500" pro slevu 500 Kč na libovolný brněnský kurz. Lze kombinovat se slevami uvedenými u školení i použít pro více kurzů. Akce končí 28.7.

JavaFX 2 quickstart: Události a CSS

Java JavaFX JavaFX 2 quickstart: Události a CSS

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Zdrojové kódy budu, tak jako v předchozím díle, z důvodu úspory místa uvádět bez importů. Všechny zde uvedené kódy si můžete stáhnout v přiloženém zipu.

Event (událost)

Událost vzniká určitou akcí (činností) jako například pohybem myši, stiskem tlačítka či klávesy (KeyEvent – stiskem klávesy na klávesnici, MouseEvent – pohybem myši nebo stiskem tlačítka na myši,...). Událost (event) je objekt, který má v sobě všechny informace, týkající se dané události (jaký je to typ události, kde událost vznikla, kdo ji vyvolal, …).

Uzel (node) si může zaregistrovat ovladač (handler), který bude zavolán v případě, že vznikne určitá událost. Handler pak v metodě handle() definuje, co se má stát.

public class YesNo extends Application {
        private Button yesBT, noBT;
        private final int PANE_WIDTH = 400;
        private final int PANE_HEIGHT = 200;

        @Override
        public void start(Stage stage) {
                try {
                        BorderPane rootPane = new BorderPane();         // vytvoření BorderPane rozvržení, tento uzel bude root node scene grafu
                        rootPane.setPadding(new Insets(20));
                        Font font = Font.font("Verdana", FontWeight.BOLD, 20);

                        VBox topPane = new VBox();                                      // vytvoření VBox rozvržení (do něj vložíme Label)
                        topPane.setAlignment(Pos.CENTER);                               // nastavení zarovnání obsahu VBox na střed
                        Label questionLB = new Label("Líbí se vám tento tutoriál?");        // vytvoření nového štítku
                        questionLB.setFont(font);                                       // nastavení písma textu na štítku
                        topPane.getChildren().add(questionLB);

                        VBox bottomPane = new VBox();
                        bottomPane.setAlignment(Pos.CENTER);
                        final Label responseLB = new Label();
                        responseLB.setFont(font);
                        bottomPane.getChildren().add(responseLB);

                        rootPane.setTop(topPane);               // do horní části BorderPane rozvržení vloží VBox rozvržení se štítkem
                        rootPane.setBottom(bottomPane);         // totéž pro dolní část BorderPane rozvržení


                        yesBT = new Button("Ano");              // vytvoří nové tlačítko s popiskem
                        yesBT.setFont(font);                    // nastaví písmo pro popisek tlačítka
                        noBT = new Button("Ne");
                        noBT.setFont(font);

                        GridPane centerPane = new GridPane();                   // vytvoří GridPane rozvržení
                        centerPane.setPrefSize(PANE_WIDTH, PANE_HEIGHT);        // nastaví požadovanou velikost pro rozvržení GridPane
                        centerPane.add(yesBT, 0, 0);                            // umístí tlačítko yesBT na pozici sloupec (x) = 0, řada (y) = 0 v rozvržení GridPane
                        centerPane.add(noBT, 1, 0);                             // umístí tlačítko noBT na pozici x = 1, y = 0
                        centerPane.setHgap(30);                                 // nastaví vodorovnou mezeru mezi komponentami
                        centerPane.setAlignment(Pos.CENTER);                    // nastaví zarovnání obsahu GridPane rozvržení na střed
                        rootPane.setCenter(centerPane);                         // vloží GridPane rozvržení do centrální části BorderPane rozvržení


                        // tlačítko yesBT si zaregistruje ovladač (handler), který bude reagovat na událost kliknutí na tlačítko
                        yesBT.setOnAction(new EventHandler<ActionEvent>() {

                                @Override
                                // metoda, ve které je určeno, co se v případě zavolání handleru má provést
                                public void handle(ActionEvent event) {
                                        responseLB.setText("Díky, pochvala potěší.");               // nastaví text štítku
                                }

                        });

                        // tlačítko si registruje ovladač, který bude reagovat na událost, kdy kurzor najede na tlačítko
                        yesBT.setOnMouseEntered(new EventHandler<MouseEvent>() {

                                @Override
                                public void handle(MouseEvent event) {
                                        yesBT.setScaleX(1.5);           // nastavuje měřítko, dle kterého se bude měnit velikost komponenty podél osy x
                                        yesBT.setScaleY(1.5);           // totéž pro osu y
                                }

                        });

                        // tlačítko si registruje ovladač, který bude reagovat na událost, kdy kurzor opustí tlačítko
                        yesBT.setOnMouseExited(new EventHandler<MouseEvent>() {

                                @Override
                                public void handle(MouseEvent event) {
                                        yesBT.setScaleX(1);                     // velikost dle osy x se vrátí k původnímu rozměru
                                        yesBT.setScaleY(1);                     // totéž pro osu y
                                }

                        });

                        noBT.setOnMouseEntered(new EventHandler<MouseEvent>() {

                                @Override
                                public void handle(MouseEvent event) {
                                        Random gen = new Random();
                                        int x = gen.nextInt((int)(PANE_WIDTH - noBT.getWidth()));               // generuje náhodné číslo pro x (v rozsahu šířky GridPane)
                                        int y = gen.nextInt((int)(PANE_HEIGHT - noBT.getHeight()));             // totéž pro y (v rozsahu výšky GridPane)
                                        noBT.setLayoutX(x);                                                                                             // nové umístění tlačítka (pozice na ose x)
                                        noBT.setLayoutY(y);                                                                                             // totéž pro osu y
                                }
                        });

                        noBT.setOnAction(new EventHandler<ActionEvent>() {

                                @Override
                                public void handle(ActionEvent event) {
                                        noBT.setVisible(false);
                                }

                        });

                        Scene scene = new Scene(rootPane);
                        stage.setScene(scene);
                        stage.setTitle("YesNo");
                        stage.show();
                } catch(Exception e) {
                        e.printStackTrace();
                }
        }

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

Kaskádové styly (CSS)

Kód, který slouží jen pro stylování vzhledu aplikace a pro její funkčnost není nezbytný, lze vypustit a celé stylování lze provést pomocí kaskádových stylů. Pokud máte nějaké zkušenosti s tvorbou HTML stránek, určitě vám to zní povědomě.

Styl aplikace lze nadefinovat pomocí kaskádových stylů v samostatném souboru a tento soubor umístit do adresáře, kde se nachází náš .java soubor. V .java souboru pak stačí říci, v jakém souboru se styly nacházejí.

Uzly jako například Label, Button, … již automaticky patří do tříd (.label, .button). Všem uzlům je možné přidat třídu i id a ty následně pomocí CSS stylovat. Stylování je hierarchické. To znamená, že styl rodičovského uzlu se vztahuje i na jeho potomky a potomky potomků. V potomkovi se styl dá předefinovat a má vyšší prioritu (přebije styl rodiče).

Jako příklad si vezmeme předchozí aplikaci, jejíž vzhled ale nyní budeme definovat pomocí CSS.

.java soubor

public class YesNoCSS extends Application {
        private Button yesBT, noBT;
        private final int PANE_WIDTH = 400;
        private final int PANE_HEIGHT = 200;

        @Override
        public void start(Stage stage) {
                try {
                        BorderPane rootPane = new BorderPane();
                        rootPane.setId("rootPane");                                     // nastaví id tomuto uzlu

                        VBox topPane = new VBox();
                        topPane.getStyleClass().add("vBox");                            // nastaví třídu (class) tomuto uzlu
                        Label questionLB = new Label("Líbí se vám tento tutoriál?");
                        topPane.getChildren().add(questionLB);

                        VBox bottomPane = new VBox();
                        bottomPane.getStyleClass().add("vBox");
                        final Label responseLB = new Label();
                        bottomPane.getChildren().add(responseLB);

                        rootPane.setTop(topPane);
                        rootPane.setBottom(bottomPane);

                        yesBT = new Button("Ano");
                        noBT = new Button("Ne");

                        GridPane centerPane = new GridPane();
                        centerPane.setId("centerPane");
                        centerPane.setPrefSize(PANE_WIDTH, PANE_HEIGHT);
                        centerPane.add(yesBT, 0, 0);
                        centerPane.add(noBT, 1, 0);
                        rootPane.setCenter(centerPane);


                        /*
                         * Kód metod zůstává stejný.
                         */

                        Scene scene = new Scene(rootPane);
                        scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());      // nastaví scene styl
                        stage.setScene(scene);
                        stage.setTitle("YesNoCSS");
                        stage.show();
                } catch(Exception e) {
                        e.printStackTrace();
                }
        }

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

.css soubor

/* námi definované id rootPane */
#rootPane {
        -fx-font-size: 20pt;
        -fx-font-family: "Verdana";
        -fx-font-weight: bold;
        -fx-padding: 20;
}

/* námi definované id centerPane */
#centerPane {
        -fx-hgap: 30;
        -fx-alignment: center;
}

/* class (třída), kterou mají všechny štítky */
 .label {
        -fx-text-fill: black;
        -fx-alignment: center;
        -fx-text-alignment: center;
}

/* námi definovaná třída */
.vBox {
        -fx-alignment: center;
}

Vzhledově se nic nezměnilo a náš kód je nyní lépe čitelný. CSS umožňují použití i tzv. pseudo-tříd (např. hover, která se aplikuje, pokud je nad daným uzlem kurzor myši). Pomocí pseudo-třídy hover, můžeme nahradit i kód metod yesBT.setOnMou­seEntered() a yesBT.setOnMou­seExited(). Příklad naleznete v přiloženém zipu v balíčku applicationCSS02.

A to je vše. Doufám, že se vám tento krátký tutoriál líbil, a že jste se něco nového naučili. Pokud vás JavaFX zaujala, doporučuji se podívat na zdroje uvedené ke konci každého dílu tohoto tutoriálu.

Zdroje:


 

Stáhnout

Staženo 247x (5.6 kB)
Aplikace je včetně zdrojových kódů v jazyce java

 

 

Článek pro vás napsal vita
Avatar
Jak se ti líbí článek?
7 hlasů
vita
Miniatura
Všechny články v sekci
Okenní aplikace v Java FX
Miniatura
Následující článek
Zdrojákoviště Java - JavaFX
Aktivity (1)

 

 

Komentáře

Avatar
Pavel Vosyka
Člen
Avatar
Pavel Vosyka:7.10.2015 15:35

Jsou tady i media queries a dají se tak dělat responzivní aplikace, podobně jako weby?

Odpovědět 7.10.2015 15:35
"nikdy nepiš nic 2x"
Avatar
Odpovídá na Pavel Vosyka
Petr Štechmüller:7.10.2015 16:07

Ahoj, media queries tu nejsou. Dale tu nejsou žádné věci z CSS3 + nějaké pseudotridy z CSS 2.1. Ale responzivni aplikace se dají dělat, melo by stačit používat správný layouty...

Odpovědět 7.10.2015 16:07
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Pavel Vosyka
Člen
Avatar
Odpovídá na Petr Štechmüller
Pavel Vosyka:9.10.2015 12:57

Aha, aha. Díky :-)

Odpovědět 9.10.2015 12:57
"nikdy nepiš nic 2x"
Avatar
Pavol Franek
Člen
Avatar
Pavol Franek:16.11.2017 20:07

Ahoj, síce to v texte nepíšeš ale predpokladám že podľa metódy noBT.setOnMou­seEntered sa malo tlačidlo pohybovať vždy keď naň prejdeš myšou ale to ti nefunguje.

Podľa všetkého to nefunguje v BorderPane ale len v klasickom Pane.
Ak by niekomu pomohlo ja som to vyriešil takto.

public void start(Stage primaryStage)
    {
        try
        {
            Font font = Font.font("Verdena", FontWeight.BOLD, 20);      //vytvorenie instancie pre typ pisma

            BorderPane rootPane = new BorderPane();                     //vytvorenie BorderPane rozvrhnutia, tento uzol bude root node sceny grafu
            rootPane.setPadding(new Insets(20));                        //nastavenie medzeri medzi komponentami

            VBox topPane = new VBox();                                  //vytovrenie VBox rozvrhnutia
            topPane.setAlignment(Pos.CENTER);                           //nastavenie zarovnania obsahu VBox na stred
            Label questionLB = new Label();                             //vytvorenie labelu bez textu
            questionLB.setText("Páči sa Vám tento tutorial?");          //nastavenie textu labelu
            questionLB.setFont(font);                                   //nastavenie fontu pre label
            topPane.getChildren().add(questionLB);                      //priadnie labelu do rozvrhnutia

            VBox bottomPane = new VBox();                               //vytovrenie VBox rozvrhnutia
            bottomPane.setAlignment(Pos.CENTER);                        //nastavenie zarovnania obsahu
            final Label responseLB = new Label();                       //vytvorenie labelu bez textu
            responseLB.setFont(font);                                   //nastavenie fontu pre label
            bottomPane.getChildren().add(responseLB);                   //priadnie labelu do rozvrhnutia

            rootPane.setTop(topPane);                                   //vlozenie do Top casti BorderPane rozvrhnutia VBox so stitkom
            rootPane.setBottom(bottomPane);                             //vlozenie do Bottom casti BorderPane rozvrhnutia VBox so stitkom

            yesBT = new Button("Ano");                                  //vytvorenie noveho tlacidla s popiskom
            yesBT.setFont(font);                                        //nastavenie fontu pre tlacidlo
            noBT = new Button("Nie");                                   //vytvorenie noveho tlacidla s popiskom
            noBT.setFont(font);                                         //nastavenie fontu pre tlacidlo
            noBT.setLayoutX(120);                                       //nastavenie prvej X pozicie tlacidal
            noBT.setLayoutY(77);                                        //nastavenie prvej Y pozicie tlacidal

            GridPane centerPane = new GridPane();                       //vytvorenie GridPane rozvrhnutiia

            centerPane.setPrefSize(PANE_WIDTH, PANE_WIDTH);             //nastavenie pozadovanej velkosti rozvrhnutia pre GridPane
            centerPane.add(yesBT, 0, 0);                                //umiestnenie tlacidla na poziciu stlpca (x) = 0, riadku (y) = 0 v rozvrhnutia GridPane

            Pane btPane = new Pane();                                   //vytvorenie Pane rozvrhnutia
            btPane.setPrefHeight(BT_PANE_HIGHT);                        //nastavenie preferovanej velkosti
            btPane.setPrefWidth(BT_PANE_WIDTH);                         //nastavenie preferovanej velkosti
            btPane.getChildren().add(noBT);                             //priadeni tlacdla do Pain
            centerPane.add(btPane, 1, 0);                               //umiestnenie Pane na poziciu stlpca (x) = 1, riadku (y) = 0 v rozvrhnutia GridPane
            centerPane.setHgap(30);                                     //nastavenie vodorovnej medzeri medzi komponentami
            centerPane.setAlignment(Pos.CENTER);                        //nastavenie zarovnania obsahu GridPane na stred

            rootPane.setCenter(centerPane);

            //tlacidlo yesBT si zaregistruje ovladac(handler), ktorý bude reagovat na udalost - kliknutie na tlacidlo
            yesBT.setOnAction(new EventHandler<ActionEvent>()
            {
                //metoda, v ktroej je urcene, co sa vykona v priapde zavolania handleru
                @Override
                public void handle(ActionEvent event)
                {
                    responseLB.setText("Ďakujem, pochvala poteší.");
                }
            }
            );

            //tlacidlo yesBT si registruje ovladac(handler), ktorý bude reagovat na udalost - kurzor prejde na tlacidlo
            yesBT.setOnMouseEntered(new EventHandler<MouseEvent>()
            {
                //metoda, v ktorej je urcena co sa vykona v pripade zavolania handleru
                @Override
                public void handle(MouseEvent event)
                {
                    yesBT.setScaleX(1.5);                               //nastavuje meradlo, podla ktoreho sa bude velkost komponentu menit pozdlz osy x
                    yesBT.setScaleY(1.5);                               //nastavuje meradlo, podla ktoreho sa bude velkost komponentu menit pozdlz osy y
                }
            }
            );

            //tlacidlo yesBT si registruje ovladac(handler), ktorý bude reagovat na udalost - kurzor opusti tlacidlo
            yesBT.setOnMouseExited(new EventHandler<MouseEvent>()
            {
                //metoda, v ktorej je urcena co sa vykona v pripade zavolania handleru
                @Override
                public void handle(MouseEvent event)
                {
                    yesBT.setScaleX(1);                                 //nastavuje meradlo, podla ktoreho sa bude velkost komponentu menit pozdlz osy x
                    yesBT.setScaleY(1);                                 //nastavuje meradlo, podla ktoreho sa bude velkost komponentu menit pozdlz osy y
                }
            }
            );

            //tlacidlo yesBT si registruje ovladac(handler), ktorý bude reagovat na udalost - kurzor prejde na tlacidlo
            noBT.setOnMouseEntered(new EventHandler<MouseEvent>()
            {
                //metoda, v ktorej je urcena co sa vykona v pripade zavolania handleru
                @Override
                public void handle(MouseEvent event)
                {
                    Random rand = new Random();
                    //generuje nahodne cisla pri x (v rozsahu sirky GridPane)
                    int x = rand.nextInt((int) (BT_PANE_WIDTH - noBT.getWidth()));
                    //generuje nahodne cisla pri y (v rozsahu sirky GridPane)
                    int y = rand.nextInt((int) (BT_PANE_HIGHT - noBT.getHeight()));
                    noBT.setLayoutX(x);                                 //nastavuje meradlo, podla ktoreho sa bude velkost komponentu menit pozdlz osy x
                    noBT.setLayoutY(y);                                 //nastavuje meradlo, podla ktoreho sa bude velkost komponentu menit pozdlz osy y
                }
            }
            );

            //tlacidlo noBT si zaregistruje ovladac(handler), ktorý bude reagovat na udalost - kliknutie na tlacidlo
            noBT.setOnAction(new EventHandler<ActionEvent>()
            {
                //metoda, v ktroej je urcene, co sa vykona v priapde zavolania handleru
                @Override
                public void handle(ActionEvent event)
                {
                    noBT.setVisible(false);                             //schovane tlacidla
                }
            }
            );

            Scene scene = new Scene(rootPane);

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
 
Odpovědět 16.11.2017 20:07
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 4 zpráv z 4.