通过for循环向FlowPane(JavaFX)添加按钮

时间:2014-04-08 03:37:20

标签: java for-loop javafx fxml

我多次尝试通过for循环向FlowPane添加按钮。但是,当在我的start方法中运行循环时,按钮无法呈现。我已经为我使用的控制器类和fxml布局文件提供了代码。

这是我的控制器代码:

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();
    }
    }
}

这是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>

1 个答案:

答案 0 :(得分:2)

  1. 不要在控制器中实例化@ FXML注入的字段。我们的想法是,FXMLLoader会为这些实例注入这些实例。
  2. 要将FXML文件中的字段注入控制器,您需要属性fx:id =“fieldName”,例如<FlowPane fx:id="butLayout" ...>
  3. 使用您拥有的代码,字段不会被注入,并且您不在场景图中的节点上运行(即您将按钮添加到您在控制器中创建的FlowPane,而不是您在中创建的FlowPane FMXL文件)。