package jp.ac.aiit.jointry;
import java.util.Locale;
import javafx.animation.Animation;
import javafx.animation.FadeTransition;
import javafx.animation.ParallelTransition;
import javafx.animation.ScaleTransition;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextInputControl;
import javafx.scene.text.Font;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javafx.util.Duration;
import jp.ac.aiit.jointry.controllers.MainController;
import jp.ac.aiit.jointry.services.broker.app.JointryDialogBase;
import org.comtel.javafx.control.KeyBoardPopup;
import org.comtel.javafx.control.KeyBoardPopupBuilder;
import org.comtel.javafx.robot.RobotFactory;
public class JointryMain extends Application {
private KeyBoardPopup popup;
private boolean enableKeyboard = true;
@Override
public void start(Stage stage) throws Exception {
final FXMLLoader loader;
loader = new FXMLLoader(getClass().getResource("controllers/Main.fxml"));
Parent parent = (Parent) loader.load();
final MainController controller = loader.getController();
JointryDialogBase.install(controller);
controller.initWindow("new");
stage.setOnHidden(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent t) {
controller.windowClose();
Platform.exit();
}
});
controller.setJointryMain(this);
Scene scene = new Scene(parent);
stage.setScene(scene);
setupKeyboard(stage);
popup.show(stage);
stage.show();
}
private void setupKeyboard(Stage stage) {
// appearance setting
String fontUrl = this.getClass().getResource("/font/FontKeyboardFX.ttf").toExternalForm();
Font f = Font.loadFont(fontUrl, -1);
String css = this.getClass().getResource("/css/KeyboardButtonStyle.css").toExternalForm();
stage.getScene().getStylesheets().add(css);
// initialize
popup = KeyBoardPopupBuilder.create().initScale(1.0).initLocale(Locale.ENGLISH).addIRobot(RobotFactory.createFXRobot()).build();
// add keyboard scene listener to all text components
stage.getScene().focusOwnerProperty().addListener(new ChangeListener<Node>() {
@Override
public void changed(ObservableValue<? extends Node> value, Node n1, Node n2) {
if (n2 != null && n2 instanceof TextInputControl) {
setPopupVisible(true, (TextInputControl) n2);
} else {
setPopupVisible(false, null);
}
}
});
popup.getKeyBoard().setOnKeyboardCloseButton(new EventHandler<Event>() {
public void handle(Event event) {
setPopupVisible(false, null);
}
});
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
private void setPopupVisible(final boolean b, final TextInputControl textNode) {
if (!isEnableKeyboard()) {
return;
}
Platform.runLater(new Runnable() {
private Animation fadeAnimation;
@Override
public void run() {
if (b) {
if (textNode != null) {
Rectangle2D textNodeBounds = new Rectangle2D(textNode.getScene().getWindow().getX()
+ textNode.getLocalToSceneTransform().getTx(), textNode.getScene().getWindow().getY()
+ textNode.getLocalToSceneTransform().getTy(), textNode.getWidth(), textNode
.getHeight());
Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
if (textNodeBounds.getMinX() + popup.getWidth() > screenBounds.getMaxX()) {
popup.setX(screenBounds.getMaxX() - popup.getWidth());
} else {
popup.setX(textNodeBounds.getMinX());
}
if (textNodeBounds.getMaxY() + popup.getHeight() > screenBounds.getMaxY()) {
popup.setY(textNodeBounds.getMinY() - popup.getHeight() + 20);
} else {
popup.setY(textNodeBounds.getMaxY() + 40);
}
}
}
if (fadeAnimation != null) {
fadeAnimation.stop();
}
if (!b) {
popup.hide();
return;
}
if (popup.isShowing()) {
return;
}
popup.getKeyBoard().setOpacity(0.0);
FadeTransition fade = new FadeTransition(Duration.seconds(.5), popup.getKeyBoard());
fade.setToValue(b ? 1.0 : 0.0);
fade.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
fadeAnimation = null;
}
});
ScaleTransition scale = new ScaleTransition(Duration.seconds(.5), popup.getKeyBoard());
scale.setToX(b ? 1 : 0.8);
scale.setToY(b ? 1 : 0.8);
ParallelTransition tx = new ParallelTransition(fade, scale);
fadeAnimation = tx;
tx.play();
if (b) {
if (!popup.isShowing()) {
popup.show(popup.getOwnerWindow());
}
}
}
});
}
/**
* @return the enableKeyboard
*/
public boolean isEnableKeyboard() {
return enableKeyboard;
}
/**
* @param enableKeyboard the enableKeyboard to set
*/
public void setEnableKeyboard(boolean enableKeyboard) {
this.enableKeyboard = enableKeyboard;
}
}