I have an equations program that I'm working on, which randomly selects one of 50 equations, then takes the user through a series of scenes in order to solve it. Once the user solves the equation, they're asked if they want another equation. If they answer no, the program closes. If they answer yes, the program is supposed to randomly select another equation, then take them through the scenes to solve that one.
The program works just as I want it to the first time through. However, if the user selects "yes" for another equation, the program displays the END of the first scene, showing them the previous problem that they've already solved.
How can I send the user to the beginning of the scene, so that a new equation is randomly selected?
Here’s the relevant code for Scene 1:
package Equations;
import java.util.Random;
import javafx.application.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.text.Text;
import javafx.scene.control.*;
import javafx.event.*;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
public class equationsapp extends Application
implements EventHandler<ActionEvent> {
public static void main(String[] args) {
launch(args);
}
#Override public void start(Stage primaryStage) {
stage = primaryStage;
Random eqrdmzr = new Random();
int randomNumber = eqrdmzr.nextInt(3) + 1;
if (randomNumber == 1) {
isolCounterCoeff = 2;
isolVrblb = new Label("+");
isolCounter1a = 7;
isolCounter2a = 17;
slvCoeff = 2;
slvEqVrblTerm = new Text("2n");
slvEqWhlNmbrInt = 10;
slvEqWhlNmbr = new Text("10");
}
if(randomNumber == 2) {
isolCounterCoeff = 2;
isolVrblb = new Label("+");
isolVrblb.setVisible(false);
isolCounter1a = -18;
isolCounter2a = 4;
slvCoeff = 2;
slvEqVrblTerm = new Text("2n");
slvEqWhlNmbrInt = 22;
slvEqWhlNmbr = new Text("22");
}
if(randomNumber == 3) {
isolCounterCoeff = 3;
isolVrblb = new Label("+");
isolVrblb.setVisible(false);
isolCounter1a = -5;
isolCounter2a = 19;
slvCoeff = 3;
slvEqVrblTerm = new Text("3n");
slvEqWhlNmbrInt = 24;
slvEqWhlNmbr = new Text("24");
}
//Build Scene 1 - Top BorderPane
Text isolText = new Text("Isolate the Variable Term");
isolText.setStyle("-fx-font-size: 16pt");
//Build Scene 1 - Center BorderPane
Label isolCoeff = new Label();
isolCoeff.setStyle("-fx-font-size: 24pt;");
isolCoeff.setText(Integer.toString(isolCounterCoeff));
Label isolVrbl = new Label("n");
isolVrbl.setStyle("-fx-font-size: 24pt;");
isolVrblb.setStyle("-fx-font-size: 24pt;");
isolVrblb.managedProperty().bind(isolVrblb.visibleProperty());
Label isolEqIntLeft = new Label();
isolEqIntLeft.setStyle("-fx-font-size: 24pt;");
isolEqIntLeft.setPadding(new Insets(0, 10, 0, 0));
isolEqIntLeft.setText(Integer.toString(isolCounter1a));
isolEqIntLeft.managedProperty().bind(isolEqIntLeft.visibleProperty());
Label isolEqualSign = new Label("=");
isolEqualSign.setStyle("-fx-font-size: 24pt;");
Label isolEqIntRight = new Label();
isolEqIntRight.setStyle("-fx-font-size: 24pt;");
isolEqIntRight.setPadding(new Insets(0, 0, 0, 10));
isolEqIntRight.setText(Integer.toString(isolCounter2a));
//Build Scene 1 - Bottom BorderPane
Label isolLbl1 = new Label();
isolLbl1.setStyle("-fx-font-size: 22pt;");
isolEqIntLeft.setText(Integer.toString(isolCounter1a));
isolLbl1.setText(Integer.toString(isolCounter1b));
//Create GridPanes and Fill Them
GridPane isolGridPane1 = new GridPane();
isolGridPane1.setAlignment(Pos.CENTER);
isolGridPane1.add(isolText, 0, 0);
GridPane isolGridPane2 = new GridPane();
isolGridPane2.setAlignment(Pos.CENTER);
isolGridPane2.add(isolCoeff, 0, 0);
isolGridPane2.add(isolVrbl, 1, 0);
isolGridPane2.add(isolVrblb, 2, 0);
isolGridPane2.add(isolEqIntLeft, 3, 0);
isolGridPane2.add(isolEqualSign, 4, 0);
isolGridPane2.add(isolEqIntRight, 5, 0);
GridPane isolGridPane3 = new GridPane();
isolGridPane3.setAlignment(Pos.CENTER);
isolGridPane3.setHgap(25.0);
isolGridPane3.setVgap(10.0);
isolGridPane3.setPadding(new Insets(0, 0, 20, 0));
isolGridPane3.add(isolbtn1, 0, 0);
isolGridPane3.add(isolLbl1, 1, 0);
isolGridPane3.add(isolBtn2, 2, 0);
isolGridPane3.add(isolBtn3, 4, 0);
isolGridPane3.add(isolLbl2, 5, 0);
isolGridPane3.add(isolBtn4, 6, 0);
isolGridPane3.add(isolContinueBtn, 3, 1);
//Add GridPane to BorderPane
BorderPane isolBorderPane = new BorderPane();
isolBorderPane.setTop(isolGridPane1);
isolBorderPane.setCenter(isolGridPane2);
isolBorderPane.setBottom(isolGridPane3);
//Add BorderPane to Scene
scene1 = new Scene(isolBorderPane, 500, 300);
//Add the scene to the stage, set the title and show the stage
primaryStage.setScene(scene1);
primaryStage.setTitle("Equations");
primaryStage.show();
Here’s the event handler that’s supposed to send them back to the start of Stage 1:
Button yesBtn = new Button("Yes");
yesBtn.setStyle("-fx-font-size: 12pt;");
yesBtn.setOnAction(new EventHandler<ActionEvent>() {
public void handle (ActionEvent event) {
if (event.getSource() == yesBtn) {
stage.setScene(scene1);
}
}
});
Just setting the scene on the stage doesn't reload the contents of the scene..
How to resolve this.. ?
As far as I see, you do not need to change scene. Create a simple method called loadMainDisplay(), which creates the BorderPane isolBorderPane by the adding the grid to it with all the required controls.
BorderPane loadMainDisplay() {
...
}
You can call it initially while loading the contents. Later, when the user selects YES for another equation, call this method, again.
yesBtn.setOnAction(event -> {
if (event.getSource() == yesBtn) {
scene.setRoot(loadMainDisplay());
}
});
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ChangePaneExample extends Application{
/**
* #param args
*/
public static void main( String[] args ){
launch( args );
}
int screenNumber = 1;
private GridPane root;
private Scene rootScene;
private StackPane changingPane;
/**
* #see javafx.application.Application#start(javafx.stage.Stage)
* #param primaryStage
* #throws Exception
*/
#Override
public void start( Stage primaryStage ) throws Exception{
root = new GridPane();
rootScene = new Scene( root );
primaryStage.setScene( rootScene );
changingPane = new StackPane();
changeScreen();
Button changeBtn = new Button();
changeBtn.setText( "Change Screen" );
changeBtn.setOnAction( new EventHandler<ActionEvent>(){
#Override
public void handle( ActionEvent arg0 ){
changeScreen();
}
} );
root.addRow( 1, changeBtn );
root.addRow( 2, changingPane );
primaryStage.show();
}
/**
*/
private void changeScreen(){
if( screenNumber > 2 ) screenNumber = 1;
changingPane.getChildren().clear();
changingPane.getChildren().add( getDisplayPane( screenNumber + "" ) );
screenNumber++;
}
public static Pane getDisplayPane( String uniqueIdOfScreen ){
switch( uniqueIdOfScreen ){
case "1":
return getIsoletedGridPane2();
case "2":
return getIsoletedGridPane1();
default:
break;
}
return null;
}
public static Pane getIsoletedGridPane2(){
GridPane isolGridPane3 = new GridPane();
Label label = new Label();
label.setText( "this is isolated GridPane--------------- 2 ----------------------" );
isolGridPane3.getChildren().add( label );
return isolGridPane3;
}
public static Pane getIsoletedGridPane1(){
HBox isolGridPane3 = new HBox();
Label label = new Label();
label.setText( "this is isolated HBox --------------------------- 1 ----------------------------" );
isolGridPane3.getChildren().add( label );
return isolGridPane3;
}
}
This is one example of changing the Panes on the scene.
Changing the entire scene is not recommended way.
Related
How to set minimum diameter to jfxtras circularpane. For example take a look at following code,
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import jfxtras.scene.layout.*;
/**
* AssistiveBall
*/
public class AssistiveBall extends Application
{
#Override
public void start(Stage pStage) throws Exception
{
StackPane root = new StackPane();
CircularPane pane = new CircularPane();
Scene scene = new Scene(root, 800, 600);
Button btn = new Button("Center");
Button[] buttons = new Button[13];
for (int i = 0; i < buttons.length; i++)
{
buttons[i] = new Button("" + i);
}
pane.getChildren().addAll(buttons);
btn.setOnAction(e -> {
if(pane.isVisible())
{
pane.setVisible(false);
}
else
{
pane.setVisible(true);
}
});
root.getChildren().add(pane);
root.getChildren().add(btn);
pStage.setScene(scene);
pStage.setTitle("Assistive Ball");
pStage.show();
}
public static void main( String[] args )
{
AssistiveBall.launch(args);
}
}
Here here code if fine, but if i use just 3 buttons it starts appear one on another, So how to set minimum diameter or there is any another way to do this ?
Thanks.
Version 11-r3-SNAPSHOT has changed certain methods like computeChainDiameter and determineBeadDiameter to protected, so you can override them and tune the output.
I want never to hide the virtual keyboard like Programmatically show/hide virtual keyboard
OR (if above point is not possible then)
I want to remove/hide/disable below (highlighted green left bottom) button from virtual keyboard.
I am using Java 8 and Javafx.
Update 1
I have integrated José Pereda's code. The hide button (.hide) is hidden successfully. Now I am having hard time to keep displaying the keyboard for all time.
Problem:
Whenever there is focus out from the textarea the keyboard hides. So when user clicks on Convert Now! button the keyboard hides. I tried to stay focused on textarea by using textarea.requestFocus();, but there is a blinking of keyboard (hide then show).
My Goal
To never hide the keyboard at any case unless the program is not terminated.
Code: You can check my code on github too.
package com.binaryname.view;
import java.util.Iterator;
import com.sun.javafx.print.PrintHelper;
import com.sun.javafx.print.Units;
import com.sun.javafx.scene.control.skin.FXVK;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.print.PageLayout;
import javafx.print.PageOrientation;
import javafx.print.Paper;
import javafx.print.Printer;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Path;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.transform.Scale;
import javafx.stage.PopupWindow;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.Window;
public class Main extends Application {
private PopupWindow keyboard;
private final Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
private final Rectangle2D bounds = Screen.getPrimary().getBounds();
private final double taskbarHeight = bounds.getHeight() - visualBounds.getHeight();
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Binary Name");
Label helloLbl = new Label("Hello");
helloLbl.setAlignment(Pos.CENTER);
helloLbl.setFont(Font.font("Comic Sans MS", FontWeight.BOLD, 68));
helloLbl.setStyle("-fx-background-color: red;padding: 20px;");
helloLbl.setTextFill(Color.web("#ffffff"));
Label myNameLbl = new Label("my name is");
myNameLbl.setAlignment(Pos.CENTER);
myNameLbl.setFont(Font.font("Comic Sans MS", 48));
myNameLbl.setStyle("-fx-background-color: red;padding: 20px;");
myNameLbl.setTextFill(Color.web("#ffffff"));
TextArea nameTxtArea = new TextArea();
nameTxtArea.setWrapText(Boolean.TRUE);
nameTxtArea.getStyleClass().add("center-text-area");
nameTxtArea.setFont(Font.font("Comic Sans MS", 28));
nameTxtArea.setStyle("padding: 20px;");
Button printBtn = new Button("PRINT");
printBtn.setId("ipad-grey");
printBtn.setDisable(Boolean.TRUE);
Button convertBtn = new Button("Convert Now!");
convertBtn.setId("ipad-grey");
convertBtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
nameTxtArea.requestFocus();
convertBtn.setDisable(Boolean.TRUE);
printBtn.setDisable(Boolean.FALSE);
}
});
HBox hBox = new HBox(100);
hBox.setAlignment(Pos.CENTER);
hBox.getChildren().addAll(convertBtn, printBtn);
VBox vBox = new VBox(10);
vBox.setAlignment(Pos.TOP_CENTER);
vBox.getChildren().addAll(helloLbl, myNameLbl, nameTxtArea, hBox);
vBox.setStyle("-fx-background-color: red;margin: 20px;");
printBtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
nameTxtArea.requestFocus();
// Start printing
print(vBox, nameTxtArea.getText());
convertBtn.setDisable(Boolean.FALSE);
printBtn.setDisable(Boolean.TRUE);
nameTxtArea.setText("");
}
});
Scene scene = new Scene(vBox);
scene.getStylesheets().add(Main.class.getResource("/style.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setScene(scene);
primaryStage.setX(visualBounds.getMinX());
primaryStage.setY(visualBounds.getMinY());
primaryStage.setWidth(visualBounds.getWidth());
primaryStage.setHeight(visualBounds.getHeight());
adjustTextAreaLayout(nameTxtArea);
primaryStage.show();
// attach keyboard to first node on scene:
Node first = scene.getRoot().getChildrenUnmodifiable().get(0);
if (first != null) {
FXVK.init(first);
FXVK.attach(first);
keyboard = getPopupWindow();
}
nameTxtArea.focusedProperty().addListener((ob, b, b1) -> {
if (keyboard == null) {
keyboard = getPopupWindow();
}
keyboard.setHideOnEscape(Boolean.FALSE);
keyboard.setAutoHide(Boolean.FALSE);
keyboard.centerOnScreen();
keyboard.requestFocus();
keyboard.yProperty().addListener(obs -> {
Platform.runLater(() -> {
Double y = bounds.getHeight() - taskbarHeight - keyboard.getY();
nameTxtArea.setMaxHeight((bounds.getHeight() - y) * 0.4);
nameTxtArea.setMinHeight((bounds.getHeight() - y) * 0.4);
});
});
});
}
public static void main(String[] args) {
launch(args);
}
private void print(Node node1, String text) {
// Create a printer job for the default printer
Printer printer = Printer.getDefaultPrinter();
Paper label = PrintHelper.createPaper("2.5x3.5", 2.5, 3.5, Units.INCH);
PageLayout pageLayout = printer.createPageLayout(label, PageOrientation.LANDSCAPE, Printer.MarginType.EQUAL);
PrinterJob job = PrinterJob.createPrinterJob();
Node node = createFullNode(text);
double scaleX = pageLayout.getPrintableWidth() / node1.getBoundsInParent().getWidth();
double scaleY = pageLayout.getPrintableHeight() / node1.getBoundsInParent().getHeight();
node.getTransforms().add(new Scale(scaleX, scaleY));
if (job != null) {
// Print the node
boolean printed = job.printPage(node);
if (printed) {
// End the printer job
job.endJob();
} else {
// Write Error Message
System.out.println("Printing failed.");
}
} else {
// Write Error Message
System.out.println("Could not create a printer job.");
}
node.getTransforms().remove(node.getTransforms().size() - 1);
}
private PopupWindow getPopupWindow() {
#SuppressWarnings("deprecation")
final Iterator<Window> windows = Window.impl_getWindows();
while (windows.hasNext()) {
final Window window = windows.next();
if (window instanceof PopupWindow) {
if (window.getScene() != null && window.getScene().getRoot() != null) {
Parent root = window.getScene().getRoot();
if (root.getChildrenUnmodifiable().size() > 0) {
Node popup = root.getChildrenUnmodifiable().get(0);
if (popup.lookup(".fxvk") != null) {
FXVK vk = (FXVK) popup.lookup(".fxvk");
// hide the key:
vk.lookup(".hide").setVisible(false);
return (PopupWindow) window;
}
}
}
return null;
}
}
return null;
}
private Node createFullNode(String text) {
Label helloLbl = new Label("Hello");
helloLbl.setAlignment(Pos.CENTER);
helloLbl.setFont(Font.font("Comic Sans MS", FontWeight.BOLD, 68));
helloLbl.setStyle("-fx-background-color: red;padding: 20px;");
helloLbl.setTextFill(Color.web("#ffffff"));
Label myNameLbl = new Label("my name is");
myNameLbl.setAlignment(Pos.CENTER);
myNameLbl.setFont(Font.font("Comic Sans MS", 48));
myNameLbl.setStyle("-fx-background-color: red;padding: 20px;");
myNameLbl.setTextFill(Color.web("#ffffff"));
TextArea nameTxtArea = new TextArea();
nameTxtArea.setWrapText(Boolean.TRUE);
nameTxtArea.setFont(Font.font("Comic Sans MS", 28));
nameTxtArea.setStyle("padding: 20px;");
nameTxtArea.setText(text);
nameTxtArea.getStyleClass().add("center-text-area");
HBox hBox = new HBox(1000);
hBox.setAlignment(Pos.CENTER);
VBox vBox = new VBox(10);
vBox.setAlignment(Pos.CENTER);
vBox.getChildren().addAll(helloLbl, myNameLbl, nameTxtArea, hBox);
vBox.setStyle("-fx-background-color: red;margin: 20px;");
vBox.getStylesheets().add(Main.class.getResource("/style.css").toExternalForm());
return vBox;
}
private void adjustTextAreaLayout(TextArea textArea) {
textArea.applyCss();
textArea.layout();
ScrollPane textAreaScroller = (ScrollPane) textArea.lookup(".scroll-pane");
Text text = (Text) textArea.lookup(".text");
ChangeListener<? super Bounds> listener =
(obs, oldBounds, newBounds) -> centerTextIfNecessary(textAreaScroller, text);
textAreaScroller.viewportBoundsProperty().addListener(listener);
text.boundsInLocalProperty().addListener(listener);
}
private void centerTextIfNecessary(ScrollPane textAreaScroller, Text text) {
double textHeight = text.getBoundsInLocal().getHeight();
double viewportHeight = textAreaScroller.getViewportBounds().getHeight();
double offset = Math.max(0, (viewportHeight - textHeight) / 2 );
text.setTranslateY(offset);
Parent content = (Parent)textAreaScroller.getContent();
for (Node n : content.getChildrenUnmodifiable()) {
if (n instanceof Path) { // caret
n.setTranslateY(offset);
}
}
}
}
You can show and hide the virtual keyboard on demand.
You just need to provide a node that the keyboard will be attached to, and it doesn't need to be a TextField.
Obviously, you show the virtual keyboard for being able to type in your input control (TextField, TextArea,...), but I'll leave this part to you.
Without knowing your scene hierarchy, I'll just pick the first node on it:
#Override
public void start(Stage stage) {
...
stage.setScene(scene);
stage.show();
// attach keyboard to first node on scene:
Node first = scene.getRoot().getChildrenUnmodifiable().get(0);
if (first != null) {
FXVK.init(first);
FXVK.attach(first);
}
}
That will show the keyboard right after showing the stage.
If you want to programmatically close it at any point, you will just call:
FXVK.detach();
About hiding one of the keys of the keyboard, this is a little bit more tricky, since the keyboard is placed in a popup, so first of all you need to get a handle of it. But you can find already solutions for this, like this one.
The following snippet will look for the popup window. As for the deprecated method, on JavaFX 9 it will be a public method (javafx.stage.Windows.getWindows()).
private PopupWindow getPopupWindow() {
#SuppressWarnings("deprecation")
final Iterator<Window> windows = Window.impl_getWindows();
while (windows.hasNext()) {
final Window window = windows.next();
if (window instanceof PopupWindow) {
if (window.getScene() != null && window.getScene().getRoot() != null) {
Parent root = window.getScene().getRoot();
if (root.getChildrenUnmodifiable().size() > 0) {
Node popup = root.getChildrenUnmodifiable().get(0);
if (popup.lookup(".fxvk") != null) {
FXVK vk = (FXVK) popup.lookup(".fxvk");
return (PopupWindow) window;
}
}
}
return null;
}
}
return null;
}
Once you have the virtual keyboard instance, you will be able to find any of its nodes with lookups, based on their style classes. Luckily, all the keys have assigned the styleClass key, so you can easily interact with all of them. As for the particular key to hide the keyboard, this one also has special and hide style classes:
// hide the key:
vk.lookup(".hide").setVisible(false);
Full sample code:
public class FXVKAlwaysOn extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 1280, 600);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
Node first = scene.getRoot().getChildrenUnmodifiable().get(0);
if (first != null) {
FXVK.init(first);
FXVK.attach(first);
getPopupWindow();
}
}
private PopupWindow getPopupWindow() {
#SuppressWarnings("deprecation")
final Iterator<Window> windows = Window.impl_getWindows();
while (windows.hasNext()) {
final Window window = windows.next();
if (window instanceof PopupWindow) {
if (window.getScene() != null && window.getScene().getRoot() != null) {
Parent root = window.getScene().getRoot();
if (root.getChildrenUnmodifiable().size() > 0) {
Node popup = root.getChildrenUnmodifiable().get(0);
if (popup.lookup(".fxvk") != null) {
FXVK vk = (FXVK) popup.lookup(".fxvk");
// hide the key:
vk.lookup(".hide").setVisible(false);
return (PopupWindow) window;
}
}
}
return null;
}
}
return null;
}
}
Hello there brilliant minds of stack overflow!
I am currently working on a personal program that should ultimately function as a reminder every 20 or so minutes to do another task(one of those productivity-boosting things) as well as a basic timer that will tell me when my shift is over # work.
I am having difficulty parsing the appropriate textfields into an int to place in the timers I am making(aswell as the profile object).
I know there are probably a couple ways to go about this please let me know your thoughts, here is my code so far:
package javafxneoalarm;
import java.util.Timer;
import java.util.TimerTask;
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.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
/**
*
* #author Hvd
*/
public class JavaFXNeoAlarm extends Application {
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Neo Alarm");
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
Text sceneTitle = new Text("Welcome! \nPlease Enter Name &\nThe Hour/Minute of your Alarm");
sceneTitle.setFont(Font.font("Helvetica", FontWeight.NORMAL, 20));
grid.add(sceneTitle, 0, 0, 2, 1);
Button btn = new Button("Lets go!");
HBox hbBtn = new HBox(10);
hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
hbBtn.getChildren().add(btn);
grid.add(hbBtn, 1, 4);
final Text actiontarget = new Text();
grid.add(actiontarget, 1, 6);
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e){
actiontarget.setFill(Color.FIREBRICK);
actiontarget.setText("Count-down initiated \nMay the force be with you");
}
});
Label userName = new Label("Name: \n");
grid.add(userName, 0, 1);
TextField userTextField = new TextField();
grid.add(userTextField, 1, 1);
Label a1 = new Label("Alarm1: \n");
grid.add(a1, 0, 2);
TextField a1BoxHr = new TextField();
grid.add(a1BoxHr, 1, 2);
TextField a1BoxMin = new TextField();
grid.add(a1BoxMin, 2, 2);
Label a2 = new Label("Alarm2: \n");
grid.add(a2, 0, 3);
TextField a2BoxHr = new TextField();
grid.add(a2BoxHr, 1, 3);
TextField a2BoxMin = new TextField();
grid.add(a2BoxMin, 2, 3);
Scene scene = new Scene(grid, 300, 275);
primaryStage.setScene(scene);
primaryStage.show();
// double 1BoxHr = Double.parseDouble(a1BoxHr);
// profileOne = new Profile(userTextField, (((a1BoxHr*60)+a1BoxMin)*60), (((a2BoxHr*60)+a2BoxMin)*60));
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
Timer alarmA1 = new Timer();
Timer alarmA2 = new Timer();
TimerTask task = new TimerTask()
{
public void run(){
// when timer goes off
}
};
Profile profileOne;
}
}
And the profile class:
package javafxneoalarm;
/**
*
* #author Hvd
*/
public class Profile {
// declare instance variables
private String user;
private double alarm1;
private double alarm2;
// constructor (overloaded, has new instance variable or parameter to apply maths through)
public Profile(String newUser, double newAlarm1, double newAlarm2){
user = newUser;
alarm1 = newAlarm1;
alarm2 = newAlarm2;
}
// getters
public String getUser(){
return user;
}
public double getAlarm1(){
return alarm1;
}
public double getAlarm2(){
return alarm2;
}
// setters
public void setUser(String newUser){
user = newUser;
}
public void setAlarm1(double newAlarm1){
alarm1 = newAlarm1;
}
public void setAlarm2(double newAlarm2){
alarm2 = newAlarm2;
}
}
So basically how do I assign the inputs to an alarm that will go off after x amount of time, also I would like the window to close/minimize to tray after inputting/submitting the profile information and re-open when the alarm goes off but that might be a challenge for another day.
Thanks a lot guys, I look forward to continuing this creative endeavor :)
Here's how to assign a double depending on the input in the textfield, I should be placing the assignment inside the button click:
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e){
actiontarget.setFill(Color.FIREBRICK);
actiontarget.setText("Count-down initiated \nMay the force be with you");
String BUser = userTextField.getText(); // sets variable BUser from inputs
double BAlarm1Hrs = Double.parseDouble(a1BoxHr.getText());
double BAlarm1Min = Double.parseDouble(a1BoxMin.getText());
double BAlarm1 = (((BAlarm1Hrs * 60) * 60) + (BAlarm1Min * 60)); // sets BAlarm1 to seconds of hrs and minutes inputted
double BAlarm2Hrs = Double.parseDouble(a2BoxHr.getText());
double BAlarm2Min = Double.parseDouble(a2BoxMin.getText());
double BAlarm2 = (((BAlarm2Hrs * 60) * 60) + (BAlarm2Min * 60));
Profile profileA = new Profile(BUser, BAlarm1, BAlarm2);
}
});
I need to use exception handling to capture incorrect numeric values when adding numbers. I have the code I created but I am not sure how to do this. can someone show me how it is properly done so i know for the future.
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.event.*;
import javafx.stage.Stage;
public class test33 extends Application {
private double num1 = 0, num2 = 0, result = 0;
#Override
// Override the start method in the Application class
public void start(Stage primaryStage) {
FlowPane pane = new FlowPane();
pane.setHgap(2);
TextField tfNumber1 = new TextField();
TextField tfNumber2 = new TextField();
TextField tfResult = new TextField();
tfNumber1.setPrefColumnCount(3);
tfNumber2.setPrefColumnCount(3);
tfResult.setPrefColumnCount(3);
pane.getChildren().addAll(new Label("Number 1: "), tfNumber1,
new Label("Number 2: "), tfNumber2, new Label("Result: "), tfResult);
// Create four buttons
HBox hBox = new HBox(5);
Button btAdd = new Button("Add");
hBox.setAlignment(Pos.CENTER);
hBox.getChildren().addAll(btAdd);
BorderPane borderPane = new BorderPane();
borderPane.setCenter(pane);
borderPane.setBottom(hBox);
BorderPane.setAlignment(hBox, Pos.TOP_CENTER);
// Create a scene and place it in the stage
Scene scene = new Scene(borderPane, 375, 150);
primaryStage.setTitle("Test33"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
btAdd.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
num1 = Double.parseDouble(tfNumber1.getText());
num2 = Double.parseDouble(tfNumber2.getText());
result = num1 + num2;
tfResult.setText(String.format("%.1f", result));
}
});
}
/**
* The main method is only needed for the IDE with limited
* JavaFX support. Not needed for running from the command line.
*/
public static void main(String[] args) {
launch(args);
}
}
One aspect of the exception handling that should be present is in the .parseDouble(). I would suggest adding at a minimum NumberFormatException handling
public void handle(ActionEvent e) {
try {
num1 = Double.parseDouble(tfNumber1.getText());
num2 = Double.parseDouble(tfNumber2.getText());
result = num1 + num2;
tfResult.setText(String.format("%.1f", result));
}
catch (NumberFormatException nfe) {
tfResult.setText("Invalid input!");
}
}
One can get more fine-grained by catching the specific input that caused the error, etc. However, from a demonstration perspective of catching a bad number, this code is illustrative.
I have javafx application that show some info.
I am new to javafx and trying to understand things while trying some tests.
I want to add clock on top of the application, and i found next source
How can i add this clock (from the source) to my current application on same screen (on top of the screen)? my app use next code on main.java (i am using also FXML file and edit it by Scene builder):
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import net.sourceforge.zmanim.hebrewcalendar.JewishCalendar;
import net.sourceforge.zmanim.hebrewcalendar.HebrewDateFormatter;
import net.sourceforge.zmanim.hebrewcalendar.JewishCalendar;
import net.sourceforge.zmanim.util.GeoLocation;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Label lblShabat = (Label) root.lookup("#shabat");
Label lbldateHeb = (Label) root.lookup("#dateHeb");
JewishCalendar israelCalendar = new JewishCalendar();
israelCalendar.setInIsrael(true); //set the calendar to Israel
JewishCalendar chutsLaaretzCalendar = new JewishCalendar();
chutsLaaretzCalendar.setInIsrael(false); //not really needed since the API defaults to false
JewishCalendar jd = new JewishCalendar();
HebrewDateFormatter hdf = new HebrewDateFormatter();
hdf.setHebrewFormat(true);
for(int i = 0; i < 14; i++){
israelCalendar.forward(); //roll the date forward a day
// chutsLaaretzCalendar.forward(); //roll the date forward a day
if(israelCalendar.getDayOfWeek() == 7){ //ignore weekdays
if (lblShabat!=null) lblShabat.setText(hdf.formatYomTov(jd)); //hdf.formatParsha(israelCalendar)
//hdf.formatYomTov(jd)
}
}
String cholHamoedSuccos = "חול המועד סוכות";
if(hdf.formatYomTov(jd) == cholHamoedSuccos) {
String image = Main.class.getResource("Dollarphotoclub_91486993.jpg").toExternalForm();
root.setStyle("-fx-background-image: url('" + image + "'); " +
"-fx-background-position: center center; " +
"-fx-background-repeat: stretch;");
}
if (lbldateHeb!=null) lbldateHeb.setText(hdf.format(jd));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.setFullScreen(true);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
There is perhaps a better way that doesn't require as much refactoring, but I refactored Clock so a function createLayout() is separated from the start() function of Clock. In SceneBuilder add a subscene where you want the clock placed and set an id for it, I used clocksubscene. In the controller initialize() function create the layout and set the root of clocksubscene to layout. Also added the clock.css to the styles of main scene.
Refactored Clock.java (ommitted parts were unchanged) :
public void start(final Stage stage) throws Exception {
Parent layout = createLayout();
final Scene scene = new Scene(layout, Color.TRANSPARENT);
scene.getStylesheets().add(getResource("clock.css"));
// show the scene.
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.show();
}
public Parent createLayout() {
// construct the analogueClock pieces.
final Circle face = new Circle(100, 100, 100);
face.setId("face");
final Label brand = new Label("Splotch");
brand.setId("brand");
brand.layoutXProperty().bind(face.centerXProperty().subtract(brand.widthProperty().divide(2)));
brand.layoutYProperty().bind(face.centerYProperty().add(face.radiusProperty().divide(2)));
final Line hourHand = new Line(0, 0, 0, -50);
hourHand.setTranslateX(100);
hourHand.setTranslateY(100);
hourHand.setId("hourHand");
final Line minuteHand = new Line(0, 0, 0, -75);
minuteHand.setTranslateX(100);
minuteHand.setTranslateY(100);
minuteHand.setId("minuteHand");
final Line secondHand = new Line(0, 15, 0, -88);
secondHand.setTranslateX(100);
secondHand.setTranslateY(100);
secondHand.setId("secondHand");
final Circle spindle = new Circle(100, 100, 5);
spindle.setId("spindle");
Group ticks = new Group();
for (int i = 0; i < 12; i++) {
Line tick = new Line(0, -83, 0, -93);
tick.setTranslateX(100);
tick.setTranslateY(100);
tick.getStyleClass().add("tick");
tick.getTransforms().add(new Rotate(i * (360 / 12)));
ticks.getChildren().add(tick);
}
final Group analogueClock = new Group(face, brand, ticks, spindle, hourHand, minuteHand, secondHand);
// construct the digitalClock pieces.
final Label digitalClock = new Label();
digitalClock.setId("digitalClock");
// determine the starting time.
Calendar calendar = GregorianCalendar.getInstance();
final double seedSecondDegrees = calendar.get(Calendar.SECOND) * (360 / 60);
final double seedMinuteDegrees = (calendar.get(Calendar.MINUTE) + seedSecondDegrees / 360.0) * (360 / 60);
final double seedHourDegrees = (calendar.get(Calendar.HOUR) + seedMinuteDegrees / 360.0) * (360 / 12);
// define rotations to map the analogueClock to the current time.
final Rotate hourRotate = new Rotate(seedHourDegrees);
final Rotate minuteRotate = new Rotate(seedMinuteDegrees);
final Rotate secondRotate = new Rotate(seedSecondDegrees);
hourHand.getTransforms().add(hourRotate);
minuteHand.getTransforms().add(minuteRotate);
secondHand.getTransforms().add(secondRotate);
// the hour hand rotates twice a day.
final Timeline hourTime = new Timeline(
new KeyFrame(
Duration.hours(12),
new KeyValue(
hourRotate.angleProperty(),
360 + seedHourDegrees,
Interpolator.LINEAR
)
)
);
// the minute hand rotates once an hour.
final Timeline minuteTime = new Timeline(
new KeyFrame(
Duration.minutes(60),
new KeyValue(
minuteRotate.angleProperty(),
360 + seedMinuteDegrees,
Interpolator.LINEAR
)
)
);
// move second hand rotates once a minute.
final Timeline secondTime = new Timeline(
new KeyFrame(
Duration.seconds(60),
new KeyValue(
secondRotate.angleProperty(),
360 + seedSecondDegrees,
Interpolator.LINEAR
)
)
);
// the digital clock updates once a second.
final Timeline digitalTime = new Timeline(
new KeyFrame(Duration.seconds(0),
new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
Calendar calendar = GregorianCalendar.getInstance();
String hourString = pad(2, '0', calendar.get(Calendar.HOUR) == 0 ? "12" : calendar.get(Calendar.HOUR) + "");
String minuteString = pad(2, '0', calendar.get(Calendar.MINUTE) + "");
String secondString = pad(2, '0', calendar.get(Calendar.SECOND) + "");
String ampmString = calendar.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM";
digitalClock.setText(hourString + ":" + minuteString + ":" + secondString + " " + ampmString);
}
}
),
new KeyFrame(Duration.seconds(1))
);
// time never ends.
hourTime.setCycleCount(Animation.INDEFINITE);
minuteTime.setCycleCount(Animation.INDEFINITE);
secondTime.setCycleCount(Animation.INDEFINITE);
digitalTime.setCycleCount(Animation.INDEFINITE);
// start the analogueClock.
digitalTime.play();
secondTime.play();
minuteTime.play();
hourTime.play();
// add a glow effect whenever the mouse is positioned over the clock.
final Glow glow = new Glow();
analogueClock.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
analogueClock.setEffect(glow);
}
});
analogueClock.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
analogueClock.setEffect(null);
}
});
// layout the scene.
final VBox layout = new VBox();
layout.getChildren().addAll(analogueClock, digitalClock);
layout.setAlignment(Pos.CENTER);
return layout;
}
new Controller initialize code:
#Override
public void initialize(URL url, ResourceBundle rb) {
Clock clock = new Clock();
clocksubscene.setRoot(clock.createLayout());
}
In main start routine:
Scene scene = new Scene(root, 300, 275);
scene.getStylesheets().add(Clock.getResource("clock.css"));
primaryStage.setScene(scene);
TheStageOfthesource.getScene().getRoot();//will give you the root pane
is that what you want ? then you add it to your Pane