Checkbox initialization delay Java FX 8 - java

Can someone tell me why there is a delay on Checkbox initialization with my Code?
What happens is that if I open the program, I have to click the Checkbox several times until it performes the desired Action.
The Controller also contains setter and getter methods.
Thanks a lot
public class Controller {
/* Defined variables */
#FXML
private CheckBox happyboxtick;
#FXML
private VBox topbox;
#FXML
private VBox designbox;
#FXML
public void initialize(){
happyboxtick.setSelected(true);
designbox.setVisible(false);
designbox.getChildren().removeAll();
topbox.setVisible(true);
topbox.getChildren().addAll();
}
#FXML
public void doSomething(ActionEvent e) {
//final CheckBox chk1 = new CheckBox("chk 1");
//final CheckBox chk2 = new CheckBox("chk 2");
EventHandler eh = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
if (event.getSource() instanceof CheckBox) {
CheckBox chk = (CheckBox) event.getSource();
//System.out.println("Action performed on checkbox " + chk.getText());
//System.out.println(chk);
if(chk.isSelected()){
System.out.println("My box is selected.");
topbox.setVisible(false);
topbox.getChildren().removeAll();
designbox.setVisible(true);
designbox.getChildren().addAll();
} else
{
System.out.println("My box is not selected.");
topbox.setVisible(true);
topbox.getChildren().addAll();
designbox.setVisible(false);
designbox.getChildren().removeAll();
}/*
if ("Yes".equals(chk.getText())) {
chk2.setSelected(!chk1.isSelected());
} else if ("chk 2".equals(chk.getText())) {
chk1.setSelected(!chk2.isSelected());
}*/
}
}
};
happyboxtick.setOnAction(eh);
//chk1.setOnAction(eh);
//chk2.setOnAction(eh);
}
}
The Code compiles perfectly.
Initialization works.
The right Option is selected.
But when I click the box, I may have to click several times until the Elements are shown. And I don't know why.

Related

javafx cannot access button in custom listcell

