How to edit fxml from code? - javafx

So I have a BorderPane in my FXML, what I want to do is to reload my BorderPane.Center properties so it shows a different pane with different layout,
How can I achieve this? The codes below doesn't work for me.
p.s : sorry for indonesian.
My FXML :
<BorderPane fx:id="bPane" xmlns:fx="http://javafx.com/fxml" fx:controller="fx.HomeMhsController" stylesheets="#css.css">
<left>
<VBox spacing="10" fx:id="vbox" id="vbox" prefWidth="100" >
<Label id="Label" fx:id="biodata" text="Biodata" onMouseClicked="#showIdentity"/>
<Label id="Label" fx:id="histori" text="Histori Nilai" onMouseClicked="#showHistory" />
<Label id="Label" fx:id="jadwal" text="Jadwal Kuliah" onMouseClicked="#showSchedule" />
<Label id="Label" fx:id="pilih" text="Pilih Mata Kuliah" onMouseClicked="#chooseSchedule"/>
</VBox>
</left>
My Controller :
public class HomeMhsController{
#FXML private Label biodata2;
#FXML private BorderPane bPane;
#FXML private void showIdentity() throws SQLException{
init.initializeDB();
String query="select * from mahasiswa where nama_dpn ='" + MainController.username + "'";
ResultSet rset = init.stmt.executeQuery(query);
if(rset.next()){
String nim = rset.getString(1);
String nama_dpn = rset.getString(2);
String nama_blkg = rset.getString(3);
String tgl_lahir = rset.getString(4);
String tempat_lahir = rset.getString(5);
String jns_kelamin = rset.getString(6);
String agama = rset.getString(7);
String alamat = rset.getString(8);
String no_hp = rset.getString(9);
biodata2.setText(nim + nama_dpn + nama_blkg + tgl_lahir + tempat_lahir + jns_kelamin + agama + alamat + no_hp);
}
}
#FXML private void showHistory() throws IOException{
FXMLLoader loader = new FXMLLoader();
Parent rootNode = null;
rootNode = loader.load(getClass().getResource("homeMhs_fxml.fxml"));
Label dua = new Label("2");
Pane pane = new Pane();
pane.getChildren().add(dua);
((BorderPane) rootNode).setCenter(pane);
}
#FXML private void showSchedule() throws SQLException, IOException{
FXMLLoader loader = new FXMLLoader();
Parent rootNode = null;
rootNode = loader.load(getClass().getResource("homeMhs_fxml.fxml"));
Label tiga = new Label("3");
Pane pane = new Pane();
pane.getChildren().add(tiga);
((BorderPane) rootNode).setCenter(pane);
}
#FXML private void chooseSchedule() throws SQLException{
}

In the following code snippet:
#FXML private void showHistory() throws IOException{
FXMLLoader loader = new FXMLLoader();
Parent rootNode = null;
rootNode = loader.load(getClass().getResource("homeMhs_fxml.fxml"));
Label dua = new Label("2");
Pane pane = new Pane();
pane.getChildren().add(dua);
((BorderPane) rootNode).setCenter(pane);
}
you are loading the fxml file again, which is a new instance and different from the one you already have (since this method in its controller class). Moreover you are not doing anything with this newly loaded one (i.e. rootNode is not being added to any scene).
Instead just use the existing injected border pane:
#FXML private void showHistory() {
Label dua = new Label("2");
Pane pane = new Pane();
pane.getChildren().add(dua);
bPane.setCenter(pane);
}
or more shorter:
#FXML private void showHistory() {
bPane.setCenter(new Pane(new Label("2")));
}

Related

Populate TableView using Derby Database

