Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

CSS et JavaFx : un développeur affirme pouvoir reproduire l'UI de tous les OS
Un défi pour montrer le potentiel de ces technologies

Le , par la.lune

0PARTAGES

5  1 
Des gens demandaient à Jasper Potts (Architecte Développeur pour JavaFX) s'il était possible de recréer le look de tel ou tel OS avec JavaFX 2.x. Certains, persuadés qu'il ne pourrait pas, lui ont même lancé un défi.

Il a donc décidé de le relever.

La clef de sa méthode repose sur les feuilles de styles (CSS) qui permettent de personnaliser les boutons de JavaFX.

Résultat, des UI d'iPad, d'iPhone, de Windows 7, ou d'Android sans utiliser la moindre image (un design faisable également sans CSS et rien qu'en code Java avec les API JavaFX 2.x).

La meilleure méthode reste cependant les feuilles de style qui séparent le contenu et le rendu graphique. Et qui sont plus simple à coder qu'avec du Java.



Dans le détail, Jasper Potts explique qu'il utilise les gradients du CSS. Un bouton d'UI aura un air de Windows 7 si on lui applique par exemple la feuille de style suivante :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
#windows7-default {
    -fx-background-color:
        #3c7fb1,
        linear-gradient(#fafdfe, #e8f5fc),
        linear-gradient(#eaf6fd 0%, #d9f0fc 49%, #bee6fd 50%, #a7d9f5 100%);
    -fx-background-insets: 0,1,2;
    -fx-background-radius: 3,2,1;
    -fx-padding: 3 30 3 30;
    -fx-text-fill: black;
    -fx-font-size: 14px;
}
Défi réussi ?

Le projet Netbeans "ButtonStyles.zip" est disponible en téléchargement libre

Source : Billet de Jasper Potts

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de sinok
Expert éminent sénior https://www.developpez.com
Le 22/12/2011 à 13:52
Citation Envoyé par huit_six Voir le message
Du coup, je comprend pas trop quel est le lien avec JavaFX, si c'est du CSS ?
C'est pas un troll hein ! c'est une vrai question vu que je connais pas javafx !
JavaFX permet le theming de ses composants via des feuilles de style CSS, comme d'autres API le permettent (genre Qt & cie).
2  0 
Avatar de la.lune
Membre chevronné https://www.developpez.com
Le 21/12/2011 à 16:22
En utilisant le patern Build fournit aussi dans l'api JavaFX 2.x ,facile et rapide ,il a coder l'application comme suit:

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
 
package buttonstyles;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.SceneBuilder;
import javafx.scene.control.ButtonBuilder;
import javafx.scene.control.ToolBarBuilder;
import javafx.scene.layout.BorderPaneBuilder;
import javafx.scene.layout.VBoxBuilder;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 * @author Jasper
 */
public class ButtonStyles extends Application {

    public static void main(String[] args) { launch(args); }
    
    @Override public void start(Stage primaryStage) {
        primaryStage.setTitle("JavaFX CSS Buttons");
        primaryStage.setScene(SceneBuilder.create()             
            .stylesheets(ButtonStyles.class.getResource("Buttons.css").toExternalForm())
            .fill(Color.gray(0.9))
            .root(
                BorderPaneBuilder.create()
                    .left(
                        VBoxBuilder.create()
                            .spacing(10)
                            .padding(new Insets(20))
                            .alignment(Pos.CENTER)
                            .children(
                                ButtonBuilder.create().text("Green").id("green").build(),
                                ButtonBuilder.create().text("Round Red").id("round-red").build(),
                                ButtonBuilder.create().text("Bevel Grey").id("bevel-grey").build(),
                                ButtonBuilder.create().text("Glass Grey").id("glass-grey").build(),
                                ButtonBuilder.create().text("Shiny Orange").id("shiny-orange").build(),
                                ButtonBuilder.create().text("DARK BLUE").id("dark-blue").build(),
                                ButtonBuilder.create().text("Record Sales").id("record-sales").build(),
                                ButtonBuilder.create().text("Rich Blue").id("rich-blue").build(),
                                ButtonBuilder.create().text("Big Yellow").id("big-yellow").build(),
                                ToolBarBuilder.create()
                                    .id("iphone-toolbar")
                                    .items(
                                        ButtonBuilder.create().text("iPhone").id("iphone").build()
                                    )
                                    .build(),
                                ButtonBuilder.create().text("Large iPad Dark Grey").id("ipad-dark-grey").build(),
                                ButtonBuilder.create().text("Large iPad Grey").id("ipad-grey").build(),
                                ButtonBuilder.create().text("OSX Lion (Default)").id("lion-default").build(),
                                ButtonBuilder.create().text("OSX Lion").id("lion").build(),
                                ButtonBuilder.create().text("Windows 7 (Default)").id("windows7-default").build(),
                                ButtonBuilder.create().text("Windows 7").id("windows7").build()
                            )
                            .build()
                    )
                    .center(
                        VBoxBuilder.create()
                            .spacing(10)
                            .padding(new Insets(20))
                            .alignment(Pos.CENTER)
                            .style("-fx-background-color: #373737;")
                            .children(
                                ButtonBuilder.create().text("Green").id("green").build(),
                                ButtonBuilder.create().text("Round Red").id("round-red").build(),
                                ButtonBuilder.create().text("Bevel Grey").id("bevel-grey").build(),
                                ButtonBuilder.create().text("Glass Grey").id("glass-grey").build(),
                                ButtonBuilder.create().text("Shiny Orange").id("shiny-orange").build(),
                                ButtonBuilder.create().text("DARK BLUE").id("dark-blue").build(),
                                ButtonBuilder.create().text("Record Sales").id("record-sales").build(),
                                ButtonBuilder.create().text("Rich Blue").id("rich-blue").build(),
                                ButtonBuilder.create().text("Big Yellow").id("big-yellow").build(),
                                ToolBarBuilder.create()
                                    .id("iphone-toolbar")
                                    .items(
                                        ButtonBuilder.create().text("iPhone").id("iphone").build()
                                    )
                                    .build(),
                                ButtonBuilder.create().text("Large iPad Dark Grey").id("ipad-dark-grey").build(),
                                ButtonBuilder.create().text("Large iPad Grey").id("ipad-grey").build(),
                                ButtonBuilder.create().text("OSX Lion (Default)").id("lion-default").build(),
                                ButtonBuilder.create().text("OSX Lion").id("lion").build(),
                                ButtonBuilder.create().text("Windows 7 (Default)").id("windows7-default").build(),
                                ButtonBuilder.create().text("Windows 7").id("windows7").build()
                            )
                            .build()
                    )
                .build()
            )
            .build());
        primaryStage.show();
    }
}
A noter qu'ici il s'est suffit de l'id du contrôle pour le référencer dans les feuilles de style,mais il est possible d'utiliser les class
Code : Sélectionner tout
buton0.setStylClass(String)
. De plus il est possible d’intégrer directement le style en appelant la méthode du contrôle comme ça:

Code : Sélectionner tout
button1.setStyle("-fx-font: 22 arial; -fx-base: #b6e7c9;");
Vous trouverez un bon document mais en anglais qui explique comment créer et gérer les contrôles,leurs effets et styles,effets 3D.ici
1  0 
Avatar de tchize_
Expert éminent sénior https://www.developpez.com
Le 22/12/2011 à 13:31
Autant java fx 1.0 était imbuvable, autant le faite que javafx2 interagisse avec du code java sauve un peu le miche. Et il faut le reconnaitre. aujourd'hui, c'est la seul api "officielle" de oracle foutue de fournir des interfaces graphique présentables

Bon après, pour le moment coté interface graphique, je préfère encore apache pivot, mais qui sait, avec java 8, ....
1  0 
Avatar de bouye
Rédacteur/Modérateur https://www.developpez.com
Le 01/01/2012 à 0:10
Sort la tête de ses vacances sans programmation...

Ah donc ils a continué sur ce sujet. Qqun lui avait posé la question lors de la session "Meet the Java & JavaFX Experience Team" car il était dans l'audience en tant que guest spectator (même si au final plus de 50% des questions lui ont été posée à lui au lieu des speakers) et il indiquait effectivement que le CSS était une bonne voie pour avoir un LnF natif. Ce à quoi on avait rétorqué que ça serait bien qu'Oracle fournisse ces CSS de la même manière qu'ils fournissent déjà des LnF natifs pour Swing.

Une question similaire avait été postée lors de la première présentation de Jim Weaver et aussi lors d'une autre session ; il semblait qu'un frein majeur pour la pénétration de FX en entreprise fusse le fait que Caspian est trop différent du LnF système.

L'ennuie avec le CSS est que de nos jours la plupart des LnF sont animés (boutons qui pulsent etc.), hors les CSS de FX ne supportent pas les animations (pour le moment).

Concernant Swing, oui on peut faire des jolis truc mais par défaut il faut presque recoder tous les composants (ou du moins toutes leurs UI). Ou utiliser Substance, chose que Kiril a mis des années et des années à developper. Là, en JavaFX ,c'est beaucoup plus rapide, faut juste modifier le CSS et relancer le programme.

Retourne profiter de ses derniers jours de vacances.
Ah oui et bonne année au fait !
1  0 
Avatar de la.lune
Membre chevronné https://www.developpez.com
Le 21/12/2011 à 15:41
Voici le code du fichier CSS très simple à intégrer dans une sceneGraph JavaFX
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#green {
    -fx-background-color:
        linear-gradient(#f0ff35, #a9ff00),
        radial-gradient(center 50% -40%, radius 200%, #b8ee36 45%, #80c800 50%);
    -fx-background-radius: 6, 5;
    -fx-background-insets: 0, 1;
    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
    -fx-text-fill: #395306;
}
#round-red {
    -fx-background-color: linear-gradient(#ff5400, #be1d00);
    -fx-background-radius: 30;
    -fx-background-insets: 0;
    -fx-text-fill: white;
}
#bevel-grey {
    -fx-background-color:
        linear-gradient(#f2f2f2, #d6d6d6),
        linear-gradient(#fcfcfc 0%, #d9d9d9 20%, #d6d6d6 100%),
        linear-gradient(#dddddd 0%, #f6f6f6 50%);
    -fx-background-radius: 8,7,6;
    -fx-background-insets: 0,1,2;
    -fx-text-fill: black;
    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );
}
#glass-grey {
    -fx-background-color:
        #c3c4c4,
        linear-gradient(#d6d6d6 50%, white 100%),
        radial-gradient(center 50% -40%, radius 200%, #e6e6e6 45%, rgba(230,230,230,0) 50%);
    -fx-background-radius: 30;
    -fx-background-insets: 0,1,1;
    -fx-text-fill: black;
    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 3, 0.0 , 0 , 1 );
}
#shiny-orange {
    -fx-background-color:
        linear-gradient(#ffd65b, #e68400),
        linear-gradient(#ffef84, #f2ba44),
        linear-gradient(#ffea6a, #efaa22),
        linear-gradient(#ffe657 0%, #f8c202 50%, #eea10b 100%),
        linear-gradient(from 0% 0% to 15% 50%, rgba(255,255,255,0.9), rgba(255,255,255,0));
    -fx-background-radius: 30;
    -fx-background-insets: 0,1,2,3,0;
    -fx-text-fill: #654b00;
    -fx-font-weight: bold;
    -fx-font-size: 14px;
    -fx-padding: 10 20 10 20;
}
#dark-blue {
    -fx-background-color:
        #090a0c,
        linear-gradient(#38424b 0%, #1f2429 20%, #191d22 100%),
        linear-gradient(#20262b, #191d22),
        radial-gradient(center 50% 0%, radius 100%, rgba(114,131,148,0.9), rgba(255,255,255,0));
    -fx-background-radius: 5,4,3,5;
    -fx-background-insets: 0,1,2,0;
    -fx-text-fill: white;
    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );
    -fx-font-family: "Arial";
    -fx-text-fill: linear-gradient(white, #d0d0d0);
    -fx-font-size: 12px;
    -fx-padding: 10 20 10 20;
}
#dark-blue Text {
    -fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.9) , 1, 0.0 , 0 , 1 );
}
#record-sales {
    -fx-padding: 8 15 15 15;
    -fx-background-insets: 0,0 0 5 0, 0 0 6 0, 0 0 7 0;
    -fx-background-radius: 8;
    -fx-background-color:
        linear-gradient(from 0% 93% to 0% 100%, #a34313 0%, #903b12 100%),
        #9d4024,
        #d86e3a,
        radial-gradient(center 50% 50%, radius 100%, #d86e3a, #c54e2c);
    -fx-effect: dropshadow( gaussian , rgba(0,0,0,0.75) , 4,0,0,1 );
    -fx-font-weight: bold;
    -fx-font-size: 1.1em;
}
#record-sales:hover {
    -fx-background-color:
        linear-gradient(from 0% 93% to 0% 100%, #a34313 0%, #903b12 100%),
        #9d4024,
        #d86e3a,
        radial-gradient(center 50% 50%, radius 100%, #ea7f4b, #c54e2c);
}
#record-sales:pressed {
    -fx-padding: 10 15 13 15;
    -fx-background-insets: 2 0 0 0,2 0 3 0, 2 0 4 0, 2 0 5 0;
}
#record-sales Text {
    -fx-fill: white;
    -fx-effect: dropshadow( gaussian , #a30000 , 0,0,0,2 );
}
#rich-blue {
    -fx-background-color:
        #000000,
        linear-gradient(#7ebcea, #2f4b8f),
        linear-gradient(#426ab7, #263e75),
        linear-gradient(#395cab, #223768);
    -fx-background-insets: 0,1,2,3;
    -fx-background-radius: 3,2,2,2;
    -fx-padding: 12 30 12 30;
    -fx-text-fill: white;
    -fx-font-size: 12px;
}
#rich-blue Text {
    -fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.8) , 0, 0.0 , 0 , 1);
}
#big-yellow {
    -fx-background-color:
        #ecebe9,
        rgba(0,0,0,0.05),
        linear-gradient(#dcca8a, #c7a740),
        linear-gradient(#f9f2d6 0%, #f4e5bc 20%, #e6c75d 80%, #e2c045 100%),
        linear-gradient(#f6ebbe, #e6c34d);
    -fx-background-insets: 0,9 9 8 9,9,10,11;
    -fx-background-radius: 50;
    -fx-padding: 15 30 15 30;
    -fx-font-family: "Helvetica";
    -fx-font-size: 18px;
    -fx-text-fill: #311c09;
    -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.1) , 2, 0.0 , 0 , 1);
}
#big-yellow Text {
    -fx-effect: dropshadow( one-pass-box , rgba(255,255,255,0.5) , 0, 0.0 , 0 , 1);
}
#iphone-toolbar {
    -fx-background-color: linear-gradient(#98a8bd 0%, #8195af 25%, #6d86a4 100%);
}
#iphone {
    -fx-background-color:
        #a6b5c9,
        linear-gradient(#303842 0%, #3e5577 20%, #375074 100%),
        linear-gradient(#768aa5 0%, #849cbb 5%, #5877a2 50%, #486a9a 51%, #4a6c9b 100%);
    -fx-background-insets: 0 0 -1 0,0,1;
    -fx-background-radius: 5,5,4;
    -fx-padding: 7 30 7 30;
    -fx-text-fill: #242d35;
    -fx-font-family: "Helvetica";
    -fx-font-size: 12px;
    -fx-text-fill: white;
}
#iphone Text {
    -fx-effect: dropshadow( one-pass-box , rgba(0,0,0,0.8) , 0, 0.0 , 0 , -1 );
}
#ipad-dark-grey {
    -fx-background-color:
        linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
        linear-gradient(#020b02, #3a3a3a),
        linear-gradient(#9d9e9d 0%, #6b6a6b 20%, #343534 80%, #242424 100%),
        linear-gradient(#8a8a8a 0%, #6b6a6b 20%, #343534 80%, #262626 100%),
        linear-gradient(#777777 0%, #606060 50%, #505250 51%, #2a2b2a 100%);
    -fx-background-insets: 0,1,4,5,6;
    -fx-background-radius: 9,8,5,4,3;
    -fx-padding: 15 30 15 30;
    -fx-font-family: "Helvetica";
    -fx-font-size: 18px;
    -fx-font-weight: bold;
    -fx-text-fill: white;
    -fx-effect: dropshadow( three-pass-box , rgba(255,255,255,0.2) , 1, 0.0 , 0 , 1);
}
#ipad-dark-grey Text {
    -fx-effect: dropshadow( one-pass-box , black , 0, 0.0 , 0 , -1 );
}
#ipad-grey {
    -fx-background-color:
        linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
        linear-gradient(#020b02, #3a3a3a),
        linear-gradient(#b9b9b9 0%, #c2c2c2 20%, #afafaf 80%, #c8c8c8 100%),
        linear-gradient(#f5f5f5 0%, #dbdbdb 50%, #cacaca 51%, #d7d7d7 100%);
    -fx-background-insets: 0,1,4,5;
    -fx-background-radius: 9,8,5,4;
    -fx-padding: 15 30 15 30;
    -fx-font-family: "Helvetica";
    -fx-font-size: 18px;
    -fx-font-weight: bold;
    -fx-text-fill: #333333;
    -fx-effect: dropshadow( three-pass-box , rgba(255,255,255,0.2) , 1, 0.0 , 0 , 1);
}
#ipad-grey Text {
    -fx-effect: dropshadow( one-pass-box , white , 0, 0.0 , 0 , 1 );
}
#lion-default {
    -fx-background-color:
        rgba(0,0,0,0.08),
        linear-gradient(#5a61af, #51536d),
        linear-gradient(#e4fbff 0%,#cee6fb 10%, #a5d3fb 50%, #88c6fb 51%, #d5faff 100%);
    -fx-background-insets: 0 0 -1 0,0,1;
    -fx-background-radius: 5,5,4;
    -fx-padding: 3 30 3 30;
    -fx-text-fill: #242d35;
    -fx-font-size: 14px;
}
#lion {
    -fx-background-color:
        rgba(0,0,0,0.08),
        linear-gradient(#9a9a9a, #909090),
        linear-gradient(white 0%, #f3f3f3 50%, #ececec 51%, #f2f2f2 100%);
    -fx-background-insets: 0 0 -1 0,0,1;
    -fx-background-radius: 5,5,4;
    -fx-padding: 3 30 3 30;
    -fx-text-fill: #242d35;
    -fx-font-size: 14px;
}
#windows7-default {
    -fx-background-color:
        #3c7fb1,
        linear-gradient(#fafdfe, #e8f5fc),
        linear-gradient(#eaf6fd 0%, #d9f0fc 49%, #bee6fd 50%, #a7d9f5 100%);
    -fx-background-insets: 0,1,2;
    -fx-background-radius: 3,2,1;
    -fx-padding: 3 30 3 30;
    -fx-text-fill: black;
    -fx-font-size: 14px;
}
#windows7 {
    -fx-background-color:
        #707070,
        linear-gradient(#fcfcfc, #f3f3f3),
        linear-gradient(#f2f2f2 0%, #ebebeb 49%, #dddddd 50%, #cfcfcf 100%);
    -fx-background-insets: 0,1,2;
    -fx-background-radius: 3,2,1;
    -fx-padding: 3 30 3 30;
    -fx-text-fill: black;
    -fx-font-size: 14px;
}
0  0 
Avatar de huit_six
Membre actif https://www.developpez.com
Le 22/12/2011 à 13:44
Du coup, je comprend pas trop quel est le lien avec JavaFX, si c'est du CSS ?
C'est pas un troll hein ! c'est une vrai question vu que je connais pas javafx !
0  0 
Avatar de la.lune
Membre chevronné https://www.developpez.com
Le 22/12/2011 à 15:10
Citation Envoyé par huit_six Voir le message

C'est pas un troll hein !
Et bien ce n'est pas un troll dans le moment où on t'a donné le code source, la source de l'info et un lien pour télécharger le projet Netbeans .Donc si tu télécharges La 2e mise à jour du JDK 7: JDK 7u2. Le SDK de JavaFX 2.0.2 est inclut et s’installe automatiquement après installation du JDK.Tu pourra voir toi même le résultat.

A présent une version de la version 2.1 est disponible pour Windows et Mac Os
Téléchargez JavaFX 2.1 b06
0  0 
Avatar de la.lune
Membre chevronné https://www.developpez.com
Le 24/12/2011 à 20:01
Citation Envoyé par tchize_ Voir le message
Et il faut le reconnaitre. aujourd'hui, c'est la seul api "officielle" de oracle foutue de fournir des interfaces graphique présentables
Mais on peut faire du présentable avec Swing non? Et oui regarde un peu ça!





C'est du Swing mon ami, et bien tu peux trouver ce thème agréable sans le site java.net par ici
0  0 
Avatar de tchize_
Expert éminent sénior https://www.developpez.com
Le 24/12/2011 à 20:55
Je parlais surtout du niveau binding entre les éléments, l'aspect dynamique des interfaces etc. Swing, même avec un beau toolkit, ça reste swing avec sa complexité et ses limitations.
0  0 
Avatar de la.lune
Membre chevronné https://www.developpez.com
Le 24/12/2011 à 21:46
Citation Envoyé par tchize_ Voir le message
Je parlais surtout du niveau binding entre les éléments, l'aspect dynamique des interfaces etc. Swing, même avec un beau toolkit, ça reste swing avec sa complexité et ses limitations.
Je confirme! Tout reste que JavaFX gère bien tout ce que tu viens de mentionner et plus!
0  0 
Contacter le responsable de la rubrique Accueil

Partenaire : Hébergement Web