The core of the problem is that I cannot refresh or change the content of a node of a scene (here TablesMain) from another class (here NamePriceCell).
I am building and application with a main StackPane (TableMainController extends StackPane) that contains other nodes, some of which are ListViews. In a specific ListView (say 'readitemslistview') I have created a custom ListCell (public class NamePriceCell extends ListCell) and this NamePriceCell listcell contains a button (plusbtn). When a user clicks on the plusbtn, an arraylist (say 'chosenitemslist') gets filled up with the item displayed in the particular cell and at the same time another listview in the stackpane (say 'ordereditemslist') should be triggered to display the content of the 'chosenitemslist' arraylist.
I haven't found a way to reference the plusbtn of the NamePriceCell from the main controller. Moreover this post
Get ListCell via ListView
Unfortunately right now there is no API to get List Cell by index or
to get All children's(listcells) for ListView.
has turned me away from such an attempt (I haven't been able to understand if the solution provided there is suitable for my needs, as I don't want a refresh of the same listview but from another in the same scene).
So the only way I have found to get a mouse click action from the plusbtn is with an EventHandler in the same class (NamePriceCell). And even though I can get an arraylist filled according to the clicks on the NamePriceCell buttons (the NamePriceCell calls a static method in another class with a static arraylist in it) and I can get the result in my orderedlistview by letting the user click on another button node of the TableMain StackPane, I cannot find a way to do that when the user clicks on the NamePriceCell button.
Among the things I tried is setting a static method in the TablesMainController that I can access it from the NamePriceCell EventHandler (but then I have to make the holder node of the ordereditemslist static, and even so, it hasn't worked),
writing a separate fxml for the VBox containing the ordereditemslist with a corresponding separate controller so that I can have a method there to create the ordereditemslist and set the cellFactory (but even though the fxml file displays correctly and calling the method from the EventHandler of NamePriceCell works - a System.out gets displayed - it won't affect anything on the screen not the ordereditemslist, not even a label I tested.
I am relatively a java newbie and even so more when it comes to javafx. Your help is greatly needed and appreciated.
The code of my last approach is below:
VboxList.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.VBox?>
<VBox>
<Label text="Label" id="label1"/>
<Label text="Label" id="label2"/>
<Label text="sdfsdf" id="label3"/>
<ListView nodeOrientation="LEFT_TO_RIGHT" id="orderedlist" prefHeight="200.0" prefWidth="200.0" />
</VBox>
VboxListController.java
public class VboxListController extends VBox{
FXMLLoader fxmlLoader;
#FXML
private Label label1;
#FXML
private Label label2;
#FXML
private ListView<OrderItem> orderedlist;
public VboxListController() {
fxmlLoader = new FXMLLoader(getClass().getResource("fxml/VboxList.fxml"));
//fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
public void getorderedlist(ArrayList<OrderItem> chosenitems){
ObservableList<OrderItem> myObservableList = FXCollections.observableList(chosenitems);
this.getChildren().remove(orderedlist);
orderedlist = new ListView<>();
orderedlist.setItems(myObservableList);
orderedlist.setCellFactory(new Callback<ListView<OrderItem>, ListCell<OrderItem>>() {
#Override
public ListCell<OrderItem> call(ListView<OrderItem> p) {
ListCell<OrderItem> cell = new ListCell<OrderItem>() {
#Override
protected void updateItem(OrderItem dataobj, boolean bln) {
super.updateItem(dataobj, bln);
if (dataobj != null) {
setText(dataobj.read_item_name);
}
}
};
return cell;
}
});
this.getChildren().add(orderedlist);
orderedlist.setItems(null);
orderedlist.setItems(myObservableList);
label1 = null;
this.getChildren().remove(label1);
label1 = new Label();
label1.setText("oooops!");
System.out.println("sdf");
this.getChildren().add(label1);
}
}
NamePriceCell.java
public class NamePriceCell extends ListCell<ReadItemChoiceObj> {
int count=0;
#FXML
Label namelbl;
#FXML
Label pricelbl;
#FXML
Button plusbtn;
#FXML
Region spacer;
#FXML
HBox cellHbox;
FXMLLoader mLLoader;
ReadItemChoiceObj readitem;
ArrayList<ReadItemChoiceObj> chosenreaditems;
#Override
protected void updateItem(ReadItemChoiceObj readitem, boolean empty) {
super.updateItem(readitem, empty);
chosenreaditems = new ArrayList<>();
if(empty || readitem == null) {
setText(null);
setGraphic(null);
} else {
this.readitem = readitem;
if (mLLoader == null) {
mLLoader = new FXMLLoader(getClass().getResource("fxml/NamePriceCell.fxml"));
mLLoader.setController(this);
try {
mLLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
namelbl.setText(readitem.getname());
namelbl.setMaxWidth(500);
pricelbl.setText(String.format("%.2f", readitem.getprice()));
pricelbl.setStyle("-fx-font: 8pt \"Arial\";");
pricelbl.setMaxWidth(40);
spacer.setMaxWidth(10);
spacer.setMinWidth(10);
plusbtn.setMaxWidth(20);
cellHbox.setHgrow(namelbl, Priority.ALWAYS);
cellHbox.setAlignment(Pos.BASELINE_LEFT);
setText(null);
setGraphic(cellHbox);
plusbtn.setOnMouseClicked(whattodohandler);
}
}
EventHandler<MouseEvent> whattodohandler = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
ChosenItemsStat.getplusbtnclicked(readitem);
ChosenItemsStat chos = new ChosenItemsStat();
count+=1;
plusbtn.setText(String.valueOf(count));
new VboxListController().getorderedlist(chos.sendchosenlist());
}
};
}
and a part of TablesMain.java
#FXML
Label label1;
#FXML
BorderPane borderpane;
#FXML
Pane tablepane;
#FXML
ListView<DataObj> tabcatlist;
#FXML
VBox VboxList;
#FXML
VboxListController vboxListController;
/* #FXML
ListView<OrderItem> orderedlist;*/
#FXML
VBox leftVbox;
public TablesMain(Order order) {
this.order = order;
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml/tablesmain.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
ObservableList<DataObj> myObservableList = FXCollections.observableList(gettable_categories());
tabcatlist.setItems(myObservableList);
tabcatlist.setCellFactory(new Callback<ListView<DataObj>, ListCell<DataObj>>() {
#Override
public ListCell<DataObj> call(ListView<DataObj> p) {
ListCell<DataObj> cell = new ListCell<DataObj>() {
#Override
protected void updateItem(DataObj dataobj, boolean bln) {
super.updateItem(dataobj, bln);
if (dataobj != null) {
setText(dataobj.getname());
}
}
};
return cell;
}
});
if (table_categoryID == 0) table_categoryID = tablecategories.get(0).getid();
gettables(table_categoryID);
}
private void make_readitemlist(int itemcategoryID) {
readitems = new ArrayList<>();
.... the readitems arraylist gets filled up...
ObservableList<ReadItemChoiceObj> myObservableList = FXCollections.observableList(readitems);
readitemlist.setItems(myObservableList);
readitemlist.setCellFactory(new Callback<ListView<ReadItemChoiceObj>,
ListCell<ReadItemChoiceObj>>() {
#Override
public ListCell<ReadItemChoiceObj> call(ListView<ReadItemChoiceObj> list) {
readitemlistcell = new NamePriceCell();
return readitemlistcell;
}
}
);
readitemlist.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
ReadItemChoiceObj dataobj = (ReadItemChoiceObj) readitemlist.getSelectionModel().getSelectedItem();
System.out.println(String.valueOf(dataobj.getid()));
// showorderedlist(new ChosenItemsStat().sendchosenlist());
}
});
System.out.println(readitemlist.cellFactoryProperty().getClass().toString());
}
...
}
Since it's been almost 5 months without another contribution, i would like to post my solution as an answer. It's not mine but inspired (or copied) by the post mentioned in my question (or another one, now I don't remember, please excuse my possible misplacement of credits).
More precisely I created a static StringProperty in TableMain file (the main Controller class). Every time the plusbtn (NamePriceCell class that extends ListCell) is clicked a random number turned to string is forced in the static StringProperty of the TableMain controller class. Inside this class the StringProperty has a ChangeListener added which in its turn triggers (from inside of the main controller now - that was the clue) the refreshing of the orderedlist (the listview that had to be refreshed with the added items).
NamePriceCell.java
public class NamePriceCell extends ListCell<ReadItemChoiceObj> {
#FXML
Label namelbl;
#FXML
Label pricelbl;
#FXML
Button plusbtn;
#FXML
Region spacer;
#FXML
HBox cellHbox;
FXMLLoader mLLoader;
ReadItemChoiceObj readitem;
#Override
protected void updateItem(ReadItemChoiceObj readitem, boolean empty) {
super.updateItem(readitem, empty);
if(empty || readitem == null) {
setText(null);
setGraphic(null);
} else {
this.readitem = readitem;
if (mLLoader == null) {
mLLoader = new FXMLLoader(getClass().getResource("fxml/NamePriceCell.fxml"));
mLLoader.setController(this);
try {
mLLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
namelbl.setText(readitem.getname());
namelbl.setMaxWidth(500);
pricelbl.setText(String.format("%.2f", readitem.getprice()));
pricelbl.setStyle("-fx-font: 8pt \"Arial\";");
pricelbl.setMaxWidth(40);
spacer.setMaxWidth(10);
spacer.setMinWidth(10);
plusbtn.setMaxWidth(20);
cellHbox.setHgrow(namelbl, Priority.ALWAYS);
cellHbox.setAlignment(Pos.BASELINE_LEFT);
setText(null);
setGraphic(cellHbox);
plusbtn.setOnMouseClicked(whattodohandler);
}
}
EventHandler<MouseEvent> whattodohandler = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
OrderItem orderitem = new OrderItem();
orderitem.read_item_name = readitem.getname();
orderitem.read_item_price=readitem.getprice();
orderitem.read_itemID=readitem.getid();
orderitem.choice_name_list = new ArrayList<String>();
orderitem.choice_price_list = new ArrayList<Float>();
orderitem.choice_id_list = new ArrayList<Integer>();
ChosenItemsStat.getplusbtnclicked(orderitem);
Random rand = new Random();
TablesMain.stringProperty.setValue(String.valueOf(rand));
}
};
}
ChosenItemsStat.java (a static class receiving the additions to the list)
public class ChosenItemsStat {
static ArrayList<OrderItem> chosenorderitemsstat = new ArrayList<>();
static void getplusbtnclicked(OrderItem orderitem){
chosenorderitemsstat.add(orderitem);
}
}
I didn't use the VboxList.fxml or the VboxListController.java as I included this in the TablesMain.java (see below)
TablesMain.java (as in the question but with this addition)
stringProperty = new SimpleStringProperty();
stringProperty.setValue("");
tablelbl.setText(stringProperty.getValue());
stringProperty.addListener(new ChangeListener(){
#Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
showselectedlist();
}
});
while the showselectedlist() that is being called by the change of the StringProperty value is the one below (in this method the cell is being contructed as in the removed class (VboxListController)
private void showselectedlist(){
orderitems.addAll(ChosenItemsStat.chosenorderitemsstat);
ChosenItemsStat.chosenorderitemsstat.clear();
ListView<OrderItem> selectedlist = new ListView<>();
ObservableList<OrderItem> myObservableList = FXCollections.observableList(orderitems);
selectedlist.setItems(myObservableList);
selectedlist.setMaxWidth(220);
selectedlist.setCellFactory(new Callback<ListView<OrderItem>, ListCell<OrderItem>>() {
#Override
public ListCell<OrderItem> call(ListView<OrderItem> p) {
ListCell<OrderItem> cell = new ListCell<OrderItem>(){
OrderedCell ordcell= new OrderedCell();
#Override
protected void updateItem(OrderItem orderitem, boolean bln) {
super.updateItem(orderitem, bln);
if (orderitem != null) {
Float price = ordcell.getitemTempPrice(orderitem,orderitem.read_item_price);
HBox namepriceHbox = new HBox();
Label lblprice= new Label(String.format("%.2f",price));
Region betweenregion = new Region();
Label lblname = new Label();
lblname.setText(orderitem.read_item_name );
lblname.setStyle("-fx-font: 10pt \"Arial\";-fx-font-weight:bold");
namepriceHbox.setHgrow(betweenregion, Priority.ALWAYS);
namepriceHbox.getChildren().addAll(lblname,betweenregion,lblprice);
VBox allVbox = new VBox();
Text lblchoices = new Text();
String choices = ordcell.choicestostring(orderitem);
lblchoices.setText(choices);
lblchoices.setWrappingWidth(listpane.getLayoutBounds().getWidth());
if (choices.equals("")) allVbox.getChildren().addAll(namepriceHbox);
else allVbox.getChildren().addAll(namepriceHbox, lblchoices);
double namepricewidth = listpane.getLayoutBounds().getWidth();
System.out.println("namepricewidth is "+String.valueOf(namepricewidth));
//allVbox.setPadding(new Insets(10,0,10,0));
setGraphic(allVbox);
}
}
};
return cell;
}
});
listpane.getChildren().add(selectedlist);
}

Get variables from Main Controller

I am creating a board game with JavaFX. I have two controllers for my project and would like to access variables and methods from the main controller. My main controller has most of the game logic and UI but I would like to have a popup window for special cases. Right now I have the popup window, but would like to use variables from the main controller in the popup window controller. I was able to get variables from the secondary controller to the main controller but not the other way around. Any help would be appreciated.
Here is the code in the main controller that opens the new popup window:
public void newWindow() {
try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("player.fxml"));
//Parent root = fxmlLoader.load();
Stage playerStage = new Stage();
playerStage.setTitle("Pick your move");
playerStage.initStyle(StageStyle.UNDECORATED);
playerStage.setScene(new Scene((Pane) fxmlLoader.load()));
playerStage.show();
ControllerPopup controller =
fxmlLoader.<ControllerPopup>getController();
this.controller = controller;
if(currentCard.getMoves() == 10){
controller.handleTen();
}
else if(currentCard.getMoves() == 11){
controller.handleEleven();
}
else{
controller.handleSeven();
}
disablePawns(bluePawns);
} catch (Exception e) {
e.printStackTrace();
}
}
And here is the secondary controller:
public class ControllerPopup implements Initializable{
#FXML
private RadioButton button1,button2,button3,button4;
#FXML
private Button closeButton;
private RadioButton selectedButton;
private ToggleGroup group;
Controller controller;
#Override
public void initialize(URL location, ResourceBundle resources) {
group = new ToggleGroup();
button1.setToggleGroup(group);
button2.setToggleGroup(group);
button3.setToggleGroup(group);
button4.setToggleGroup(group);
}
public void handleTen(){
button1.setSelected(true);
button1.setText("Move forward 10");
button2.setText("Move backwards 1");
button3.setDisable(true);
button4.setDisable(true);
}
public void handleEleven(){
button1.setSelected(true);
button1.setText("Swap with another pawn");
button2.setText("Move forward 11");
button3.setDisable(true);
button4.setDisable(true);
}
public void handleSeven(){
button1.setSelected(true);
button1.setText("Move forward 1 and 6");
button2.setText("Move forward 2 and 5");
button3.setText("Move forward 3 and 4");
button4.setText("Move forward 7");
}
#FXML
public void handleCloseButtonAction(ActionEvent event) {
selectedButton = (RadioButton) group.getSelectedToggle();
Stage stage = (Stage) closeButton.getScene().getWindow();
stage.close();
}
public RadioButton getSelectedButton(){
return selectedButton;
}
You can just create the appropriate set methods in the "secondary" controller and pass the values to them from the main controller:
controller.setXXX(...);

JavaFX: I need to get info from a TextField with a Button

I have created a text field:
TextField tfPost = new TextField("140 character word count...");
I also have a button with a ActionEvent Handler class:
Button btTweet = new Button("Tweet");
TweetHandlerClass btTweetHandler = new TweetHandlerClass();
btTweet.setOnAction(btTweetHandler);
Here is the body of the handler class:
class TweetHandlerClass implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent ae) {
System.out.println("Tweet button was clicked");
String newTweet = tfPost.getText();
}
}
What I need is for the string inside the TextField to be saved to a string variable when the Tweet button is clicked. How do I do this?
Variable scoping is a design question. The OP's question does not provide sufficient information to understand the full use case. One approach is to store the variable in the TweetHandlerClass. There are various rationales for and against such an approach. Nonetheless, for the specific question posed, it should suffice.
class TweetHandlerClass implements EventHandler<ActionEvent> {
private final TextField tfPost;
public TweetHandlerClass(TextField srcTxtFld)
{
this.tfPost = srcTxtFld;
}
#Override
public void handle(ActionEvent ae) {
System.out.println("Tweet button was clicked");
String newTweet = tfPost.getText();
}
}
Then, in the instantiating the Button:
TextField tfPost = new TextField("140 character word count...");
Button btTweet = new Button("Tweet");
TweetHandlerClass btTweetHandler = new TweetHandlerClass(tfPost);
btTweet.setOnAction(btTweetHandler);
If you really want the event handler to be a top-level class like that, you could give it a reference to a TextField as in #KevinO's answer. A slight variant on that would just be to have a reference to a Supplier<String>, which is more semantically what you really need:
class TweetHandlerClass implements EventHandler<ActionEvent> {
private final Supplier<String> tweetSupplier ;
TweetHandlerClass(Supplier<String> tweetSupplier) {
this.tweetSupplier = tweetSupplier ;
}
#Override
public void handle(ActionEvent ae) {
System.out.println("Tweet button was clicked");
String newTweet = tweetSupplier.get();
}
}
and then
Button btTweet = new Button("Tweet");
TweetHandlerClass btTweetHandler = new TweetHandlerClass(tfPost::getText);
btTweet.setOnAction(btTweetHandler);
This is pretty much overkill though. Normally you would just define the event handler with a lambda expression, instead of an explicit class:
Button btTweet = new Button("Tweet");
btTweet.setOnAction(e -> {
System.out.println("Tweet button was clicked");
String newTweet = tfPost.getText();
// ..
});

