If I have a class that extends superclass that has a .setContent(Pane pane) method, am I able to change the pane from within the class.
For example: When the example button is pushed, I would like to set the content to stackPane2. (this.setContent(stackPane2);).
public class AClass extends SomeClass{
public AClass(){
super();
HBox hBox = new HBox();
Button exampleButton = new Button("Example");
exampleButton.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
//Change the content here
}
});
StackPane stackPane1 = new StackPane();
stackPane1.getChildren().addAll(hBox);
StackPane stackPane2 = new StackPane();
stackPane2.getChildren().add(/*Some other stuff*/);
this.setContent(stackPane1);
}
}
Can this be done? If so, how? Otherwise what could be a possible workaround.
I'm not sure if i missing something, but i think that the easiest way if you don't have some much code is declare stackPane1 and stackPane2 as final fields and then call setContent from the button listener.
public class AClass extends SomeClass{
private final StackPane stackPane1;
private final StackPane stackPane2;
public AClass(){
super();
HBox hBox = new HBox();
Button exampleButton = new Button("Example");
exampleButton.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
if (somenthingHapper()) {
this.setContent(stackPane1);
} else {
this.setContent(stackPane2);
}
}
});
stackPane1 = new StackPane();
stackPane1.getChildren().addAll(hBox);
stackPane2 = new StackPane();
stackPane2.getChildren().add(/*Some other stuff*/);
this.setContent(stackPane1);
}
}
Related
I am creating a simple JavaFX based game and when I add a Button to my Pane and try to perform some action on it by clicking the mouse button while hovering over the button nothing happens - as if it is disabled but still visible.
private class Game extends Parent {
public Game() {
private Button newGameButton;
private Scene secondScene;
private Stage secondStage;
private Pane pane;
VBox menu = new VBox(15);
VBox highScore = new VBox(15);
menu.setTranslateX(280);
menu.setTranslateY(250);
highScore.setTranslateX(100);
highScore.setTranslateY(200);
try {
onLoad();
} catch (IOException e) {
e.printStackTrace();
}
newGameButton = new MenuButtonView("New Game");
newGameButton.setOnMouseClicked(event -> {
pane = new Pane();
secondScene = new Scene(pane, 800, 600);
secondStage = new Stage();
secondStage.setScene(secondScene);
secondStage.show();
scoreAndCrackView();
mickeyView();
});
public void mickeyView(){
private Button leftDownRedButton;
leftDownRedButton = new Button();
rightDownRedButton.setTranslateX(640);
rightDownRedButton.setTranslateY(560);
pane.getChildren().add(rightDownRedButton);
leftDownRedButton.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
System.out.println("Clicked");
}
});
public void scoreAndCrackView()
{
vertBox = new VBox();
vertBox.setPrefSize(800, 100); // this one was causing issue, previously: vertBox.setPrefSize(800, 600)
vertBox.getChildren().addAll(scoreLabel,crackLabel);
pane.getChildren().add(vertBox);
}
}
UPDATE
Btw I found the cause of the error - as you guys suggested something was covering my buttons and more precisely the VBox in another method which was set to the whole screen. After changing the values and minimizing prefWidth and prefHeight I can click on the buttons. Lesson for the future to set the Box only for the required area.
I have having trouble getting my program to take the user input from textField and displaying it in textArea. The program I'm making is a Stack/Queue program. It has a textField that a user inputs a number into. Then there is a button that takes the input and displays it in the textArea as a Stack(FILO).
Edit 1:
I am able to move the user input into the textArea now but, whenever I add a second input it just replaces the old input with the new instead of showing the list. I am supposed to use a toString method to show the whole list? Where do I need to put the toString method if I need it?
TLDR, How do I take input from textField and display it in textArea?
This is my main class.
TextField text = new TextField();
TextArea textArea = new TextArea("Text Area");
public class StackQueue extends Application
{
#Override
public void start(Stage stage) throws Exception
{
Stack myStack = new Stack();
Button btAdd = new Button("Add");
Button btDel = new Button("Delete");
Button btClear = new Button("Clear");
BorderPane bpane = new BorderPane();
text.setPrefWidth(50);
text.setAlignment(Pos.CENTER_LEFT);
text.setText("Label");
text.clear();
textArea.setPrefColumnCount(1);
textArea.setPrefRowCount(10);
textArea.clear();
HBox hBox = new HBox();
hBox.getChildren().addAll(btAdd, btDel, btClear);
bpane.setTop(hBox);
bpane.setCenter(text);
bpane.setBottom(textArea);
Scene scene = new Scene(bpane, 500, 250);
stage.setTitle("Stack Example");
stage.setScene(scene);
stage.show();
EventHandler<ActionEvent> addEvent = event -> add();
EventHandler<ActionEvent> delEvent = event -> del();
btAdd.setOnAction(addEvent);
btDel.setOnAction(delEvent);
public void add()
{
textArea.setText(text.getText(x));
}
public void del()
{
}
}
public static void main(String[] args)
{
launch(args);
}
}
This is the Stack class.
public class Stack<E>
{
public String status = "String";
public ArrayList<E> arrayList;
public Stack()
{
arrayList = new ArrayList(10);
}
public void add(String x)
{
arrayList.add(0, (E) x);
}
//public String del
{
}
public void Clear()
{
}
}
You have included add() and del() function inside the start() function. You need to move them outside of start() function and inside of your StackQueue class.
After doing that the variables text and textArea should be created outside of start() function because the method add() and del() are trying to get the value of text and textArea variables.
Finally, you should implement the logic to handle addition and deletion of elements inside add() and del() methods.
Paste the following code in StackQueue.java file. I didn't implement the deletion functionality and you need to tweak the add() method too. I hope now you will be able to solve it.
I added a string which will get the old value of text field and append that old value when further addition is done along with the new value
public class StackQueue extends Application {
TextField text = new TextField();
TextArea textArea = new TextArea();
String oldText;
#Override
public void start(Stage stage) throws Exception
{
Stack myStack = new Stack();
Button btAdd = new Button("Add");
Button btDel = new Button("Delete");
Button btClear = new Button("Clear");
BorderPane bpane = new BorderPane();
text.setPrefWidth(50);
text.setAlignment(Pos.CENTER_LEFT);
text.setText("Label");
text.clear();
textArea= new TextArea("Text Area");
textArea.setPrefColumnCount(1);
textArea.setPrefRowCount(10);
textArea.clear();
oldText = text.getText();
HBox hBox = new HBox();
hBox.getChildren().addAll(btAdd, btDel, btClear);
bpane.setTop(hBox);
bpane.setCenter(text);
bpane.setBottom(textArea);
Scene scene = new Scene(bpane, 500, 250);
stage.setTitle("Stack Example");
stage.setScene(scene);
stage.show();
EventHandler<ActionEvent> delEvent = event -> del();
btAdd.setOnAction( e -> {
textArea.setText(oldText + text.getText());
oldText = oldText + text.getText() +"\n";
});
btDel.setOnAction(delEvent);
}
public void del()
{
}
public static void main(String[] args)
{
launch(args);
}
}
I've been trying to make my application to switch between scenes. Here is a copy of part of the code. The credits scene simply has a back button which should return me to the main scene.
When I try to click on credits button on main scene it is becoming white a white screen. I believe that there is a better way to solve this problem could you give me some advices ?
public class Application {
public static void main(String[] args) {
javafx.application.Application.launch(GUI.class);
}
}
public class GUI extends Application {
#Override
public void start(Stage primaryStage) {
Scene mainScene, creditsScene = null;
mainScene = getMainScene(primaryStage, creditsScene);
creditsScene = getCreditsScene(primaryStage, mainScene);
primaryStage.setTitle("Test application");
primaryStage.setScene(mainScene);
primaryStage.show();
}
private Scene getMainScene(Stage primaryStage, Scene creditsScene) {
final Button credits = new Button("Credits");
credits.setOnAction((ActionEvent e) -> {
primaryStage.close();
primaryStage.setScene(creditsScene);
primaryStage.show();
});
VBox x = new VBox(50);
x.setAlignment(Pos.CENTER);
x.getChildren().addAll( run, displayInfo,
label1, displayInfo, textField, submitName, credits, exit);
//scene size
Scene scene = new Scene(x, 650, 900);
return scene;
}
private Scene getCreditsScene(Stage primaryStage, Scene main) {
final Button back = new Button("Back");
back.setOnAction((ActionEvent e) -> {
primaryStage.setScene(main);
});
VBox x = new VBox(50);
x.getChildren().addAll(back);
Scene credits = new Scene(x, 650, 900);
return credits;
}
Try to switch order of strings:
mainScene = getMainScene(primaryStage, creditsScene);
creditsScene = getCreditsScene(primaryStage, mainScene);
here you pass to getMainScene null.
I am crazy about the feature of JavaFX, in Swing, I could do,
#Override
public void onPluginRegistered(final GamePlugin plugin) {
JRadioButtonMenuItem gameMenuItem = new JRadioButtonMenuItem(plugin.getGameName());
gameMenuItem.setSelected(false);
gameMenuItem.addActionListener(event -> {
if (core.getPlayers().isEmpty()) {
// Can't start a game with no players.
showErrorDialog(frame, ERROR_NO_PLAYERS_TITLE, ERROR_NO_PLAYERS_MSG);
gameGroup.clearSelection();
} else {
core.startNewGame(plugin);
}
});
gameGroup.add(gameMenuItem);
newGameMenu.add(gameMenuItem);
}
if I want to add a radio item whenever a plugin has registered.
However in JavaFX, it seems, you can't declare any global item of JavaFX, because once the start() is called, it starts a new constructor and everything you've done before is nothing (there is no variable share to me).
Here is my Javafx code.
#Override
public void start(Stage primaryStage) throws Exception {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 500, 500);
scene.getStylesheets().add("./Buttons.css");
Region spacer = new Region();
spacer.setMinWidth(10);
primaryStage.setScene(scene);
primaryStage.show();
TabPane tabPane = new TabPane();
Tab tabData = new Tab("Get your data");
tabPane.getTabs().add(tabData);
Tab tabDisplay = new Tab("Visualize your data");
tabPane.getTabs().add(tabDisplay);
pluginGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>(){
#Override
public void changed(ObservableValue<? extends Toggle> ov,
Toggle old_toggle, Toggle new_toggle) {
if (pluginGroup.getSelectedToggle() != null) {
RadioButton chk = (RadioButton) new_toggle.getToggleGroup().getSelectedToggle();
chk.getText();
}
}
});
root.setCenter(tabPane);
FlowPane inputPanel = new FlowPane();
TextField source = new TextField ();
Button confirmButton = new Button("Get Your Resource!");
confirmButton.getStyleClass().add("GREEN");
inputPanel.getChildren().addAll(new Label("Input your source:"),
spacer, source, confirmButton);
root.setBottom(inputPanel);
RadioButton defaultBtn = new RadioButton("No data plugin are registered");
FlowPane pane = new FlowPane();
pane.getChildren().addAll(new Label("Select your data source"), spacer);
if (radioButtonBox != null) {
pane.getChildren().add(radioButtonBox);
}
tabData.setContent(pane);
}
#Override
public void onPluginRegistered(DataPlugin plugin) {
RadioButton button = new RadioButton(plugin.getName());
button.setToggleGroup(pluginGroup);
radioButtonBox.getChildren().add(button);
}
public void caller(String[] args) {
launch(args);
}
I want to initialize the javafx program from,
public static void main(String[] args) throws Exception {
DataFramework core = new ConcreteDataFramework();
GuiFramework gui = new GuiFramework(core);
core.addGuiListener(gui);
gui.caller(args);
core.registerPlugin(new CsvData());
}
It is weird that I can't add any radio button to the existing radioButtonBox every time I call onPluginRegistered(DataPlugin plugin) (The new radiobutton does not show up)
You should consider the start() method as the replacement for the main method. If your application needs access to some kind of service or model, create it in the start() (or init()) method. I would actually recommend making the Application subclass (which is inherently not reusable) as minimal as possible - it should just do the startup work - and factoring the remaining GUI code into a separate class. (If you use FXML, the FXML file can define the UI, and the Application subclass is then already pretty minimal: it just loads and displays the FXML.)
You haven't really provided enough context to make it clear what's going on here, but I'm guessing GuiFramework is the Application subclass you've shown part of, and DataFramework is an interface of some kind. I also assume GuiFramework is implementing some interface that defines the onPluginRegistered method.
So I would do:
public class GuiFramework implements PluginAware {
private final BorderPane root ;
private final DataFramework dataFramework ;
public GuiFramework(DataFramework dataFramework) {
this.dataframework = dataFramework ;
this.root = new BorderPane();
TabPane tabPane = new TabPane();
Tab tabData = new Tab("Get your data");
tabPane.getTabs().add(tabData);
// etc etc (remaining code from your start() method)
}
public Parent getView() {
return root ;
}
#Override
public void onPluginRegistered(DataPlugin plugin) {
RadioButton button = new RadioButton(plugin.getName());
button.setToggleGroup(pluginGroup);
radioButtonBox.getChildren().add(button);
}
}
and define a Main class for starting the application:
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
DataFramework core = new ConcreteDataFramework();
GuiFramework gui = new GuiFramework(core);
core.addGuiListener(gui);
Scene scene = new Scene(gui.getView(), 500, 500);
scene.getStylesheets().add("./Buttons.css");
primaryStage.setScene(scene);
primaryStage.show();
core.registerPlugin(new CsvData());
}
// for environments not supporting JavaFX launch automatically:
public static void main(String[] args) {
launch(args);
}
}
I developed a small JavaFX application to be deployed in an Android device. Since, Alert is not yet supported in this current version of JavaFXPorts, I made my own implementaion of dialog. My problem is: I do not know how to implement the showAndWait functionality. Can someone know the idea?
Here's the code:
private static int status;
public static int showConfirm(String message){
status = 0;
black = new StackPane();
black.setStyle("-fx-background-color: black; -fx-opacity: 0.7;");
black.setPrefSize(Main.WIDTH, Main.HEIGHT);
Label label = new Label(message);
label.setStyle("-fx-font-size: 22px;");
label.setWrapText(true);
Button okBtn = new Button("OK");
okBtn.getStyleClass().add("terminal-button");
okBtn.setPrefWidth(120);
okBtn.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
status = 1;
Dialog.hide();
}
});
Button cancelBtn = new Button("Cancel");
cancelBtn.getStyleClass().add("terminal-button");
cancelBtn.setPrefWidth(120);
cancelBtn.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
status = -1;
Dialog.hide();
}
});
HBox btnContainer = new HBox(10);
btnContainer.setAlignment(Pos.CENTER_RIGHT);
btnContainer.getChildren().addAll(okBtn,cancelBtn);
VBox root = new VBox(30);
root.setStyle("-fx-background-color: white;");
root.setPadding(new Insets(20));
root.setPrefWidth(Main.WIDTH - 200);
root.getChildren().addAll(label,btnContainer);
Group container = new Group();
container.getChildren().add(root);
Main.PAGE.getChildren().add(black);
Main.PAGE.getChildren().add(container);
return status;
}