I've been working on an online exam project and currently adding some multiple choice feature. My problem is, each time I moved to the next question the value from the previous radiogroupbutton is removed/deselect. But still the assigned value of the object is present.
I tried removing/adding the component as well, still the selected value for the RadioGroupButton is missing.
public class TestQuestionaire extends Dialog {
TQCoverageService tqcs = new TQCoverageServiceImpl();
CellItemService cis = new CellItemServiceImpl();
ItemKeyService iks = new ItemKeyServiceImpl();
VerticalLayout mainLayout;
TQCoverage tqCoverage;
List<CellItem> ciList = new ArrayList();
Map<CellItem, CellItemOption> cellItemAnswerMap = new HashMap();
CellItem cellItem;
Binder<CellItem> binder;
private int tqCoverageId;
private int cellItemIndex = 0;
private int cellItemIndexSize = 0;
private int score = 0;
Button next;
Button prev;
String stem;
Paragraph stemHolder;
RadioButtonGroup<CellItemOption> cioGroup;
public TestQuestionaire(int tqCoverageId) {
this.tqCoverageId = tqCoverageId;
tqCoverage = tqcs.findTQCoverage(tqCoverageId);
cellItemIndexSize = tqCoverage.getTotalItems();
for(TQItems tqi : tqcs.findAllTQItems(tqCoverageId)){
cellItem = cis.findCellItem(tqi.getCellItemId());
List<CellItemOption> cioList = cis.findAllItemOptions(tqi.getCellItemId());
cellItem.setCellItemOptionList(cioList);
ItemKey ik = iks.findItemKey(tqi.getItemKeyId());
cellItem.setItemKey(ik);
TQAnswerKey tqak = tqcs.findTQAnswerKeyByTQItem(tqi.getTqItemId());
cellItem.setTQAnswerKey(tqak);
cellItemAnswerMap.put(cellItem, new CellItemOption());
ciList.add(cellItem);
}
stemHolder = new Paragraph();
stemHolder.setWidthFull();
stemHolder.getStyle().set("font-weight", "500");
Hr hr = new Hr();
hr.setWidthFull();
cioGroup = new RadioButtonGroup<>();
cioGroup.setRenderer(new TextRenderer<>(CellItemOption::getCellItemOption));
cioGroup.addThemeVariants(RadioGroupVariant.LUMO_VERTICAL);
cioGroup.addValueChangeListener(event -> {
if(event.getValue() == null){
return;
}
if(!event.getValue().equals(event.getOldValue())){
cellItemAnswerMap.replace(getCellItem(), event.getValue());
}
});
mainLayout = new VerticalLayout(stemHolder, hr, cioGroup);
mainLayout.setWidth("600px");
hr = new Hr();
hr.setWidthFull();
mainLayout.add(hr);
binder = new Binder();
binder.forField(cioGroup)
.bind(CellItem::getCellItemOption, CellItem::setCellItemOption);
changeCellItem();
prev = new Button(VaadinIcon.BACKWARDS.create());
prev.addClickListener(event -> {
cellItemIndex--;
if(cellItemIndex == 0){
prev.setEnabled(false);
next.setEnabled(true);
} else {
prev.setEnabled(true);
next.setEnabled(true);
}
changeCellItem();
});
prev.setEnabled(false);
next = new Button(VaadinIcon.FORWARD.create());
next.getStyle().set("margin-left", "490px");
next.addClickListener(event -> {
cellItemIndex++;
if((cellItemIndex + 1) == cellItemIndexSize){
next.setEnabled(false);
prev.setEnabled(true);
} else {
next.setEnabled(true);
prev.setEnabled(true);
}
changeCellItem();
});
//this button is only to test if the current value for radiobuttongroup is removed/deselect when clicked!!
mainLayout.add(new Button("TEST", event -> {
changeCellItem();
}));
HorizontalLayout buttons = new HorizontalLayout(prev, next);
buttons.setWidthFull();
buttons.setJustifyContentMode(FlexComponent.JustifyContentMode.START);
mainLayout.add(buttons);
add(mainLayout);
open();
}
//refresh components for new/previous set if item
private void changeCellItem(){
stemHolder.removeAll();
cellItem = ciList.get(getCellItemIndex());
stem = cellItem.getItem().replace("{key}", cellItem.getItemKey().getItemKey());
stemHolder.add(stem);
cioGroup.clear();
cioGroup.setItems(cellItem.getCellItemOptionList());
cellItem.setCellItemOption(cellItemAnswerMap.get(cellItem));
binder.readBean(cellItem);
//binder.setBean(cellItem);
}
public TQCoverage getTQCoverage() {
return tqCoverage;
}
public CellItem getCellItem() {
return cellItem;
}
public int getCellItemIndex() {
return cellItemIndex;
}
public int getCellItemIndexSize() {
return cellItemIndexSize;
}
}
I'm a really new programmer so idk if this question sounds really stupid but..
This is my main:
package culminating;
import javafx.application.Application;
& all other necessary imports...
public class CulminatingMAIN extends Application {
//Set Global variables
int count = 0;
String name;
String gender = "Boy";
Label testLabel = new Label(gender + " has been selected");
#Override
public void start(Stage primaryStage) throws Exception {
/**
* ************************ SCENE 1 WORK *************************
*/
TextField nameTextField = new TextField();
nameTextField.setMaxWidth(100);
Label nameLabel = new Label("Please enter your name.");
Label genderLabel = new Label();
Label titleLabel = new Label("Math Adventure!");
titleLabel.setFont(Font.font("Arial", FontWeight.BOLD, 30));
Rectangle titleRectangle = new Rectangle();
titleRectangle.setFill(Color.TOMATO);
titleRectangle.setWidth(280);
titleRectangle.setHeight(60);
titleRectangle.setStroke(Color.BLACK);
titleRectangle.setStrokeWidth(2.0);
StackPane root = new StackPane(titleRectangle, titleLabel);
//Set VBox properties
VBox vbox1 = new VBox(25);
vbox1.setAlignment(Pos.TOP_CENTER);
vbox1.setPadding(new Insets(60, 0, 0, 0));
vbox1.setStyle("-fx-background-color: lightskyblue");
HBox genderBtnBox = new HBox(25);
genderBtnBox.setAlignment(Pos.CENTER);
//Set Scene 1 buttons
Button enterNameBtn = new Button("Enter");
Button goToScene2Btn = new Button("Continue");
//Set Radio Button functionality here
final ToggleGroup genderGroup = new ToggleGroup();
RadioButton rb1 = new RadioButton("Boy");
rb1.setToggleGroup(genderGroup);
rb1.setUserData("Boy");
rb1.setSelected(true);
RadioButton rb2 = new RadioButton("Girl");
rb2.setToggleGroup(genderGroup);
rb2.setUserData("Girl");
//Add panes, labels and buttons to the VBox
vbox1.getChildren().addAll(root, nameLabel, nameTextField, enterNameBtn, genderLabel, genderBtnBox);
Scene scene = new Scene(vbox1, 500, 500);
primaryStage.setScene(scene);
primaryStage.setTitle("Culminating Project");
primaryStage.show();
/**
* ************************ SCENE 2 WORK *************************
*/
//THIS IS ROUGH WORK SO FAR
//Here, testing out new scene to see that it loads properly (and it does)
Circle testCircle = new Circle();
testCircle.setRadius(30);
testCircle.setFill(Color.YELLOW);
StackPane testPane = new StackPane(testCircle, testLabel);
Scene scene2 = new Scene(testPane, 500, 500);
/**
* ************************ EVENTS *************************
*/
//Stores user-entered name and prompts for user gender. Adds Continue button
enterNameBtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if ((count < 1) && (!nameTextField.getText().isEmpty())) {
name = nameTextField.getText();
genderLabel.setText("Hi " + name + "! Please select whether you are a boy or girl.");
genderBtnBox.getChildren().addAll(rb1, rb2);
vbox1.getChildren().add(goToScene2Btn);
count++;
}
}
});
//When pressed, changes the scene so that scene 2 is set instead
goToScene2Btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
primaryStage.setScene(scene2);
}
});
//Radio button selection is stored in gender variable
genderGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
#Override
public void changed(ObservableValue<? extends Toggle> ov,
Toggle old_toggle, Toggle new_toggle) {
if (genderGroup.getSelectedToggle() != null) {
gender = genderGroup.getSelectedToggle().getUserData().toString();
testLabel.setText(gender + " has been selected");
}
}
});
if (gender.equals("boy")){
{
}
}
else if (gender.equals("girl")){
{
}
}
}
public static void main(String[] args) {
launch(args);
}
}
Now I have another class called CharacterGraphic, which I want to call and make the graphic I created in it appear.
package culminating;
& all the other imports
public class CharacterGraphic extends Culminating_JavaFX {
public void start(Stage primaryStage) throws Exception {
String gender = "boy";
Pane pane = new Pane();
pane.setStyle("-fx-background-color: LIGHTBLUE");
pane.setPrefSize(200, 200);
Circle head = new Circle();
head.setRadius(50);
head.setCenterX(240);
head.setCenterY(120);
head.setFill(Color.BURLYWOOD);
etc etc (all other graphics i made)
How do I do this???? And where would I do this?? Any answers really, really appreciated!
How do I make my javaFX/8 dialog box shake more elegantly whenever a user input a wrong login name/password pair?.
Since the dialog in java8u40 does NOT have one, I set out to make one it myself. However, it doesn't look good enough.
What's wrong with it? Can someone help? Is there a better way in doing it?
public void loginDialog() {
// Create the custom dialog.
Dialog<Pair<String, String>> dialog = new Dialog<>();
dialog.setTitle("Mars Simulation Project");
dialog.setHeaderText("Log in");
dialog.setContentText("Enter your username and password : ");
dialog.initModality(Modality.NONE);
// Set the button types.
ButtonType loginButtonType = new ButtonType("Login", ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL);
// Create the username and password labels and fields.
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 150, 10, 10));
TextField tfPlayer = new TextField();
tfPlayer.setPromptText("e.g. m03j");
PasswordField tfPassword = new PasswordField();
tfPassword.setPromptText("xxxx");
Button defaultPWB = new Button("Use Default");
Button guestB = new Button("As Guest");
defaultPWB.setOnAction(event -> {
tfPassword.setText("msp0");
} );
guestB.setOnAction(event -> {
tfPlayer.setText("Guest_");
tfPassword.setText("msp0");
} );
grid.add(new Label("Player Name :"), 0, 0);
grid.add(tfPlayer, 1, 0);
grid.add(guestB, 2, 0);
grid.add(new Label("Password :"), 0, 1);
grid.add(tfPassword, 1, 1);
grid.add(defaultPWB, 2, 1);
// Enable/Disable login button depending on whether a username was entered.
Node loginButton = dialog.getDialogPane().lookupButton(loginButtonType);
loginButton.setDisable(true);
// Do some validation (using the Java 8 lambda syntax).
tfPlayer.textProperty().addListener((observable, oldValue, newValue) -> {
loginButton.setDisable(newValue.trim().isEmpty());
} );
dialog.getDialogPane().setContent(grid);
// Request focus on the player name field by default.
Platform.runLater(() -> tfPlayer.requestFocus());
// Convert the result to a player name /host address pair when the login
// button is clicked.
dialog.setResultConverter(dialogButton -> {
if (dialogButton == loginButtonType) {
return new Pair<>(tfPlayer.getText(), tfPassword.getText());
}
return null;
} );
Optional<Pair<String, String>> result = dialog.showAndWait();
result.ifPresent(input -> {
playerName = tfPlayer.getText();
logger.info("Player " + input.getKey() + " connecting to server at " + serverAddressStr);
try {
dialog.show();
makeContact(serverAddressStr);
// obtain a client id
boolean isSuccessful = sendRegister();
if (isSuccessful) {
dialog.close();
// establish chat...
} else {
// shake the dialog or send an alert to inform the user the
// player name is NOT valid
DialogEarthquakeCenter dec = new DialogEarthquakeCenter(dialog);
dec.startTimer();
try {
System.out.println("start sleeping ");
Thread.sleep(2000);
System.out.println("done sleeping ");
}
catch (InterruptedException e) {}
loginDialog();
}
} catch (Exception e) {
e.printStackTrace();
}
} );
So far, my problem is that as soon as I hit the button "login", the dialog will close by default.
Therefore I have to use dialog.show() to make it show up again.
[edit] This, however, still cannot prevent the momentary gap from happening (seeing the dialog disappear and reappear).
After that, I create an instance of DialogEarthquakeCenter in order to shake the dialog.
Note that my DialogEarthquakeCenter below is a direct modification of this original :
https://github.com/gigiigig/Java-Chat/blob/master/tag/FacebookChatCore_Original/src/facebookchat/ui/common/DialogEarthquakeCenter.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.scene.control.Dialog;
import javafx.util.Duration;
import javafx.util.Pair;
public class DialogEarthquakeCenter {
public static final int SHAKE_DISTANCE = 10;
public static final double SHAKE_CYCLE = 50;
public static final int SHAKE_DURATION = 500;
public static final int SHAKE_UPDATE = 5;
private Dialog<Pair<String, String>> dialog;
private int x, y;
private long startTime;
private Timer shakeTimer;
private final double TWO_PI = Math.PI * 2.0;
private Timeline timeline;
public DialogEarthquakeCenter(Dialog<Pair<String, String>> parent) {
dialog = parent;
}
/**
* Creates and starts the timer
*
* #return Scene
*/
public void startTimer() {
x = (int) dialog.getX();
y = (int) dialog.getY();
startTime = System.currentTimeMillis();
// Set up earth time text update
timeline = new Timeline(new KeyFrame(Duration.millis(SHAKE_DURATION), ae -> startNudging()));
//timeline.setCycleCount(javafx.animation.Animation.INDEFINITE);
timeline.play();
}
public void startNudging() {
x = (int) dialog.getX();
y = (int) dialog.getY();
startTime = System.currentTimeMillis();
shakeTimer = new Timer(SHAKE_UPDATE, new ActionListener() {
public void actionPerformed(ActionEvent e) {
shake();
}
});
shakeTimer.start();
}
public void shake() {
// calculate elapsed time
long elapsed = System.currentTimeMillis() - startTime;
//System.out.println("elapsed is " + elapsed);
// use sin to calculate an x-offset
double waveOffset = (elapsed % SHAKE_CYCLE) / SHAKE_CYCLE;
double angle = waveOffset * TWO_PI;
// offset the x-location by an amount
// proportional to the sine, up to shake_distance
int shakenX = (int) ((Math.sin(angle) * SHAKE_DISTANCE) + x);
Platform.runLater(() -> {
//dialog.hide();
dialog.setX(shakenX);
//System.out.println("set shakenX to " + shakenX);
dialog.setY(y);
dialog.show();
});
//try {Thread.sleep(20);}
//catch (InterruptedException ex) {}
// should we stop timer
if (elapsed >= SHAKE_DURATION) {
stopShake();
}
}
public void stopShake() {
shakeTimer.stop();
Platform.runLater(() -> {
timeline.stop();
dialog.close();
});
}
}
I did notice that controlsfx dialog has a shake() method.
Does anyone know if it works well ?
see https://code.google.com/p/mqtt-spy/source/browse/mqtt-spy/src/main/java/org/controlsfx/dialog/CustomDialogs.java?r=6ec0240e4e64d1b8cc2b59bc77cd5902a68e0c81
Thanks much for any comments!
There's a way you can add a transition once the user has click on the login button using the Dialog API, before the window is closed.
Using dialog.show() instead of dialog.showAndWait()`, the trick is just trapping the click action on the button, consume the event, and then perform the required logic.
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.show();
loginButton.addEventFilter(EventType.ROOT,
e->{
if(e.getEventType().equals(ActionEvent.ACTION)){
e.consume();
// (hardcoded) Login Validation
boolean isSuccessful = false;
if (isSuccessful) {
dialog.close();
}
else {
// perform animation and close the dialog (or any other action)
ShakeTransition anim = new ShakeTransition(dialog.getDialogPane(), t->dialog.close());
anim.playFromStart();
}
}
});
For the shake animation, I've modified ShakeTransition from Jasper Potts, in order to move the dialog window, as #jewelsea already pointed out:
/**
* Animate a shake effect on the given node
*
* Based on CachedTimelineTransition, a Transition that uses a Timeline internally
* and turns SPEED caching on for the animated node during the animation.
*
* https://github.com/fxexperience/code/blob/master/FXExperienceControls/src/com/fxexperience/javafx/animation/CachedTimelineTransition.java
*
* and ShakeTransition
*
* https://github.com/fxexperience/code/blob/master/FXExperienceControls/src/com/fxexperience/javafx/animation/ShakeTransition.java
*
* #author Jasper Potts
*/
class ShakeTransition extends Transition {
private final Interpolator WEB_EASE = Interpolator.SPLINE(0.25, 0.1, 0.25, 1);
private final Timeline timeline;
private final Node node;
private boolean oldCache = false;
private CacheHint oldCacheHint = CacheHint.DEFAULT;
private final boolean useCache=true;
private final double xIni;
private final DoubleProperty x = new SimpleDoubleProperty();
/**
* Create new ShakeTransition
*
* #param node The node to affect
*/
public ShakeTransition(final Node node, EventHandler<ActionEvent> event) {
this.node=node;
statusProperty().addListener((ov, t, newStatus) -> {
switch(newStatus) {
case RUNNING:
starting();
break;
default:
stopping();
break;
}
});
this.timeline= new Timeline(
new KeyFrame(Duration.millis(0), new KeyValue(x, 0, WEB_EASE)),
new KeyFrame(Duration.millis(100), new KeyValue(x, -10, WEB_EASE)),
new KeyFrame(Duration.millis(200), new KeyValue(x, 10, WEB_EASE)),
new KeyFrame(Duration.millis(300), new KeyValue(x, -10, WEB_EASE)),
new KeyFrame(Duration.millis(400), new KeyValue(x, 10, WEB_EASE)),
new KeyFrame(Duration.millis(500), new KeyValue(x, -10, WEB_EASE)),
new KeyFrame(Duration.millis(600), new KeyValue(x, 10, WEB_EASE)),
new KeyFrame(Duration.millis(700), new KeyValue(x, -10, WEB_EASE)),
new KeyFrame(Duration.millis(800), new KeyValue(x, 10, WEB_EASE)),
new KeyFrame(Duration.millis(900), new KeyValue(x, -10, WEB_EASE)),
new KeyFrame(Duration.millis(1000), new KeyValue(x, 0, WEB_EASE))
);
xIni=node.getScene().getWindow().getX();
x.addListener((ob,n,n1)->(node.getScene().getWindow()).setX(xIni+n1.doubleValue()));
setCycleDuration(Duration.seconds(1));
setDelay(Duration.seconds(0.2));
setOnFinished(event);
}
/**
* Called when the animation is starting
*/
protected final void starting() {
if (useCache) {
oldCache = node.isCache();
oldCacheHint = node.getCacheHint();
node.setCache(true);
node.setCacheHint(CacheHint.SPEED);
}
}
/**
* Called when the animation is stopping
*/
protected final void stopping() {
if (useCache) {
node.setCache(oldCache);
node.setCacheHint(oldCacheHint);
}
}
#Override
protected void interpolate(double d) {
timeline.playFrom(Duration.seconds(d));
timeline.stop();
}
}
And this will be a JavaFX application using your login dialog:
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Show Login Dialog");
btn.setOnAction(mevent -> {
// Create the custom dialog.
Dialog<Pair<String, String>> dialog = new Dialog<>();
dialog.setTitle("Mars Simulation Project");
dialog.setHeaderText("Log in");
dialog.setContentText("Enter your username and password : ");
dialog.initModality(Modality.NONE);
// Set the button types.
ButtonType loginButtonType = new ButtonType("Login", ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL);
// Create the username and password labels and fields.
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 150, 10, 10));
TextField tfPlayer = new TextField();
tfPlayer.setPromptText("e.g. m03j");
PasswordField tfPassword = new PasswordField();
tfPassword.setPromptText("xxxx");
Button defaultPWB = new Button("Use Default");
Button guestB = new Button("As Guest");
defaultPWB.setOnAction(event -> {
tfPassword.setText("msp0");
} );
guestB.setOnAction(event -> {
tfPlayer.setText("Guest_");
tfPassword.setText("msp0");
} );
grid.add(new Label("Player Name :"), 0, 0);
grid.add(tfPlayer, 1, 0);
grid.add(guestB, 2, 0);
grid.add(new Label("Password :"), 0, 1);
grid.add(tfPassword, 1, 1);
grid.add(defaultPWB, 2, 1);
// Enable/Disable login button depending on whether a username was entered.
Node loginButton = dialog.getDialogPane().lookupButton(loginButtonType);
loginButton.setDisable(true);
// Do some validation (using the Java 8 lambda syntax).
tfPlayer.textProperty().addListener((observable, oldValue, newValue) -> {
loginButton.setDisable(newValue.trim().isEmpty());
} );
dialog.getDialogPane().setContent(grid);
// Request focus on the player name field by default.
Platform.runLater(() -> tfPlayer.requestFocus());
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.show();
loginButton.addEventFilter(EventType.ROOT,
e->{
if(e.getEventType().equals(ActionEvent.ACTION)){
e.consume();
// (hardcoded) Login Validation
boolean isSuccessful = false;
if (isSuccessful) {
dialog.close();
}
else {
ShakeTransition anim = new ShakeTransition(dialog.getDialogPane(), t->dialog.close());
anim.playFromStart();
}
}
});
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Shaky Login Dialog");
primaryStage.setScene(scene);
primaryStage.show();
}
I am trying to develop a wizard using the new ControlsFX 8.20.7 release. I have taken a look at the following example: BitBucket ControlsFX, and especially the method
showLinearWizard()
I simply can't understand how to use this API, can anyone help me get going or link to some examples?
This is my code right now, full of errors:
public class WizardTest extends Application {
private final ComboBox<StageStyle> styleCombobox = new ComboBox<>();
private final ComboBox<Modality> modalityCombobox = new ComboBox<>();
private final CheckBox cbUseBlocking = new CheckBox();
private final CheckBox cbCloseDialogAutomatically = new CheckBox();
private final CheckBox cbShowMasthead = new CheckBox();
private final CheckBox cbSetOwner = new CheckBox();
private final CheckBox cbCustomGraphic = new CheckBox();
private Stage stage;
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
showLinearWizard();
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
private void showLinearWizard() {
// define pages to show
Wizard wizard = new Wizard();
wizard.setTitle("Linear Wizard");
// --- page 1
int row = 0;
GridPane page1Grid = new GridPane();
page1Grid.setVgap(10);
page1Grid.setHgap(10);
page1Grid.add(new Label("First Name:"), 0, row);
TextField txFirstName = createTextField("firstName");
wizard.getValidationSupport().registerValidator(txFirstName, Validator.createEmptyValidator("First Name is mandatory"));
page1Grid.add(txFirstName, 1, row++);
page1Grid.add(new Label("Last Name:"), 0, row);
TextField txLastName = createTextField("lastName");
wizard.getValidationSupport().registerValidator(txLastName, Validator.createEmptyValidator("Last Name is mandatory"));
page1Grid.add(txLastName, 1, row);
WizardPane page1 = new WizardPane();
page1.setHeaderText("Please Enter Your Details");
page1.setContent(page1Grid);
// --- page 2
final WizardPane page2 = new WizardPane() {
#Override
public void onEnteringPage(Wizard wizard) {
String firstName = (String) wizard.getSettings().get("firstName");
String lastName = (String) wizard.getSettings().get("lastName");
setContentText("Welcome, " + firstName + " " + lastName + "! Let's add some newlines!\n\n\n\n\n\n\nHello World!");
}
};
page2.setHeaderText("Thanks For Your Details!");
// --- page 3
WizardPane page3 = new WizardPane();
page3.setHeaderText("Goodbye!");
page3.setContentText("Page 3, with extra 'help' button!");
ButtonType helpDialogButton = new ButtonType("Help", ButtonData.HELP_2);
page3.getButtonTypes().add(helpDialogButton);
Button helpButton = (Button) page3.lookupButton(helpDialogButton);
helpButton.addEventFilter(ActionEvent.ACTION, actionEvent -> {
actionEvent.consume(); // stop hello.dialog from closing
System.out.println("Help clicked!");
});
// create wizard
wizard.setFlow(new LinearFlow(page1, page2, page3));
System.out.println("page1: " + page1);
System.out.println("page2: " + page2);
System.out.println("page3: " + page3);
// show wizard and wait for response
wizard.showAndWait().ifPresent(result -> {
if (result == ButtonType.FINISH) {
System.out.println("Wizard finished, settings: " + wizard.getSettings());
}
});
}
private TextField createTextField(String id) {
TextField textField = new TextField();
textField.setId(id);
GridPane.setHgrow(textField, Priority.ALWAYS);
return textField;
}
}
The problem was that I forgot to add the
openjfx-dialogs.jar
I am trying to add a slider on my page like progress bar. But my code is not working well.
My task is when I am going to copy something from one location to another I want to display a progress bar on my page.
So in javaFx I wrote following task but it is not working well. That code runs but I want show the work in percentage like 30%, 50% and "finish". But my code fails to gives me like requirement so please help me.
My code is:
1.Declaration of progress bar and progress indicator
#FXML
final ProgressBar progressBar = new ProgressBar();
#FXML
final ProgressIndicator progressIndicator = new ProgressIndicator();
2.Assign values when I click on copy button.
#FXML
private void handleOnClickButtonAction(MouseEvent event) {
if (fromLabel.getText().isEmpty()
|| toLabel.getText().isEmpty()
|| fromLabel.getText().equalsIgnoreCase("No Directory Selected")
|| toLabel.getText().equalsIgnoreCase("No Directory Selected")) {
// Nothing
} else {
progressBar.setProgress(0.1f);
progressIndicator.setProgress(progressBar.getProgress());
this.directoryCount.setText("Please Wait !!!");
}
}
This code shows me only 10% completion an then directly shows "done", but I want whole process in percentage like 10,20,30,.. etc and then "done".
My copy code:
double i = 1;
while (rst.next()) {
File srcDirFile = new File(fromLabel.getText() + "/" + rst.getString("nugget_media_files"));
File dstDirFile = new File(toLabel.getText() + "/" + rst.getString("nugget_media_files"));
File dstDir = new File(toLabel.getText() + "/" + rst.getString("nugget_directory"));
if (srcDirFile.lastModified() > dstDirFile.lastModified()
|| srcDirFile.length() != dstDirFile.length()) {
copyDirectory(srcDirFile, dstDirFile, dstDir);
}
this.currentNuggetCount = i / this.nuggetFolderSize;
System.out.println("Nugget Count : " + this.currentNuggetCount);
Platform.runLater(new Runnable() {
#Override
public void run() {
progressBar.setProgress(1.0f);
progressIndicator.setProgress(progressBar.getProgress());
}
});
++i;
}
This is the copyDirectory method:
private static void copyDirectory(File srcDir, File dstDir,File destNugget) {
System.out.println(srcDir+" >> "+dstDir);
if(!destNugget.exists()) {
destNugget.mkdirs();
}
if (srcDir.isDirectory()) {
if (!dstDir.exists()) {
dstDir.mkdirs();
}
String[] children = srcDir.list();
for (int i=0; i<children.length; i++) {
copyDirectory(new File(srcDir, children[i]),
new File(dstDir, children[i]),
destNugget);
}
} else {
InputStream in = null;
try {
in = new FileInputStream(srcDir);
OutputStream out = new FileOutputStream(dstDir);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException ex) {
System.out.println("Exceptio "+ex);
} finally {
try {
in.close();
} catch (IOException ex) {
System.out.println("Exceptio "+ex);
}
}
}
}
Try this code. It will give you Progress bar with progress indicator which depends on the slider control.
public class Main extends Application {
#Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Progress Controls");
final Slider slider = new Slider();
slider.setMin(0);
slider.setMax(50);
final ProgressBar pb = new ProgressBar(0);
final ProgressIndicator pi = new ProgressIndicator(0);
slider.valueProperty().addListener(new ChangeListener<Number>() {
public void changed(ObservableValue<? extends Number> ov,
Number old_val, Number new_val) {
pb.setProgress(new_val.doubleValue()/50);
pi.setProgress(new_val.doubleValue()/50);
}
});
final HBox hb = new HBox();
hb.setSpacing(5);
hb.setAlignment(Pos.CENTER);
hb.getChildren().addAll(slider, pb, pi);
scene.setRoot(hb);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
You must enter your code inside a Task and set within UpdateProgress method. Before you run the Task you have to set progressBar.progressProperty (). Bind (task.progressProperty ());
This is an example:
TaskTest