JavaFX setting Button style on Mouse Click

I've got a problem with a Java project I'm working on: I'm creating a grid of buttons via code in javafx on a pane. The buttons are all types of a subclass of the javafx Button class that i wrote.
Here's the header of the class:
private final String BASIC_STYLE = "-fx-font: 6 arial;";
private final String CLICKED_STYLE = "-fx-background-color: #0f0";
private int row;
private int col;
private String category;
private boolean selected = false;
Within the constructor i do the follwing:
this.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
toggleSelected();
}
});
Here's the toggleSelected() Method:
public void toggleSelected() {
this.selected = !selected;
this.setStyle(selected ? this.BASIC_STYLE : this.BASIC_STYLE+this.CLICKED_STYLE);
}
It's basically supposed to swap the style everytime you click the button. When i click the button, the button first gets selected by the OS (the border is becoming blue) and only after i click a second time on the exact same button it'll become green (the style that i'm giving it via setStyle).
However, the selected property becomes true on the first click and false on the second click, which means i click once on the button and it gets a blue border and selected = true, if i click on it a second time it becomes green and selected = false and if i click on it a third time it becomes normal again but selected will be true again.
I find it to be really strange that the first click on a button changes the "selected" variable correctly but not the style. Why is this happening and how can i avoid that i've to select the button first before i can click it?
You initialize
selected = false ;
and
setStyle(BASIC_STYLE);
But your event handler enforces the rule
selected == true -> setStyle(BASIC_STYLE);
selected == false -> setStyle(CLICKED_STYLE);
So your initial state is inconsistent with the state your handler enforces.
From the initial state, the first time you click, selected is set to true which causes setStyle(BASIC_STYLE) (which is the value it already has, so nothing changes). From then on, everything will switch as required.
You either need to change the initial state, or switch the logic of the setStyle(...) call in the handler.
public class ButtonEnterAction extends Button {
boolean selected = true;
public ButtonEnterAction(String connect) {
setText(connect);
action();
}
public ButtonEnterAction() {
action();
}
private void action() {
EventHandler<KeyEvent> enterEvent = (KeyEvent event) -> {
if (event.getCode() == KeyCode.ENTER) {
fire();
}
};
addEventFilter(KeyEvent.KEY_PRESSED, enterEvent);
// setOnMouseEntered(new EventHandler<MouseEvent>() {
// #Override
// public void handle(MouseEvent me) {
// SepiaTone st = new SepiaTone();
// setEffect(st);
// }
// });
// setOnMouseExited(new EventHandler<MouseEvent>() {
// #Override
// public void handle(MouseEvent me) {
// setEffect(null);
// }
// });
}
#Override
public void fire() {
super.fire(); //To change body of generated methods, choose Tools | Templates.
if (selected) {
SepiaTone st = new SepiaTone();
setEffect(st);
} else {
setEffect(null);
}
selected = !selected;
}
}
Create the Instant Class in ButtonEnterAction is like.
ButtonEnterAction bea = new ButtonEnterAction("TestButton");
bea.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("hello");
}
});