This is my first time using Derby database and I am having trouble adding information into my tableview.
public class AddController implements Initializable {
final String DB_URL = "jdbc:derby:StudentDB;";
#FXML TableView<Student> studentListView;
#FXML TableColumn stuName;
#FXML TableColumn stuAge;
#FXML TableColumn stuMajor;
#FXML TableColumn stuGPA;
#FXML ComboBox ageCB;
#FXML ComboBox majorCB;
#FXML ComboBox gpaCB;
ObservableList<Student> studentList;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
studentList = FXCollections.observableArrayList();
createDB();
createStudentsDB();
studentListView.setItems(studentList);
}
public void createDB(){
try
{
Connection conn = DriverManager.getConnection("jdbc:derby:StudentDB;create=true");
conn.close();
System.out.println("Connection successful");
}
catch(Exception ex)
{
System.out.println("ERROR: " + ex.getMessage());
}
}
public void createStudentsDB(){
try{
Connection conn = DriverManager.getConnection(DB_URL);
Statement stmt = conn.createStatement();
stmt.execute("DROP TABLE Student");
stmt.execute("CREATE TABLE Student (" +
"Name CHAR(25), " +
"Age INT, " +
"Major CHAR(45), " +
"GPA DECIMAL, ");
String sql = "INSERT INTO Student VALUES" +
"('Robert', 21, 'Computer Information Systems', 3.8)";
stmt.executeUpdate(sql);
String sqlStatement = "SELECT Name, Age, Major, GPA FROM Student";
ResultSet result = stmt.executeQuery(sqlStatement);
ObservableList<Student> studentList = FXCollections.observableArrayList();
while (result.next())
{
Student newStudent = new Student();
newStudent.name = result.getString("Name");
newStudent.age = result.getInt("Age");
newStudent.major = result.getString("Major");
newStudent.gpa = result.getDouble("GPA");
studentList.add(newStudent);
}
stmt.close();
conn.close();
}
catch (Exception ex)
{
var msg = ex.getMessage();
System.out.println(msg);
}
}
<TableView fx:id="studentListView" prefWidth="400">
<columns>
<TableColumn fx:id="stuName" text="Student" prefWidth="125"/>
<TableColumn fx:id="stuAge" text="Age" prefWidth="75"/>
<TableColumn fx:id="stuMajor" text="Major" prefWidth="125"/>
<TableColumn fx:id="stuGPA" text="GPA" prefWidth="75"/>
</columns>
</TableView>
I already created a TableView in FXML with the 4 columns I want. I just do not know how to get the information from the database to the TableView.
This code reads from a Derby Database the table is named Parent
We are using a MVC Model View Controller Pattern
And we strongly suggest you use the MVC concept when working with any database
private void ReadFromParent() throws SQLException{
ObservableList<ParentModel> TableData = FXCollections.observableArrayList();
stmnt = conn.createStatement();
ResultSet rs = stmnt.executeQuery("SELECT * FROM Parent");
while (rs.next()){// Add data to observableArrayList TableData to select a table ROW
TableData.add(new ParentModel(rs.getString("PID"),rs.getString("pMonth"),rs.getString("pYear")));
}
PropertyValueFactory<ParentModel, String> IDCellValueFactory = new PropertyValueFactory<>("PID");
colID.setCellValueFactory(IDCellValueFactory);
PropertyValueFactory<ParentModel, String> DateCellValueFactory = new PropertyValueFactory<>("pMonth");
colMonth.setCellValueFactory(DateCellValueFactory);
PropertyValueFactory<ParentModel, String> TypeCellValueFactory = new PropertyValueFactory<>("pYear");
colYear.setCellValueFactory(TypeCellValueFactory);
// ================================================================
// colTxDate are the ID's for the tableview columns
// sortDate are the Column Names for the Database TABLE CDBalance
// ================================================================
colMonth.setStyle("-fx-alignment: CENTER;");
colYear.setStyle("-fx-alignment:CENTER;");
Collections.sort(TableData, (p2, p1)-> p1.getPID().compareToIgnoreCase(p2.getPID()));
// Line of Code above Sorts Database Columns based on VARIABLE in ParentModel
// Change p2,p1 to sort Ascending or Descending
if(TableData.size() < 15) {// Format TableView to display Vertical ScrollBar
ptable.setPrefWidth(336);// 19 is the off set
}else {
ptable.setPrefWidth(355);
} ptable.setItems(TableData);
stmnt.close();
}

Some nodes won't appear in HBox

