.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
#Wed Apr 19 14:36:46 CEST 2023
|
||||
gradle.version=7.4.1
|
Binary file not shown.
17
bac1/q2/algo/tp7/ExempleFX/.project
Normal file
17
bac1/q2/algo/tp7/ExempleFX/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ExempleFX</name>
|
||||
<comment>Project ExempleFX created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -0,0 +1,13 @@
|
||||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=/usr/lib/jvm/java-19-openjdk
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=true
|
||||
show.console.view=true
|
||||
show.executions.view=true
|
25
bac1/q2/algo/tp7/ExempleFX/build.gradle
Normal file
25
bac1/q2/algo/tp7/ExempleFX/build.gradle
Normal file
@ -0,0 +1,25 @@
|
||||
plugins {
|
||||
id 'application'
|
||||
id 'org.openjfx.javafxplugin' version '0.0.9'
|
||||
}
|
||||
|
||||
compileJava.options.encoding = "UTF-8"
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
}
|
||||
|
||||
application {
|
||||
// C'est le nom de la classe principale (contenant la méthode main). On
|
||||
// doit donner les packages s'il y en a. Ici, Main est dans le package
|
||||
// exemplefx.
|
||||
mainClass = 'exemplefx.Main'
|
||||
}
|
||||
|
||||
javafx {
|
||||
version = "11"
|
||||
modules = [ 'javafx.controls' ]
|
||||
}
|
Binary file not shown.
BIN
bac1/q2/algo/tp7/ExempleFX/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
bac1/q2/algo/tp7/ExempleFX/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
bac1/q2/algo/tp7/ExempleFX/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
bac1/q2/algo/tp7/ExempleFX/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
234
bac1/q2/algo/tp7/ExempleFX/gradlew
vendored
Executable file
234
bac1/q2/algo/tp7/ExempleFX/gradlew
vendored
Executable file
@ -0,0 +1,234 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
89
bac1/q2/algo/tp7/ExempleFX/gradlew.bat
vendored
Normal file
89
bac1/q2/algo/tp7/ExempleFX/gradlew.bat
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
260
bac1/q2/algo/tp7/ExempleFX/src/main/java/exemplefx/Main.java
Normal file
260
bac1/q2/algo/tp7/ExempleFX/src/main/java/exemplefx/Main.java
Normal file
@ -0,0 +1,260 @@
|
||||
package exemplefx;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
// La classe principale pour javafx doit hériter de Application.
|
||||
//
|
||||
// L'objectif de ce programme est d'afficher une forme (cercle ou carré) que
|
||||
// l'on pourra déplacer via des boutons. Commencez par exécuter le code pour
|
||||
// voir ce que ça fait.
|
||||
//
|
||||
// Pour ce faire, ouvrez un terminal dans le dossier contenant le fichier
|
||||
// build.gradle et entrez la commande "gradle run" (sans les guillemets)
|
||||
//
|
||||
// Si vous n'avez pas installé gradle, remplacez gradle dans la commande par
|
||||
// .\gradlew.bat si vous êtes sous windows et ./gradlew si vous êtes sous mac
|
||||
// ou linux.
|
||||
public class Main extends Application {
|
||||
|
||||
private CheckBox drawSquare;
|
||||
private CheckBox blink;
|
||||
private Button up;
|
||||
private Button down;
|
||||
private MonCanvas canvas;
|
||||
private TextField size;
|
||||
private TextField increment;
|
||||
private Timer blinkTimer;
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Méthode statique de Application pour lancer le programme
|
||||
launch(args);
|
||||
}
|
||||
|
||||
// Méthode appelée quand on initialise la fenêtre. C'est à partir de là
|
||||
// qu'on va ajouter les boutons et autres.
|
||||
// Stage représente la fenêtre.
|
||||
public void start(Stage stage) {
|
||||
// Il s'agit d'un layout. Un layout est un objet auquel on va ajouter
|
||||
// des éléments (boutons, texte, ...) et qui va gérer comment les
|
||||
// placer sur la fenêtre.
|
||||
// Le BorderPane découpe la zone en cinq : haut, bas, gauche, droite et
|
||||
// centre. Il permet de placer des éléments sur les bords tout en
|
||||
// gardant un maximum de place pour le centre où on peut mettre le
|
||||
// principal. Par exemple, dans un éditeur de texte, on peut avoir les
|
||||
// boutons au dessus et le texte prend la place restante au centre.
|
||||
BorderPane root = new BorderPane();
|
||||
|
||||
// On crée deux boutons
|
||||
up = new Button("Haut");
|
||||
down = new Button("Bas");
|
||||
|
||||
// Une VBox est un autre exemple de layout. Elle va placer les éléments
|
||||
// de haut en bas dans l'ordre où on les ajoute. Pour un placement de
|
||||
// gauche à droite, on utilise une HBox.
|
||||
VBox buttons = new VBox();
|
||||
// On ajoute le bouton up en l'ajoutant aux "enfants" de la VBox. Les
|
||||
// enfants d'un élément sont ceux qui se trouvent à l'intérieur.
|
||||
buttons.getChildren().add(up);
|
||||
buttons.getChildren().add(down);
|
||||
// On peut aussi demander à la VBox de centrer ses composants.
|
||||
buttons.setAlignment(Pos.CENTER);
|
||||
|
||||
// Ici, on place la VBox dans la partie gauche du BorderPane. Cela veut
|
||||
// dire que le BorderPane va juste placer tous les éléments de la VBox
|
||||
// dans la partie gauche de la fenêtre mais c'est la VBox qui va
|
||||
// choisir comment les placer dans cette partie gauche. Ici, de haut en
|
||||
// bas car c'est le principe d'une VBox.
|
||||
root.setLeft(buttons);
|
||||
|
||||
// On crée une check box avec le texte donné.
|
||||
drawSquare = new CheckBox("Dessiner un carré");
|
||||
blink = new CheckBox("Clignoter");
|
||||
|
||||
HBox checks = new HBox(drawSquare, blink);
|
||||
checks.setAlignment(Pos.CENTER);
|
||||
// On place la check box en haut du BorderPane et donc en haut de la
|
||||
// fenêtre comme le BorderPane sera le contenu principal de la fenêtre.
|
||||
root.setTop(checks);
|
||||
|
||||
// Un GridPane est un layout qui place ses éléments sous forme de
|
||||
// grille. On peut y ajouter chaque élément dans une certaine ligne et
|
||||
// une certaine colonne.
|
||||
GridPane texts = new GridPane();
|
||||
// On crée un Label qui correspond à un simple texte. Ce Label sera
|
||||
// placé dans la ligne 0 et la colonne 0 du GridPane. C'est à dire,
|
||||
// dans la case en haut à gauche.
|
||||
texts.add(new Label("Taille de la forme (rayon) :"), 0, 0);
|
||||
// Un TextField permet d'entrer du texte.
|
||||
size = new TextField();
|
||||
// On place le TextField pour la taille de la forme dans la première
|
||||
// ligne et dans la deuxième colonne du GridPane.
|
||||
texts.add(size, 1, 0);
|
||||
texts.add(new Label("Distance du déplacement :"), 0, 1);
|
||||
increment = new TextField();
|
||||
texts.add(increment, 1, 1);
|
||||
texts.setAlignment(Pos.CENTER);
|
||||
|
||||
root.setBottom(texts);
|
||||
|
||||
// On crée un canvas personnalisé (voir MonCanvas.java)
|
||||
canvas = new MonCanvas(800, 600);
|
||||
// Le canvas pourra utiliser toute la place restante au centre. Mais
|
||||
// comme les canvas de JavaFX ont une taille fixe, il ne changera pas
|
||||
// de taille si on change la taille de la fenêtre. Pour cela, il
|
||||
// faudrait modifier notre canvas.
|
||||
root.setCenter(canvas);
|
||||
|
||||
// La scène représente ce qui sera affiché dans la fenêtre.
|
||||
// Une scène à besoin d'un layout. C'est pour ça qu'on lui donne root
|
||||
// qui sera le layout principal.
|
||||
Scene scene = new Scene(root);
|
||||
|
||||
// On configure la scène à afficher.
|
||||
stage.setScene(scene);
|
||||
|
||||
// Cette méthode définie plus bas va configurer tous les éléments qui
|
||||
// doivent réagir à certains évènements. Par exemple, que faire quand
|
||||
// on clique sur un bouton.
|
||||
this.confHandlers(stage);
|
||||
|
||||
// On configure le titre de la fenêtre
|
||||
stage.setTitle("Ma fenêtre");
|
||||
|
||||
// En général, c'est la dernière instruction de start. On dit à javafx
|
||||
// d'afficher la fenêtre (sinon elle ne sera pas visible).
|
||||
stage.show();
|
||||
}
|
||||
|
||||
private void confHandlers(Stage stage) {
|
||||
// Dans une interface graphique, on utilise de la programmation
|
||||
// évènementielle. C'est à dire qu'on va exécuter certaines fonctions
|
||||
// quand un évènement particulier se produit. Par exemple, cliquer sur
|
||||
// un bouton. Le code à exécuter est donné par un objet appelé le
|
||||
// "handler". Une sous-classe de EventHandler pour JavaFX.
|
||||
// Ci-dessous, on crée une classe anonyme qui sera sous-classe de
|
||||
// EventHandler pour les KeyEvent (pour le clavier). Sa méthode handle
|
||||
// va faire monter ou descendre la forme du canvas selon la touche
|
||||
// enfoncée. La syntaxe <KeyEvent> veut juste dire qu'on ne gère que
|
||||
// les KeyEvent. Donc que les touches du clavier et pas, par exemple,
|
||||
// la souris.
|
||||
EventHandler keyhandler = new EventHandler<KeyEvent>() {
|
||||
public void handle(KeyEvent evt) {
|
||||
// Le code est celui de la touche utilisée. Ceux-ci sont
|
||||
// contenus dans la classe KeyCode. KeyCode.UP est le code pour
|
||||
// la flèche du haut.
|
||||
KeyCode code = evt.getCode();
|
||||
if (code == KeyCode.UP) {
|
||||
// Si on a appuyé sur la flèche du haut, on fait monter la
|
||||
// forme dans le canvas.
|
||||
canvas.up();
|
||||
} else if (code == KeyCode.DOWN) {
|
||||
canvas.down();
|
||||
}
|
||||
}
|
||||
};
|
||||
// On ajoute le handler à la fenêtre. On précise bien qu'on ne
|
||||
// s'intéresse que aux évènements KEY_PRESSED qui correspondent à une
|
||||
// touche qui a été enfoncée. Par opposition, KEY_RELEASED correspond à
|
||||
// une touche qui a été relachée.
|
||||
stage.addEventFilter(KeyEvent.KEY_PRESSED, keyhandler);
|
||||
|
||||
// Les handlers peuvent aussi être donnés via une expression lambda. La
|
||||
// fonction doit prendre un évèment en paramètre. Comme ici, up est un
|
||||
// bouton, les détails de l'évènement ne nous intéresse pas car il
|
||||
// s'agit juste d'un clic sur le bouton.
|
||||
//this.up.setOnAction(evt -> this.canvas.up());
|
||||
this.up.setOnAction(evt -> this.canvas.up());
|
||||
this.down.setOnAction(evt -> this.canvas.down());
|
||||
|
||||
// On remarque ici qu'on prend une propriété (selectedProperty). Il
|
||||
// s'agit d'un attribut particulier sur lequel on peut ajouter des
|
||||
// handlers pour gérer les cas où la valeur change. Ici, la propriété
|
||||
// "selected" indique si la checkbox est cochée ou pas.
|
||||
// On ajoute un listener qui est une forme de handler qui gère les cas
|
||||
// où des valeurs changent. On reçoit trois paramètres : l'objet
|
||||
// lui-même (la checkbox), la valeur avant le changement et la valeur
|
||||
// après. Avant et après sont des booléens ici (voir documentation de
|
||||
// CheckBox).
|
||||
this.drawSquare.selectedProperty().addListener(
|
||||
(box, avant, apres) -> {
|
||||
// On n'a pas besoin de la valeur précédente. Juste de la
|
||||
// nouvelle valeur indiquant si la case est cochée (true)
|
||||
// ou pas (false).
|
||||
this.canvas.setDrawSquare(apres);
|
||||
}
|
||||
);
|
||||
// Comme ci-dessus, on ajoute un handler pour mettre à jour la taille
|
||||
// de la forme quand on change la valeur dans le TextField. Sans
|
||||
// surprise, avant et apres sont des String.
|
||||
this.size.textProperty().addListener(
|
||||
(field, avant, apres) -> {
|
||||
try {
|
||||
this.canvas.setSize(Double.parseDouble(apres));
|
||||
} catch (NumberFormatException e) {
|
||||
// Ici, on ignore le problème.
|
||||
// On pourrait afficher un message d'erreur dans une
|
||||
// vraie application ou utiliser une pop-up.
|
||||
}
|
||||
}
|
||||
);
|
||||
this.increment.textProperty().addListener(
|
||||
(observable, avant, apres) -> {
|
||||
try {
|
||||
this.canvas.setIncrement(Double.parseDouble(apres));
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Pour activer ou désactiver le clignotement, on utilise un Timer. La
|
||||
// checkbox blink va donc soit activer le timer toutes les 2 secondes,
|
||||
// soit le désactiver selon qu'elle soit cochée ou pas.
|
||||
this.blinkTimer = new Timer();
|
||||
this.blink.selectedProperty().addListener(
|
||||
(observable, avant, apres) -> {
|
||||
if (!apres) {
|
||||
// Si on vient de décocher blink, on arrête le timer et
|
||||
// on en crée un nouveau qui ne sera pas lancé.
|
||||
blinkTimer.cancel();
|
||||
blinkTimer = new Timer();
|
||||
} else {
|
||||
// Si on vient de cocher blink, on lance le timer après
|
||||
// 2 secondes (2000 ms) et à intervalles de 2 secondes.
|
||||
blinkTimer.scheduleAtFixedRate(new BlinkingTask(canvas), 0, 2000);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Dernier handler, si on ferme la fenêtre, on arrête le timer.
|
||||
stage.setOnCloseRequest(evt -> this.blinkTimer.cancel());
|
||||
}
|
||||
|
||||
private class BlinkingTask extends TimerTask {
|
||||
private MonCanvas canvas;
|
||||
|
||||
public BlinkingTask(MonCanvas c) {
|
||||
this.canvas = c;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
this.canvas.toggleRed();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
package exemplefx;
|
||||
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
// Un canvas est un élément d'interface graphique qui permet de dessiner. Nous
|
||||
// créons ici notre propre canvas pour lui ajouter des fonctionnalités
|
||||
// spécifiques. On voudra pouvoir dessiner une forme spécifique à des un
|
||||
// endroit spécifique. Cette forme sera centrée en x mais pourra monter ou
|
||||
// descendre.
|
||||
public class MonCanvas extends Canvas {
|
||||
|
||||
// Coordonnée y de la forme.
|
||||
private double y;
|
||||
// Si drawSquare est vrai, on dessine un carré. Sinon, on dessine un
|
||||
// cercle.
|
||||
private boolean drawSquare;
|
||||
// De combien de pixels ont va déplacer la forme dans les méthodes up et
|
||||
// down.
|
||||
private double increment;
|
||||
// Rayon de la forme.
|
||||
private double size;
|
||||
// Si vrai, on dessine la forme en rouge. Sinon, en bleu.
|
||||
private boolean red;
|
||||
|
||||
public MonCanvas(double width, double height) {
|
||||
super(width, height);
|
||||
// La fonction reset permet de tout remettre à zéro. Mais elle sert
|
||||
// aussi à initialiser. On pourrait imaginer ajouter un bouton reset
|
||||
// dans l'interface. Voyez-vous comment ?
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
this.y = getHeight() / 2;
|
||||
this.drawSquare = false;
|
||||
this.increment = 10;
|
||||
this.size = 100;
|
||||
this.red = false;
|
||||
// Quand on a tout initialisé, on dessine.
|
||||
draw();
|
||||
}
|
||||
|
||||
public void setIncrement(double inc) {
|
||||
this.increment = inc;
|
||||
}
|
||||
|
||||
public void setDrawSquare(boolean drawsq) {
|
||||
this.drawSquare = drawsq;
|
||||
// A chaque fois qu'on change un paramètre, on va redessiner la forme
|
||||
// avec ces changements. On voit ici un exemple où les méthodes set
|
||||
// sont importantes. Ce comportement de redessiner automatiquement ne
|
||||
// serait pas possible si drawSquare était publique.
|
||||
draw();
|
||||
}
|
||||
|
||||
public void setSize(double s) {
|
||||
this.size = s;
|
||||
draw();
|
||||
}
|
||||
|
||||
public void toggleRed() {
|
||||
this.red = !red;
|
||||
draw();
|
||||
}
|
||||
|
||||
public void up() {
|
||||
// Dans un canvas, l'axe y est inversé. Le point (0,0) est en haut à
|
||||
// gauche va vers le bas. Le point en bas à droite sera donc (width,
|
||||
// height) avec width et height la largeur et la hauteur du canvas
|
||||
// respectivement. Pour dessiner la forme plus haut, on va donc
|
||||
// diminuer la valeur y.
|
||||
this.y -= this.increment;
|
||||
draw();
|
||||
}
|
||||
|
||||
public void down() {
|
||||
this.y += this.increment;
|
||||
draw();
|
||||
}
|
||||
|
||||
// Cette méthode va dessiner la forme avec tous les paramètres.
|
||||
private void draw() {
|
||||
// On ne peut pas utiliser directement les attributs width et height de
|
||||
// Canvas car elles sont privées et donc pas accessibles dans notre
|
||||
// sous-classe. On doit donc utiliser getWidth et getHeight.
|
||||
double width = this.getWidth();
|
||||
double height = this.getHeight();
|
||||
// xc est la coordonnée x correspondant au centre du canvas.
|
||||
double xc = width / 2;
|
||||
// Un GraphicsContext est un objet qui permet de dessiner sur un
|
||||
// Canvas. Il possède beaucoup de méthodes spécifiques comme strokeLine
|
||||
// pour dessiner une ligne.
|
||||
GraphicsContext gc = this.getGraphicsContext2D();
|
||||
// La méthode clearRect fonctionne comme une gomme. Il efface tous les
|
||||
// dessins se trouvant à l'intérieur. Sans cela, les dessins
|
||||
// précédents restent affichés. Essayez de commenter cette ligne pour
|
||||
// voir ce que ça donne.
|
||||
gc.clearRect(0, 0, width, height);
|
||||
// On va dessiner un rectangle pour bien voir les limites du canvas.
|
||||
// Vous verrez que sa taille reste constante.
|
||||
gc.strokeRect(1, 1, width-2, height-2);
|
||||
// Selon la valeur de red, on choisis la couleur à utiliser. La méthode
|
||||
// setFill configure la couleur pour le remplissage (l'intérieur des
|
||||
// formes). Pour choisir la couleur des lignes, on utilise setStroke.
|
||||
if (red) {
|
||||
gc.setFill(Color.RED);
|
||||
} else {
|
||||
gc.setFill(Color.BLUE);
|
||||
}
|
||||
// Si vrai, on dessine un carré. Pour cela, la méthode fillRect dessine
|
||||
// un carré et le colore avec la couleur configurée ci-dessus. Sinon,
|
||||
// on dessine un cercle avec fillOval.
|
||||
if (this.drawSquare) {
|
||||
gc.fillRect(xc-size, y-size, 2*size, 2*size);
|
||||
} else {
|
||||
gc.fillOval(xc-size, y-size, 2*size, 2*size);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user