Reputation: 85
I have attempted multiple times to add buttons to a FlowPane via a for loop. However, when the loop is run in my start method, the buttons fail to be rendered. I have proivided my code for the controller class and the fxml layout file I have used.
Here is my code for the controller:
package dimension.audio.player;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.ResourceBundle;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableMap;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBuilder;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.stage.Stage;
public class MediaViewer extends Application{
ArrayList<String> list;
File directory;
Button lab;
ArrayList<String> tagged = new ArrayList<String>();
@FXML
BorderPane layout = new BorderPane();
@FXML
FlowPane butLayout = new FlowPane(Orientation.HORIZONTAL);
@FXML
GridPane searchLayout;
@SuppressWarnings("rawtypes")
ObservableMap map;
static Stage stage;
static Scene scene;
public void start(final Stage stage) throws Exception {
MediaViewer.stage = stage;
Parent root = FXMLLoader.load(new URL(this.getClass().getResource("library.fxml").toExternalForm()));
if (MainController.getMedia() != null) {
list = organizeDirectory(new File(MainController.getMedia().getSource()).getParentFile(), "mp3");
} else {
list = organizeDirectory(new File(System.getProperty("user.home") + "/Music/"), "mp3");
}
stage.setTitle("Library - " + directory.getAbsolutePath());
stage.setResizable(false);
scene = new Scene(root);
addListItems(butLayout, stage, scene);
}
public ArrayList<String> organizeDirectory(File file, final String extension) {
directory = file;
if (!file.getName().contains("http")) {
final ArrayList<String> filtered = new ArrayList<String>();
File[] fileList = file.listFiles();
if (fileList != null) {
Path path = Paths.get(file.getAbsolutePath());
try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
return FileVisitResult.CONTINUE;
}
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (file.getFileName().toString().endsWith(extension)) {
filtered.add(file.toString());
}
return FileVisitResult.CONTINUE;
}
public FileVisitResult visitFileFailed(Path file, IOException e) {
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
}
return filtered;
} else {
return null;
}
} else {
return null;
}
}
public void addListItems(final Pane layout, final Stage stage, final Scene scene) {
ArrayList<Node> but = new ArrayList<Node>();
if (list != null) {
for (final String s : list) {
final String[] sList = s.split("\\\\");
System.out.println(sList[sList.length - 1]);
lab = new Button(sList[sList.length - 1]);
lab.getStyleClass().add("lab");
lab.setPrefHeight(10);
lab.setPrefWidth(scene.getWidth());
lab.setAlignment(Pos.CENTER_LEFT);
lab.setStyle("-fx-border-color: black");
lab.setStyle("-fx-backgound-color: lightgray");
lab.setTooltip(new Tooltip(lab.getText()));
lab.setOnMouseClicked(new EventHandler<MouseEvent>() {
public void handle(MouseEvent arg0) {
System.out.println("visible");
}
});
scene.widthProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
lab.setPrefWidth(scene.getWidth());
}
});
but.add(lab);
}
layout.getChildren().setAll(but);
stage.setScene(scene);
stage.show();
}
}
}
Here is the fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane id="layout" prefHeight="600.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="dimension.audio.player.MediaViewer">
<!-- TODO Add Nodes -->
<center>
<ScrollPane hbarPolicy="NEVER" prefHeight="200.0" prefWidth="200.0">
<content>
<FlowPane id="butLayout" mouseTransparent="false" orientation="VERTICAL" pickOnBounds="false" prefHeight="549.0" prefWidth="599.0" style="" />
</content>
</ScrollPane>
</center>
<top>
<GridPane id="searchLayout" alignment="CENTER_RIGHT" prefWidth="579.0" style="-fx-padding: 10">
<children>
<Label text="Search:" textAlignment="JUSTIFY" GridPane.columnIndex="0" GridPane.rowIndex="0" />
<TextField prefWidth="525.0" GridPane.columnIndex="1" GridPane.rowIndex="0" />
</children>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="320.0" minWidth="10.0" prefWidth="61.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="609.0" minWidth="10.0" prefWidth="539.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</top>
</BorderPane>
Upvotes: 0
Views: 1925
Reputation: 209340
<FlowPane fx:id="butLayout" ...>
. With the code you have, the fields are not being injected and you are not operating on the nodes in your scene graph (i.e. you're adding the buttons to the FlowPane you created in your controller, not the FlowPane you created in the FMXL file).
Upvotes: 2