I am working on a Yahtzee game just to develop my programming skills and I can't seem to get all the Labels and Radio Buttons to appear in the HBox. Here is all the relevant code:
public class Main extends Application{
Label diceRoll1 = new Label("1");
Label diceRoll2 = new Label("2");
Label diceRoll3 = new Label("3");
Label diceRoll4 = new Label("4");
Label diceRoll5 = new Label("5");
RadioButton holdRButton1 = new RadioButton("Hold");
RadioButton holdRButton2 = new RadioButton("Hold");
RadioButton holdRButton3 = new RadioButton("Hold");
RadioButton holdRButton4 = new RadioButton("Hold");
RadioButton holdRButton5 = new RadioButton("Hold");
Button rollDice = new Button("Roll!");
Stage window;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage)throws Exception{
VBox diceRoll1Layout = new VBox(5);
diceRoll1Layout.getChildren().addAll(diceRoll1, holdRButton1);
VBox diceRoll2Layout = new VBox(5);
diceRoll2Layout.getChildren().addAll(diceRoll2, holdRButton2);
VBox diceRoll3Layout = new VBox(5);
diceRoll3Layout.getChildren().addAll(diceRoll3, holdRButton3);
VBox diceRoll4Layout = new VBox(5);
diceRoll4Layout.getChildren().addAll(diceRoll4, holdRButton4);
VBox diceRoll5Layout = new VBox(5);
diceRoll5Layout.getChildren().addAll(diceRoll5, holdRButton5);
HBox diceRolls = new HBox(5);
diceRolls.getChildren().addAll(diceRoll1Layout,diceRoll2Layout,diceRoll3Layout,
diceRoll4Layout,diceRoll5Layout, rollDice);
BorderPane rootPane = new BorderPane();
rootPane.setBottom(diceRolls);
Scene scene = new Scene(rootPane, 400, 500);
window = primaryStage;
window.setTitle("Yahtzee!");
window.setScene(scene);
window.show();
}
}
But for some reason whenever I run the code only diceRoll1, diceRoll2, holdRButton1, holdRButton2 and rollDice appear in the window. They're all coded the same so I don't know why they don't all appear. I tried setting them to visible and it made no difference. Am I missing something?

Access textarea in one controller from another controller JavaFX

I have two controllers FXMLDocumentController and FXMLOpenedCodeController. I am reading the contents of a .txt file from FXMLDocumentController and I want that text to be placed in a textarea in the FXMLOpenedCodeController. The code is running and reading well from the FXMLDocumentController but when the window from FXMLOpenedCodeController is opened, the read contents from .txt contents is not visible in the textarea. My system.out.println shows that String mine has the contents but it is not showing in the textarea in FXMLOpenedCodeController. Please help anyone. Thank you.
FXMLDocumentController code
public class FXMLDocumentController implements Initializable {
#FXML
private MenuItem open;
#FXML
private MenuItem about;
#Override
public void initialize(URL url, ResourceBundle rb) {
open.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle (ActionEvent event){
try {
showSingleFileChooser();
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
private void showSingleFileChooser() throws IOException {
//Stage s = new Stage();
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("ZEBRA file open...");
FileChooser.ExtensionFilter exfil = new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt");
fileChooser.getExtensionFilters().add(exfil);
File selectedFile = fileChooser.showOpenDialog(stage);
if(selectedFile != null){
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("FXMLOpenedCode.fxml"));
AnchorPane frame = (AnchorPane) fxmlLoader.load();
FXMLOpenedCodeController c = fxmlLoader.getController();
//c.codeExecute = codeExecute;
c.codeExecute.appendText(readFile(selectedFile));
String mine;
mine = readFile(selectedFile);
//c.codeExecute.appendText(mine);
System.out.println(mine);
Parent root = FXMLLoader.load(getClass().getResource("FXMLOpenedCode.fxml"));
Scene scene = new Scene(root);
stage4.initModality(Modality.APPLICATION_MODAL);
stage4.setTitle("Compile Code");
stage4.setScene(scene);
stage4.show();
}
}
private void newWindow() throws IOException{
Parent root = FXMLLoader.load(getClass().getResource("FXMLNew.fxml"));
Scene scene = new Scene(root);
stage3.initModality(Modality.APPLICATION_MODAL);
stage3.setTitle("Enter code to run here");
stage3.setScene(scene);
stage3.show();
}
private String readFile(File selectedFile) throws FileNotFoundException, IOException {
StringBuilder content = new StringBuilder();
BufferedReader buffRead = null;
buffRead = new BufferedReader(new FileReader(selectedFile));
String text;
while((text = buffRead.readLine())!=null){
content.append(text);
}
return content.toString();
}
}
and in the FXMLOpenedCodeController there is a public TextArea codeExecute; I removed the #FXML and private so that the code works.
You are loading FXMLOpenedCode.fxml twice. You put the text in the text area you get from loading it the first time, but then you display the UI you get from loading it the second time. So, obviously, you don't see the text as it is set to the wrong text area.
Just load the FXML file once:
if(selectedFile != null){
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("FXMLOpenedCode.fxml"));
AnchorPane frame = (AnchorPane) fxmlLoader.load();
FXMLOpenedCodeController c = fxmlLoader.getController();
//c.codeExecute = codeExecute;
String mine;
mine = readFile(selectedFile);
c.codeExecute.appendText(mine);
System.out.println(mine);
Scene scene = new Scene(frame);
stage4.initModality(Modality.APPLICATION_MODAL);
stage4.setTitle("Compile Code");
stage4.setScene(scene);
stage4.show();
}

finding child node from a TreeView and getting content of that node

Here is my question.
I have created a hardcoded tree view with a few items in it.
There are nodes and leaf nodes in it.
how will i find the selected node is the leaf node.?
and i want to pass the content of that node to a new tab.
public void SetTreeSample(){
TreeItem<String> rootItem = new TreeItem<>("elan/6");
rootItem.setExpanded(true);
TreeItem<String> item = new TreeItem<>("Verkauf");
TreeItem<String> itemBeleg = new TreeItem<>("Belegbearbeitung");
itemBeleg.getChildren().add(new TreeItem<>("Verkaufsbeleg anlegen"));
itemBeleg.getChildren().add(new TreeItem<>("Verkaufsbelege bearbeiten"));
itemBeleg.getChildren().add(new TreeItem<>("Verkaufsbeleg abrufen"));
item.getChildren().add(itemBeleg);
TreeItem<String> itemXML = new TreeItem<>("XML-Schnittstelle");
item.getChildren().add(itemXML);
TreeItem<String> itemKun = new TreeItem<>("kunden");
item.getChildren().add(itemKun);
TreeItem<String> itemKund = new TreeItem<>("kunden-Auskun ft");
item.getChildren().add(itemKund);
TreeItem<String> itemArt = new TreeItem<>("Artikel-Auskunft");
item.getChildren().add(itemArt);
rootItem.getChildren().add(item);
item = new TreeItem<>("Kassenprogramme");
item.getChildren().add(new TreeItem<>("Kassenprogramm"));
item.getChildren().add(new TreeItem<>("Gutscheinverwaltung"));
rootItem.getChildren().add(item);
item = new TreeItem<>("Versand");
rootItem.getChildren().add(item);
item = new TreeItem<>("Bestandsfutrung");
rootItem.getChildren().add(item);
TreeView<String> treeview = new TreeView<>(rootItem);
StackPane root = new StackPane();
root.getChildren().add(treeview);
treeview.setOnMouseClicked(new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent mouseEvent)
{
if(mouseEvent.getClickCount() == 2)
{
TreeItem<String> item = treeview.getSelectionModel().getSelectedItem();
AddTab(item.getValue());
}
}
});
rootLayout.setLeft(root);
}
public void AddTab(String Text){
FXMLLoader loader = new FXMLLoader();
loader.setLocation(SampleApp2.class.getResource("view/NewAP.fxml"));
TabPane tabPane = (TabPane) rootLayout.getCenter();
tabPane.setTabClosingPolicy(TabClosingPolicy.ALL_TABS);
Tab tabdata = new Tab();
Label tabALabel = new Label(Text);
tabdata.setGraphic(tabALabel);
tabPane.getTabs().add(tabdata);
}
There is a method isLeaf() on the TreeItem.
TreeItem<String> selectedItem = treeview.getSelectionModel().getSelectedItem();
if (selectedItem.isLeaf()) {
AddTab(item.getValue());
}

JavaFX adding custom class to parent node

