I get this error message, when i try calling a method "undo" in the object invoker of class Invoker:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at view.MainWindow.lambda$2(MainWindow.java:112)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.control.MenuItem.fire(MenuItem.java:462)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$343(ContextMenuContent.java:1358)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Unknown Source)
I'm guessing the problem has to do with the javafx thread? I have tried using Platform.runLater, but the problem persisted.
I'm launching a JavaFX window through this:
public static void main(String[] args) {
Board board = new Board();
Invoker invoker = new Invoker();
TileBoardController tbc = new TileBoardController();
MainWindow mainWindow = new MainWindow();
com.sun.javafx.application.PlatformImpl.startup(()->{});
mainWindow.launch(board, tbc.CreateTiles(board), invoker);
com.sun.javafx.application.PlatformImpl.exit();
}
And the event that crashes the program lies in a menu bar in that "MainWindow" class:
menuOptions.setOnAction(e -> invoker.undo());
Strange thing is, the invoker class works, and is successfully used in another part of the same "MainWindow" object:
tileBoardStatic[rank][file].setOnAction( e -> this.onTileClick(finalRank, finalFile));
private void onTileClick(int rank, int file) {
invoker.storeAndExecute(new MovePiece(board, activeTile.getSquare(), tileBoardStatic[rank][file].getSquare()));
}
I have tried invoker.undo() in that same method, and that works.
Anyone know what the problem is here?
Here is all the code in MainWindow:
public class MainWindow extends Application{
public static final int TILE_SIZE = 100;
public static final int WIDTH = 8;
public static final int HEIGHT = 8;
private Invoker invoker;
private static Group tileGroup = null;
private static Tile[][] tileBoardStatic = null;
private Tile activeTile;
private Board board;
public void launch(Board board, Tile[][] tileBoard, Invoker invoker) {
this.board = board;
this.tileBoardStatic = tileBoard;
this.invoker = invoker;
tileGroup = new Group();
for (int rank=0; rank<tileBoard.length; rank++) {
for(int file=0; file<tileBoard[rank].length; file++) {
final int finalRank = rank;
final int finalFile = file;
tileBoardStatic[rank][file].setOnAction( e -> this.onTileClick(finalRank, finalFile));
tileGroup.getChildren().add(tileBoard[rank][file]);
}
}
Application.launch(MainWindow.class);
}
//Handles click event for Tiles
private void onTileClick(int rank, int file) {
if (activeTile == null) {
if (tileBoardStatic[rank][file].getSquare().getPiece() == null)
System.out.println("No piece in tile");
else {
if(tileBoardStatic[rank][file].getSquare().getPiece().isWhite() != board.getTurnIsWhite()) {
System.out.println("Not your turn");
} else {
activeTile = tileBoardStatic[rank][file];
activeTile.getStyleClass().add("tile-clicked");
}
}
}
else {
activeTile.getStyleClass().removeAll("tile-clicked");
//Creates and sends command to invoker
invoker.storeAndExecute(new MovePiece(board, activeTile.getSquare(), tileBoardStatic[rank][file].getSquare()));
//Repaints squares
activeTile.paintSquare();
tileBoardStatic[rank][file].paintSquare();
activeTile = null;
}
}
#Override
public void start(Stage primaryStage) throws Exception {
BorderPane root = new BorderPane();
primaryStage.getIcons().add(new Image(MainWindow.class.getResourceAsStream("resources/chess.png")));
root.getChildren().addAll(tileGroup);
root.setPrefSize(WIDTH * TILE_SIZE, HEIGHT * TILE_SIZE);
Scene scene = new Scene(root);
primaryStage.setTitle("MainWindow");
primaryStage.setScene(scene);
scene.getStylesheets().add(MainWindow.class.getResource("resources/stylesheet.css").toExternalForm());
//Menu bar
MenuBar menuBar = new MenuBar();
Menu gameMenu = new Menu("Game");
menuBar.getMenus().add(gameMenu);
MenuItem menuExit = new MenuItem("Exit game");
menuExit.setOnAction(e -> exit());
gameMenu.getItems().add(menuExit);
Menu menuOptions = new Menu("Edit");
MenuItem menuUndo = new MenuItem("Undo");
menuOptions.setOnAction(e -> invoker.undo());
menuOptions.getItems().add(menuUndo);
menuBar.getMenus().add(menuOptions);
root.setTop(menuBar);
primaryStage.show();
}
private void exit() {
Platform.exit();
System.exit(0);
}
}
You're launching your application incorrectly. Your main method initializes some objects, including an instance of MainWindow. You then call a method on said instance of MainWindow which sets some fields then calls Application.launch. This is where the problem manifests: The call to Application.launch results in a new, separate instance of MainWindow to be created. It is this instance that is used by the JavaFX runtime.
Since the start(Stage) method is invoked on an instance other than the one you called launch(Board,Tile[][],Invoker) on, none of the instance fields are set properly; this ultimately leads to your NullPointerException. Your solution to make invoker static merely covers up a symptom of the larger problem—initializing objects outside the typical life-cycle.
Try changing your main method to the following:
public static void main(String[] args) {
Application.launch(MainWindow.class, args);
}
Note: If the main method is inside the Application subclss, you can use launch(args) instead.
Then move all the initializing logic to ether Application#init() or Application#start(Stage) (or at least call the appropriate method(s) from inside one of them). Any initializing that requires the JavaFX Application Thread should be done in the start method; the init method is called on the JavaFX-Launcher thread.
Also, using Application.launch will implicitly startup the JavaFX runtime. There's no reason for you to manually call PlatformImpl.startup. You should also avoid using internal code (e.g. com.sun.*) unless there's no other option. If you find yourself needing to use internal code, take a step back and check if you're perhaps doing something wrong.
Fixed! All i had to do was to set my invoker object to static, of course. Stupid miss.
private static Invoker invoker;
Related
I would like to do a small test using JavaFX and Serenity BDD, unfortunately with failure.
-when my code calls manually from the "TestSer" class it works fine.
-when calls from the GUI unfortunately does not work.
It seems to me that I am making a simple mistake with calling this class but I lack this knowledge
I present to you my code and please help.
Test class
#RunWith(SerenityRunner.class)
public class TestSer extends PageObject {
public Logger logger = LoggerFactory.getLogger(this.getClass());
#Managed
public WebDriver driver;
#FindBy(id = "b-7")
private WebElementFacade inputNumber;
#FindBy(id = "b-8")
private WebElementFacade buttonCheck;
#FindBy(id = "b-9")
private WebElementFacade buttonClean;
#FindBy(id = "caption2_b-3")
private WebElementFacade result;
Page page = new Page();
String[] arr = {"1230391507", "1230943800","1230705176", "1230943800", "1231069185", "1230500907", "1231079746"};
#Test
public void dodo() throws Exception {
page.open();
for (int i = 0; i < arr.length; i++) {
page.check( arr[i] );
System.out.println( arr[i] );
}
}
public void check(String numer) throws Exception {
String teraz = Teraz();
waitFor( inputNumber ).waitUntilEnabled();
inputNumber.type( numer );
waitFor( buttonCheck ).isClickable();
buttonCheck.click();
this.takeSnapShot(getDriver(), "C:\\Users\\smyha\\OneDrive\\Pulpit\\z\\"+numer+ teraz+ ".png") ;
waitFor( buttonClean ).isClickable();
buttonClean.click();
pause( 2000 );
}
public static void takeSnapShot(WebDriver webdriver, String fileWithPath) throws Exception{
TakesScreenshot scrShot =((TakesScreenshot)webdriver);
File SrcFile=scrShot.getScreenshotAs( OutputType.FILE);
File DestFile=new File(fileWithPath);
FileUtils.copyFile(SrcFile, DestFile);
}
public void pause(Integer milliseconds){
try {
TimeUnit.MILLISECONDS.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public String Teraz (){
Date date = new Date(); //
SimpleDateFormat hh = new SimpleDateFormat("HH");
SimpleDateFormat mm = new SimpleDateFormat("mm");
SimpleDateFormat ss = new SimpleDateFormat("ss");
String h = hh.format(date);
String m = mm.format(date);
String s = ss.format(date);
String teraz = "_"+h+"_"+m+"_"+s;
return teraz;
}
Controller class
#RunWith(SerenityRunner.class)
public class Controller implements Initializable {
public static final String dane = "1230391507\n" +
"1230500907\n" +
"1230705176\n" +
"1230943800\n" +
"1231069185\n" +
"1231079746\n";
public String [] arr ;
public String outDir;
private Window stage;
public String dirdir;
public String[] getArr() {
return arr;
}
public void setArr(String[] arr) {
this.arr = arr;
}
#FXML
private JFXTextArea txtFiield;
#FXML
private JFXTextField txtWhere;
#FXML
private JFXButton btnWhere, btnRun;
#Override
public void initialize(URL location, ResourceBundle resources) {
txtFiield.setText( dane );
}
public void doWhere(ActionEvent actionEvent) {
DirectoryChooser directoryChooser = new DirectoryChooser();
File selectedDirectory = directoryChooser.showDialog(stage);
if(selectedDirectory == null){
}else{
txtWhere.setText( selectedDirectory.getAbsolutePath() + "\\");
dirdir = selectedDirectory.getAbsolutePath() + "\\";
}
if (txtFiield.getLength() >0 && txtWhere.getLength() >0){
// btnWhere.setDisable( false );
btnRun.setDisable( false );
}
}
#Test
public void doRun(ActionEvent actionEvent) throws Exception {
TestSer t = new TestSer();
t.dodo();
}
public void parseField(String wejsciowe){
setArr( null );
setArr( wejsciowe.split( "\n" ));
System.out.println(arr.length);
String[] a = getArr();
for(int i = 0; i < a.length; i++){
if(a[i].length() != 10){
infoBox( "nieprawidłowa długość NIPu w lini : ", "Niepoprawne dane", "Błąd", i+1 );
}
}
}
public static void infoBox(String infoMessage, String headerText, String title, int line){
Alert alert = new Alert( Alert.AlertType.CONFIRMATION);
alert.setContentText(infoMessage + line);
alert.setTitle(title);
alert.setHeaderText(headerText);
alert.showAndWait();
}
}
Errors:
log4j:WARN No appenders could be found for logger (net.thucydides.core.util.PropertiesFileLocalPreferences).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 52 more
Caused by: java.lang.NullPointerException
at net.serenitybdd.core.pages.PageObject.openPageAtUrl(PageObject.java:902)
at net.serenitybdd.core.pages.PageObject.open(PageObject.java:803)
at net.serenitybdd.core.pages.PageObject.open(PageObject.java:791)
at com.sub.serenity.TestSer.dodo(TestSer.java:48)
at com.sub.Controller.doRun(Controller.java:81)
... 62 more
I don't have time to search and I took a shortcut. I ran the test from the console.
public void cmd(String command) throws IOException {
ProcessBuilder builder = new ProcessBuilder(
"cmd.exe", "/c", "cd \"C:\\Program Files\\Microsoft SQL Server\" &&" + command);
builder.redirectErrorStream(true);
builder.start();
}
and...
#Test
public void doRun(ActionEvent actionEvent) throws Exception {
infoBox( "Czyszczenie projektu SerenityBDD ", "Krok 1- prosze czekac", "Uwaga", 1);
cmd("mvn clean");
infoBox( "Wykonanie testu", "Krok 2 - prosze czekac ", "Uwaga", 2 );
cmd("mvn clean verify");
}
In this way, at the moment I was able to test correctly, but in a very ugly way
I'm having trouble while switching scene and controller for my app using fxml views. At first I have login view and then I want to switch to lobby view and I don't how should I make it. I try to create object of new controller and load fxml file in its constructor but then I have LoadException and I can't figure out how to fix it.
Main App:
public class Client extends Application {
#Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("LoginView.fxml"));
Parent root = (Parent) loader.load();
Scene scene = new Scene(root,300,400);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
LoginController:
private void loginSuccess() {
//some login code
if (result.get() == buttonContinue){
proceedToLobby();
}
}
private void proceedToLobby() {
LobbyController lobbyController = new LobbyController(stage);
}
LobbyController:
public LobbyController(Stage stage) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("LobbyView.fxml"));
Parent root = (Parent) loader.load();
Scene scene = new Scene(root,600,400);
this.stage = stage;
this.stage.setScene(scene);
this.stage.setResizable(false);
this.stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
LoadException:
javafx.fxml.LoadException:
/C:/Users/student/eclipse-workspace/Pai-Roulette-Game/bin/roulette/client/LobbyView.fxml:9
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:932)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at roulette.client.LobbyController.<init>(LobbyController.java:33)
at roulette.client.LoginController.proceedToLobby(LoginController.java:78)
at roulette.client.LoginController.loginSuccess(LoginController.java:69)
at roulette.client.LoginController.buttonClicked(LoginController.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.Trampoline.invoke(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1771)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8413)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Unknown Source)
LobbyView 9th line:
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="roulette.client.LobbyController">
Its not a good idea to load the view from the Controller's constructor. As James_D pointed out, the loader creates a controller upon loading, which in your case then creates a new loader and the loop continues.
May I suggest you simply load the scene in your proceedToLobby() method? Something like this:
private void proceedToLobby() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("LobbyView.fxml"));
Parent root = (Parent) loader.load();
LobbyController fooController = (LobbyController ) fxmlLoader.getController();
fooController.setStage(stage); // create this method if you need to use the stage
Scene scene = new Scene(root,600,400);
// these lines may not be necessary since the stage is already showing
stage.setScene(scene);
stage.setResizable(false);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
And then your controller constructor should be like this:
public LobbyController() {
}
If you need the controller to do stuff, then you can retrieve it from the loader as in the example above and create other public methods for the functionality.
EDIT: As stated in the comments, the loader expects an empty constructor which causes the error. Its not caused by constructing the view from the controller class.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
What is a stack trace, and how can I use it to debug my application errors?
(7 answers)
Closed 5 years ago.
I'm stuck and need some advice. I keep getting NullPointerExceptions while calling getText on my TextField and PasswordField. I'm using fxml files to create the UI, and scene builder as well.
Code :
public class LoginScreenController {
private Model model;
private final String userName = "Kazam";
private final String userPassword = "Kazam420";
#FXML
TextField login_txt;
#FXML
PasswordField password_txt;
#FXML
private MainScreenController mainscreencontroller;
#FXML
Pane loginScreen;
#FXML
public void Login() {
/* FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/Options.fxml"));
Pane pane = null;
String name = login_txt.getText();
String password = password_txt.getText();
if (name.equals(userName) && password.equals(userPassword)) {
try {
pane = loader.load();
} catch (IOException ex) {
ex.printStackTrace();
}
OptionsScreenController optionsScreenController = loader.getController();
optionsScreenController.setMainScreenController(mainscreencontroller);
mainscreencontroller.setScreen(pane);
}*/
model.login();
}
public void setScreen(Pane pane){
loginScreen.getChildren().clear();
loginScreen.getChildren().add(pane);
}
public void setMainScreenController(MainScreenController mainscreencontroller) {
this.mainscreencontroller = mainscreencontroller;
}
public String getPassword(PasswordField password_txt){
String password = password_txt.getText();
return password;
}
public String getLogin(TextField login_txt) {
String login = login_txt.getText();
return login;
}
}
public class Model {
private LoginScreenController loginScreenController;
private final String userName = "Kazam";
private final String userPassword = "Kazam420";
#FXML
private MainScreenController mainscreencontroller;
#FXML
private TextField login_txt;
#FXML
private PasswordField password_txt;
String name = loginScreenController.getLogin(login_txt);
String password = loginScreenController.getPassword(password_txt);
public void login(){
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/Options.fxml"));
Pane pane;
if (name.equals(userName) && password.equals(userPassword) ){
try {
pane = loader.load();
mainscreencontroller.setScreen(pane);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
The commented code in the controller works fine. I want to put this logic in my model. If i did something wrong please be gentle. I'm a beginner both in coding and stackoverflow.
StackTrace :
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8413)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1771)
... 45 more
Caused by: java.lang.NullPointerException
at Controllers.LoginScreenController.Login(LoginScreenController.java:61)
... 55 more
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 15.783s
Finished at: Mon May 22 15:36:21 CEST 2017
Final Memory: 20M/182M
------------------------------------------------------------------------
I have 4 ComboBox in each of them there are 5 elements: " ", "1", "2", "3", "4".
I have to make if the item "1" is selected in a ComboBox, it is automatically excluded from other .And if the item " " is selected in the ComboBoxinsame
it is automatically returned to the other. So same need for other items except " ".
I tried to do this Here's the code:
public void vubadditems(ComboBox<String> vub1,ComboBox<String> vub2,ComboBox<String> vub3,ComboBox<String> vub4){
vub1.getItems().addAll(" ","1","2","3","4");
vub2.getItems().addAll(" ","1","2","3","4");
vub3.getItems().addAll(" ","1","2","3","4");
vub4.getItems().addAll(" ","1","2","3","4");
}
public void vubact(ComboBox<String> vub1,ComboBox<String> vub2,ComboBox<String> vub3,ComboBox<String> vub4){
if(vub1.getSelectionModel().getSelectedItem()!=" "){
vub2.getItems().remove(vub1.getSelectionModel().getSelectedItem());
vub3.getItems().remove(vub1.getSelectionModel().getSelectedItem());
vub4.getItems().remove(vub1.getSelectionModel().getSelectedItem());
s=vub1.getSelectionModel().getSelectedItem();
}else{
}
if(vub2.getSelectionModel().getSelectedItem()!=" "){
vub1.getItems().remove(vub2.getSelectionModel().getSelectedItem());
vub3.getItems().remove(vub2.getSelectionModel().getSelectedItem());
vub4.getItems().remove(vub2.getSelectionModel().getSelectedItem());
}
if(vub3.getSelectionModel().getSelectedItem()!=" "){
vub1.getItems().remove(vub3.getSelectionModel().getSelectedItem());
vub2.getItems().remove(vub3.getSelectionModel().getSelectedItem());
vub4.getItems().remove(vub3.getSelectionModel().getSelectedItem());
}
if(vub4.getSelectionModel().getSelectedItem()!=" "){
vub1.getItems().remove(vub4.getSelectionModel().getSelectedItem());
vub2.getItems().remove(vub4.getSelectionModel().getSelectedItem());
vub3.getItems().remove(vub4.getSelectionModel().getSelectedItem());
}
}
public void vubq1ac(){
vubact(q1vub1,q1vub2,q1vub3,q1vub4);
}
public void initialize(){
vubadditems(q1vub1,q1vub2,q1vub3,q1vub4);
vubadditems(q2vub1,q2vub2,q2vub3,q2vub4);
vubadditems(q3vub1,q3vub2,q3vub3,q3vub4);
vubadditems(q4vub1,q4vub2,q4vub3,q4vub4);
vubadditems(q5vub1,q5vub2,q5vub3,q5vub4);
}
q1vub1, q1vub2, q1vub3, q1vub4 is loaded from FXML_file ComboBox's
I add vubq1ac as action listiner on ComboBox
But I have some Exception and program works incorrect
Exception:
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException
at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.subList(ReadOnlyUnbackedObservableList.java:136)
at javafx.collections.ListChangeListener$Change.getAddedSubList(ListChangeListener.java:242)
at com.sun.javafx.scene.control.behavior.ListViewBehavior.lambda$new$177(ListViewBehavior.java:269)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:75)
at javafx.scene.control.MultipleSelectionModelBase.clearAndSelect(MultipleSelectionModelBase.java:378)
at javafx.scene.control.ListView$ListViewBitSetSelectionModel.clearAndSelect(ListView.java:1403)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.simpleSelect(CellBehaviorBase.java:256)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.doSelect(CellBehaviorBase.java:220)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:150)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:380)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:416)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Unknown Source)
If you follow your current approach your code will be quite long and rather hard to debug. Currently it seems that:
You only remove and never return items.
You don't store the previously selected value. Imagine that in your first ComboBox "1" was selected (and subsequently, excluded from other components), and you decide to change it back to " ". You can't get the previous value directly from the ComboBox, because .getSelectedItem() will only return the current value, which would be " " already.
I'll present you my approach and tell you briefly how it works.
public class JavaFXApplication extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage primaryStage) {
FlowPane root = new FlowPane();
ArrayList<String> items = new ArrayList<>();
Collections.addAll(items, " ", "1", "2", "3", "4");
List<ComboBox> comboBoxList = new ArrayList<>();
for (int i = 0; i < 4; i++) {
ComboBox c = new ComboBox(FXCollections.observableArrayList(items));
c.setValue(c.getItems().get(0));
c.valueProperty().addListener(removeFromOtherCombo(comboBoxList, c));
comboBoxList.add(c);
}
root.getChildren().addAll(comboBoxList);
Scene scene = new Scene(root, 200, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
public static ChangeListener removeFromOtherCombo(List<ComboBox> boxes, ComboBox current) {
return (o, oldVal, newVal) -> {
if (newVal.equals(oldVal)) {
return;
}
if (!oldVal.equals(" ")) {
boxes.stream()
.filter(c -> !c.equals(current))
.forEach((ComboBox) -> {
ComboBox.getItems().add(oldVal);
});
}
if (!newVal.equals(" ")) {
boxes.stream()
.filter(c -> !c.equals(current))
.forEach((ComboBox) -> {
ComboBox.getItems().remove(newVal);
});
}
};
}
}
For each ComboBox I create a ChangeListener that's aware of every other ComboBox and the ComboBox to which it's assigned.
c.valueProperty().addListener(removeFromOtherCombo(comboBoxList, c));
The ChangeListener is notified every time you pick a new value, and fortunately for us it receives both old and new value.
If old value is equal to new value then there's nothing for us to do.
if (newVal.equals(oldVal)) {
return;
}
If old value is a number (e.g. we're changing from "1" to "2") then we have to return the previously selected number to every ComboBox except one, which was filtered.
if (!oldVal.equals(" ")) {
boxes.stream()
.filter(c -> !c.equals(current))
.forEach((ComboBox) -> {
ComboBox.getItems().add(oldVal);
});
}
The same approach is taken when we're changing to a number, but this time we have to remove it from every ComboBox except one.
I´m trying to display an image on a new windows when I click on a rectangle of my main stage but I receive the following error: "Exception in thread "JavaFX Application Thread" java.lang.NullPointerException"
First controller (ControllerImpl) initializes second controller (ControllerImage) and calls one of its methods (controllerImage.displayImageSel):
#FXML
private ControllerImage controllerImage = new ControllerImage();
public void rectangleSave(Rectangle r, String imagePath) {
r.setOnMousePressed((event) -> {
try {
Stage imageStage = new Stage();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/images.fxml"));
Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds();
imageStage.setX(0);
imageStage.setY(0);
imageStage.setHeight(primScreenBounds.getHeight());
imageStage.setWidth(primScreenBounds.getWidth() * 0.7);
imageStage.setTitle("JavaFX Scene Graph Demo");
Scene scene = new Scene(loader.load());
imageStage.setScene(scene);
imageStage.show();
controllerImage.displayImageSel(imagePath);
} catch (IOException e) {
System.out.println("Me cago en el PP");
}
});
}
Second controller contains a stack pane and method called by ControllerImpl:
#FXML
public StackPane Spi;
public void displayImageSel(String imagePath) {
Rectangle ri = new Rectangle();
Spi.getChildren().add(ri);
Image image = new Image(new File(imagePath).toURI().toString());
ri.setFill(new ImagePattern(image));
}
Of course Spi is defined in FXML file:
<StackPane fx:id="Spi"......
Problem is ControllerImage can't find StackPane Spi. I´ve been implementing all kind of solutions I found related to this but no one has worked so far.
Thanks for your help!
EDIT: new error message
javafx.fxml.LoadException: Root value already specified.
/C:/tutorial-app/tutorial-app/target/resources/main/images.fxml
/C:/tutorial-app/tutorial-app/target/resources/main/images.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2597)
at javafx.fxml.FXMLLoader.createElement(FXMLLoader.java:2755)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2704)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at tutorial.controller.impl.ControllerImpl.lambda$rectangleSave$1(ControllerImpl.java:146)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:388)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
You are creating controllerImage yourself, not through FXMLLoader, so the FXML fields never get injected. You also never call load on that loader. Edit: Oops, you do, I just missed it.
Assuming you have the fx:controller set correctly in "images.fxml", remove the assignment of controllerImage and add this line after the call to FXMLLoader#load:
controllerImage = loader.getController();
If you don't have fx:controller set in the FXML you can either set it to the correct class, or instead pass the instance you create to the loader before loading:
loader.setController(controllerImage);
In this case you would of course keep the initialization of controllerImage.