How can I get a Button's text in JavaFX if the Button is being read as a Node? Looping through Group/VBox of Buttons. Returns it as Nodes

I'm learning JavaFX and this is just a small programming question.
I have 3 buttons in a VBox. And I want to apply the same 3 effects on all buttons after I put them in the Vbox. But when I use a for loop and getChildren() on the VBox, they are returned as 'Nodes'. I can't use the Button.getText() to find out the text of the button.
Is there a way I can getText of a Node? Or maybe convert the current Node to a Button and get the text that way?
VBox vbox = new VBox();
Button option1 = new Button("Single Player");
Button option2 = new Button("Network Player");
Button option3 = new Button("View Rules");
vbox.getChildren().add(option1);
vbox.getChildren().add(option2);
vbox.getChildren().add(option3);
for (final Node button : vbox.getChildren()) {
button.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent arg0) {
button.setEffect(addEffect(Color.web("#53CFA6"), .8, 10));
}
});
button.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent arg0) {
button.setEffect(addEffect(Color.web("#FF6800"), .8, 10));
}
});
button.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent arg0) {
button.setEffect(addEffect(Color.web("#E62800"), .8, 10));
//Need to use button.getText()
//Button button; button.getText() works
}
});
}
there is two options:
1. Convert types. Easy, but not safe.
If you sure you wouldn't add other children to this VBox you can just convert Node to Button:
for (Node node : vbox.getChildren()) {
if (node instanceof Button) {
final Button button = (Button) node;
// all your logic
}
2. Use Factory pattern. Best suites, IMHO.
introduce method createButton which will setup button as you need:
private Button createButton(String name) {
final Button button = new Button(name);
button.setOnMouseEntered(...);
button.setOnMouseExited(...);
button.setOnMouseClicked(...);
return button;
}
and you code will look next way:
Button option1 = createButton("Single Player");
Button option2 = createButton("Network Player");
Button option3 = createButton("View Rules");
vbox.getChildren().addAll(option1, option2, option3);
3. Introduce your own Button class. Better if you plan to extend buttons logic.
public void FancyButton extends Button {
public FancyButton(String name) {
super(name);
//handlers logic here
}
}
You can get text from button and assign it to a string variable by this code :-
String Val = ((Button)event.getSource()).getText();

Categories

Resources