I'd appreciate any help at all, I have spent hours at this to no avail.
So I need to add an instance of a class I found online called GridDisplay to the Parent root, as I need the scene to then display this for me. But I also need to use the fxml file to set up the root and hence the scene. Here is what I have so far:
#FXML private BorderPane mainPanel = new BorderPane();
#FXML private TilePane tilePane = new TilePane();
#FXML private Pane topCanvas = new Pane();
#FXML private Pane leftCanvas = new Pane();
#FXML private Pane rightCanvas = new Pane();
#FXML private Pane bottomCanvas = new Pane();
#FXML private ScrollPane scrollPane = new ScrollPane();
#FXML private Button stacksButton = new Button();
#FXML private Button queueButton = new Button();
#FXML private Button stepStacksButton = new Button();
#FXML private Button stepQueueButton = new Button();
private MazeSolver solver;
private GridDisplay gridDisplay;
private ArrayList<String> maze;
private String fileLocation;
private int height;
private int width;
#Override
public void start(Stage primaryStage) throws IOException, InterruptedException
{
solver = new MazeSolver(fileLocation);
int[] dimensions = solver.getDimensions();
this.width = dimensions[0];
this.height = dimensions[1];
maze = solver.getMazeLayout();
primaryStage.setTitle("Maze Solver");
//this is the root which uses the fxml file and in turn sets up the scene
Parent root = FXMLLoader.load(getClass().getResource("MazeApp.fxml"));
Scene scene = new Scene(root);
//Represents the grid with Rectangles
gridDisplay = new GridDisplay(height, width);
gridDisplay.setMaze(maze);
mainPanel = new BorderPane();
//here i set the scroll pane as the mainPanel's content
mainPanel.setCenter(scrollPane);
//and then set the gridDisplay as the scroll panes content
scrollPane.setContent(gridDisplay.getDisplay());
//re paints the grid and its boxes
gridDisplay.createElements();
primaryStage.setScene(scene);
primaryStage.show();
}
The order in which I do any of these things makes no difference, it just never shows. I am always left with the window and a blank space where the maze should be, like so: https://www.dropbox.com/s/rqxa9dy2w9lw4tz/Screenshot%202015-03-11%2022.01.46.png?dl=0 (sorry about linking, cant post image directly).
Any help would be greatly appreciated.
EDIT:
My GridDisplay class:
public class GridDisplay{
private static final double ELEMENT_SIZE = 30;
private static final double GAP = ELEMENT_SIZE / 90;
private TilePane tilePane = new TilePane();
private Group display = new Group(tilePane);
private int nRows;
private int nCols;
private ArrayList<String> maze = null;
public GridDisplay(int nRows, int nCols)
{
tilePane.setStyle("-fx-background-color: rgba(255, 215, 0, 0.1);");
tilePane.setHgap(GAP);
tilePane.setVgap(GAP);
setColumns(nCols);
setRows(nRows);
}
public void setColumns(int newColumns)
{
nCols = newColumns;
tilePane.setPrefColumns(nCols);
createElements();
}
public void setRows(int newRows)
{
nRows = newRows;
tilePane.setPrefRows(nRows);
createElements();
}
public TilePane getDisplay()
{
return tilePane;
}
public void createElements()
{
tilePane.getChildren().clear();
for (int i = 0; i < nRows; i++) {
for (int j = 0; j < nCols; j++) {
if(maze==null)
tilePane.getChildren().add(createElement(Color.RED));
else
{
Color color = Color.WHITE;
if(Character.toString(maze.get(i).charAt(j)).equals("#"))
color = Color.BLACK;
if(Character.toString(maze.get(i).charAt(j)).equals("o"))
color = Color.GREEN;
if(Character.toString(maze.get(i).charAt(j)).equals("*"))
color = Color.RED;
tilePane.getChildren().add(createElement(color));
}
}
}
}
public void colorSolved()
{
tilePane.getChildren().clear();
for (int i = 0; i < nRows; i++) {
for (int j = 0; j < nCols; j++) {
if(maze==null)
tilePane.getChildren().add(createElement(Color.RED));
else
{
Color color = Color.WHITE;
if(Character.toString(maze.get(i).charAt(j)).equals("#"))
color = Color.BLACK;
if(Character.toString(maze.get(i).charAt(j)).equals("o"))
color = Color.GREEN;
if(Character.toString(maze.get(i).charAt(j)).equals("*"))
color = Color.RED;
tilePane.getChildren().add(createElement(color));
}
}
}
}
public void setMaze(ArrayList<String> maze)
{
this.maze = maze;
}
private Rectangle createElement(Color color) {
Rectangle rectangle = new Rectangle(ELEMENT_SIZE, ELEMENT_SIZE);
rectangle.setStroke(Color.BLACK);
rectangle.setFill(color);
return rectangle;
}
}
I cannot share the code for the xml as it will not paste into this window properly, here is a picture:
https://www.dropbox.com/s/27tbliubdlqdfzm/Screenshot%202015-03-12%2010.09.25.png?dl=0
Since your root is a BorderPane, you can just set the appropriate region in the code:
BorderPane root = FXMLLoader.load(getClass().getResource("MazeApp.fxml"));
Scene scene = new Scene(root);
//Represents the grid with Rectangles
gridDisplay = new GridDisplay(height, width);
gridDisplay.setMaze(maze);
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(gridDisplay);
root.setCenter(scrollPane);
// etc

Resources