https://roehampton.github.io/module-content/software-development-3/week-08/lab/
Create a simple drop-down list using hard-coded values and capture the result
Your list will drop down and present the users with options “one”, “two” and “three”.
1.Go back to the example JavaFX project you created in the previous lab.
2.Locate the hello-view.fxml
file you were working on before. Keep the welcome text and the button. If you prefer, delete any other experiments you created. Your file should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.shape.Circle?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="com.example.sd3lab.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
</padding>
<Label fx:id="welcomeText"/>
<Button text="Hello! Lisa" onAction="#onHelloButtonClick"/>
</VBox>
Check that you can run the code and click the button to get the expected result.
<ComboBox fx:id="cb" id="cb" promptText="Select">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="Item 1" />
<String fx:value="Item 2" />
<String fx:value="Item 3" />
</FXCollections>
</items>
</ComboBox>
Add this as a child of VBox, and when you run your application you will see your select list.
Add an event handler that will respond to the selection, and replace the welcome text with the chosen number. To do this:
@FXML
private ComboBox<String> cb;
Note the matching of the ComboBox Id with the variable name AND the matching of the items type.
#onBoxSelect
and it will respond to the onAction event: <ComboBox fx:id="cb" id="cb" promptText="Select" onAction="#onBoxSelect">
@FXML
protected void onBoxSelect() {
welcomeText.setText(cb.getValue());
}
See below for the expected result. When you select a new value in the drop-down box, it will appear in the welcome text part of the GUI.
You will create a combobox which instead of being populated by arbitary numbers will be populated by some animals from our zoo classes. When selected, a text message will appear which will show the animal sound.
Create a package for the classes you have already created for your Animal base class and animals.
NOTE: You may need to alter or delete the package name from line 1 of these files.
In your hello-fxml file add the following inside the vbox:
<ComboBox fx:id="animalList" layoutX="15.0" layoutY="33.0" prefWidth="150.0" promptText="choose" onAction="#onChooseAnimal" >
</ComboBox>
import org.roehampton.sd3.jfxanimals.animals.*;
@FXML
public ComboBox<AnimalBase> animalList;
@FXML
protected void onChooseAnimal(Event event) {
System.out.print(animalList.getValue().getName());
welcomeText.setText(animalList.getValue().makeSound());
}
import javafx.fxml.Initializable;
Amend the class definitition as follows:
public class HelloController implements Initializable {
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
Lion l1 = new Lion("Elsa", 12);
Elephant e1 = new Elephant("Elmer", 13);
// We require an extra class to determine how to represent our animal classes as strings
// This avoids overriding the toString() methods in the animal base class
animalList.getItems().add(l1);
animalList.getItems().add(e1);
}
At this point, you should be able to run your code and see the following:
You will notice that the drop-down box has correctly referenced your classes, but the text shown is the object reference.
You should still be able to choose an animal and see the correct sound outputted in the welcome text area.
In order to show a nicely formatted string, we will add a helper ‘string converter’ class.
Add a new file to your animals directory called AnimalConverter. It will have the following contents:
// Helper method to create UI components eg. drop-down box from an Animal
// Required to avoid overriding toString() in AnimalBase
import javafx.util.StringConverter;
public class AnimalConverter extends StringConverter<AnimalBase> {
// Method to convert an Animal Object to a String
@Override
public String toString(AnimalBase animal) {
return animal == null? null : animal.getName();
}
// Method to convert a String to an Animal Object
@Override
public AnimalBase fromString(String string) {
return null;
}
}
Now amend your initialize method in the HelloController file:
Note the additional line which sets the string converter for the animalList.
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
Lion l1 = new Lion("Elsa", 12);
Elephant e1 = new Elephant("Elmer", 13);
// We require an extra class to determine how to represent our animal classes as strings
// This avoids overriding the toString() methods in the animal base class
animalList.setConverter(new AnimalConverter());
animalList.getItems().add(l1);
animalList.getItems().add(e1);
}
You will notice that the animals drop-down box now appears neatly showing the animals name as the displayed value.
HINT: This exercise is here to help you with your coursework. In your coursework you are likely to want to capture the users choice of a bookable item (eg. flat, hotel, bike etc), and the users choice of a client who wishes to booke the item. This part of the lab sheet is equivalent to that task.
<ComboBox fx:id="keeperList" layoutX="15.0" layoutY="33.0" prefWidth="150.0"
promptText="choose" onAction="#onChooseKeeper" >
</ComboBox>
<Button text="Assign keeper to Animal" onAction="#onClickAssign"/>
@FXML
public ComboBox<String> keeperList;
@FXML
protected void onChooseKeeper (Event event) {
System.out.println(keeperList.getValue());
}
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
Lion l1 = new Lion("Elsa", 12);
Elephant e1 = new Elephant("Elmer", 13);
// We require an extra class to determine how to represent our animal classes as strings
// This avoids overriding the toString() methods in the animal base class
animalList.setConverter(new AnimalConverter());
animalList.getItems().add(l1);
animalList.getItems().add(e1);
// Adding some strings to the second (keeper) combobox
keeperList.getItems().add("Lisa");
keeperList.getItems().add("Touseef");
}
@FXML
protected void onClickAssign(Event event) {
// Get the selected animal name
String selectedAnimal = animalList.getValue().getName();
// Get the selected keeper
String selectedKeeper = keeperList.getValue();
// Assemble a string for the output
String output = String.format("Keeper %s is assigned to Animal %s",
selectedKeeper, selectedAnimal);
// Set the welcome text to your string
welcomeText.setText(output);
}
The result should be something like the below: