我将https://github.com/acaicedo/JFX-MultiScreen中的代码用于多个屏幕。在第一个屏幕中,我仅选择方法,如果需要,则打开多个文件的文件对话框。我将一个ArrayList添加到ScreensController中,并在第一个屏幕中填充了它。
现在我遇到了问题,无法在secound屏幕中接收它们,用一个按钮我得到了文件列表,但是当我切换到secound屏幕时,它没有起作用
第二秒钟我无法访问myController.getdata(),收到错误消息“屏幕尚未加载!!!”来自原始的Screencontoller
我尝试使用构造函数和初始化方法加载列表
@Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
INSTANCE = this;
super.init(site, input);
FileEditorInput fei = (FileEditorInput) input;
IFile file = fei.getFile();
IProject project = file.getProject();
try {
if (project.hasNature(JavaCore.NATURE_ID)) {
IJavaProject targetProject = JavaCore.create(project);
final IClasspathEntry[] resolvedClasspath = targetProject.getResolvedClasspath(true);
ArrayList<URL> urls = new ArrayList<>();
for (IClasspathEntry classpathEntry : resolvedClasspath) {
if (classpathEntry.getPath().toFile().isAbsolute()) {
urls.add(classpathEntry.getPath().toFile().toURI().toURL());
} else {
urls.add(new File(project.getWorkspace().getRoot().getLocation().toFile(),classpathEntry.getPath().toString()).toURI().toURL());
}
}
URLClassLoader urlCl = new URLClassLoader(urls.toArray(new URL[urls.size()]));
Reflections reflections = new Reflections(urlCl,new TypeAnnotationsScanner(),new SubTypesScanner(true));
Set<Class<?>> classes = reflections.getTypesAnnotatedWith(<???>.class);
System.out.println(classes);
}
} catch (CoreException | IOException e1) {
e1.printStackTrace();
}
}
-
package minimalexample;
/**
*
* @author Angie
*/
public interface ControlledScreen {
//This method will allow the injection of the Parent ScreenPane
public void setScreenParent(ScreensController screenPage);
}
-
package minimalexample;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.property.DoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.layout.StackPane;
import javafx.util.Duration;
public class ScreensController extends StackPane {
//Holds the screens to be displayed
private ArrayList<String> dateien = new ArrayList<String>();;
public ArrayList<String> getdata() {
return dateien;
}
public void addF(String f) {
this.dateien.add(f);
}
private HashMap<String, Node> screens = new HashMap<>();
public ScreensController() {
super();
}
//Add the screen to the collection
public void addScreen(String name, Node screen) {
screens.put(name, screen);
}
//Returns the Node with the appropriate name
public Node getScreen(String name) {
return screens.get(name);
}
//Loads the fxml file, add the screen to the screens collection and
//finally injects the screenPane to the controller.
public boolean loadScreen(String name, String resource) {
try {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
URL url = classLoader.getResource(resource);
FXMLLoader myLoader = new FXMLLoader(url);
Parent loadScreen = (Parent) myLoader.load();
ControlledScreen myScreenControler = ((ControlledScreen) myLoader.getController());
myScreenControler.setScreenParent(this);
addScreen(name, loadScreen);
return true;
} catch (Exception e) {
System.out.println(e.getMessage());
return false;
}
}
//This method tries to displayed the screen with a predefined name.
//First it makes sure the screen has been already loaded. Then if there is more than
//one screen the new screen is been added second, and then the current screen is removed.
// If there isn't any screen being displayed, the new screen is just added to the root.
public boolean setScreen(final String name) {
if (screens.get(name) != null) { //screen loaded
final DoubleProperty opacity = opacityProperty();
if (!getChildren().isEmpty()) { //if there is more than one screen
Timeline fade = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(opacity, 1.0)),
new KeyFrame(new Duration(1000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
getChildren().remove(0); //remove the displayed screen
getChildren().add(0, screens.get(name)); //add the screen
Timeline fadeIn = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(opacity, 0.0)),
new KeyFrame(new Duration(800), new KeyValue(opacity, 1.0)));
fadeIn.play();
}
}, new KeyValue(opacity, 0.0)));
fade.play();
} else {
setOpacity(0.0);
getChildren().add(screens.get(name)); //no one else been displayed, then just show
Timeline fadeIn = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(opacity, 0.0)),
new KeyFrame(new Duration(2500), new KeyValue(opacity, 1.0)));
fadeIn.play();
}
return true;
} else {
System.out.println("screen hasn't been loaded!!! \n");
return false;
}
/*Node screenToRemove;
if(screens.get(name) != null){ //screen loaded
if(!getChildren().isEmpty()){ //if there is more than one screen
getChildren().add(0, screens.get(name)); //add the screen
screenToRemove = getChildren().get(1);
getChildren().remove(1); //remove the displayed screen
}else{
getChildren().add(screens.get(name)); //no one else been displayed, then just show
}
return true;
}else {
System.out.println("screen hasn't been loaded!!! \n");
return false;
}*/
}
//This method will remove the screen with the given name from the collection of screens
public boolean unloadScreen(String name) {
if (screens.remove(name) == null) {
System.out.println("Screen didn't exist");
return false;
} else {
return true;
}
}
}
-
package minimalexample;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* @author Angie
*/
public class ScreensFramework extends Application {
public static String screen1ID = "Start";
public static String screen1File = "first.fxml";
public static String screen2ID = "Secound";
public static String screen2File = "secound.fxml";
@Override
public void start(@SuppressWarnings("exports") Stage primaryStage) {
ScreensController mainContainer = new ScreensController();
mainContainer.loadScreen(ScreensFramework.screen1ID, ScreensFramework.screen1File);
mainContainer.loadScreen(ScreensFramework.screen2ID, ScreensFramework.screen2File);
mainContainer.setScreen(ScreensFramework.screen1ID);
Group root = new Group();
root.getChildren().addAll(mainContainer);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
-
package minimalexample;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
public class Secound implements Initializable, ControlledScreen {
ScreensController myController;
ArrayList<String> daten ; //= myController.getdata();
int index;
boolean first=true;
@Override
public void initialize(URL url, ResourceBundle rb) {
initializeListeners();
ArrayList<String> list = new ArrayList<String>();
list.add("eins");
list.add("zwei");
list.add("drei");
//ArrayList<String> list = getfiles();
ObservableList<String> sf =FXCollections.observableArrayList (list);
listview.setItems(sf);
}
public ArrayList<String> getfiles () {
daten=myController.getdata();
for (String file:daten) {
System.out.println("getfiles: " +file);
}
return daten;
}
public void setScreenParent(ScreensController screenParent){
myController = screenParent;
}
@FXML
private ListView<String> listview;
@FXML
void onreihenfolgerichtig(ActionEvent event) {
ArrayList<String> abc = getfiles();
ObservableList<String> sf =FXCollections.observableArrayList (abc);
listview.setItems(sf);
first=false;
}
private void initializeListeners() {
listview.setOnDragDetected(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (listview.getSelectionModel().getSelectedItem() == null) {
return;
}
Dragboard dragBoard = listview.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putString(listview.getSelectionModel().getSelectedItem());
dragBoard.setContent(content);
index = listview.getSelectionModel().getSelectedIndex();
}
});
listview.setOnDragOver(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent dragEvent) {
dragEvent.acceptTransferModes(TransferMode.MOVE);
}
});
listview.setOnDragDropped(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent dragEvent) {
String player = dragEvent.getDragboard().getString();
listview.getItems().add(player);
listview.getItems().remove(index);
dragEvent.setDropCompleted(true);
}
});
}
}
module-info
package minimalexample;
import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.FileChooser;
import javafx.stage.FileChooser.ExtensionFilter;
public class Start implements Initializable, ControlledScreen {
ScreensController myController;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void setScreenParent(ScreensController screenParent){
myController = screenParent;
}
File existDirectory = null;
@FXML
private Font x3;
@FXML
private Color x4;
@FXML
void onfahrplancsv(ActionEvent event) {
FileChooser fileChooser = new FileChooser();
fileChooser.getExtensionFilters().add(new ExtensionFilter("CSV Dateien","*.csv"));
fileChooser.setTitle("CSV öffnen");
if(existDirectory != null)
fileChooser.setInitialDirectory(existDirectory);
List<File> f = fileChooser.showOpenMultipleDialog(null);
for (File file:f) {
existDirectory = file.getParentFile();
String test = file.getAbsolutePath();
System.out.println(test);
myController.addF(test);
}
myController.setScreen(ScreensFramework.screen2ID);
}
}
first.fxml
module minimalexample {
requires javafx.controls;
requires javafx.graphics;
requires javafx.fxml;
requires javafx.base;
requires jdk.compiler;
requires jdk.javadoc;
exports minimalexample;
opens minimalexample;
}
secound.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.paint.Color?>
<?import javafx.scene.text.Font?>
<VBox prefHeight="384.0" prefWidth="578.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="minimalexample.Start">
<children>
<MenuBar prefHeight="0.0" prefWidth="848.0" VBox.vgrow="NEVER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="New" />
<MenuItem mnemonicParsing="false" text="Open…" />
<Menu mnemonicParsing="false" text="Open Recent" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Close" />
<MenuItem mnemonicParsing="false" text="Save" />
<MenuItem mnemonicParsing="false" text="Save As…" />
<MenuItem mnemonicParsing="false" text="Revert" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Preferences…" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Quit" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Undo" />
<MenuItem mnemonicParsing="false" text="Redo" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Cut" />
<MenuItem mnemonicParsing="false" text="Copy" />
<MenuItem mnemonicParsing="false" text="Paste" />
<MenuItem mnemonicParsing="false" text="Delete" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Select All" />
<MenuItem mnemonicParsing="false" text="Unselect All" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About MyHelloApp" />
</items>
</Menu>
</menus>
</MenuBar>
<SplitPane dividerPositions="0.5" orientation="VERTICAL" VBox.vgrow="ALWAYS">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Button layoutX="14.0" layoutY="20.0" mnemonicParsing="false" onAction="#onfahrplancsv" prefHeight="120.0" prefWidth="119.0" text="CSV laden" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0" />
</items>
</SplitPane>
<HBox id="HBox" alignment="CENTER_LEFT" spacing="5.0" VBox.vgrow="NEVER">
<children>
<Label maxHeight="1.7976931348623157E308" maxWidth="-1.0" text="Left status" HBox.hgrow="ALWAYS">
<font>
<Font size="11.0" fx:id="x3" />
</font>
<textFill>
<Color blue="0.625" green="0.625" red="0.625" fx:id="x4" />
</textFill>
</Label>
<Pane prefHeight="-1.0" prefWidth="-1.0" HBox.hgrow="ALWAYS" />
<ComboBox prefHeight="25.0" prefWidth="294.0" />
</children>
<padding>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
</padding>
</HBox>
</children>
</VBox>