-1

I made an application in Scene Builder on one FXML. I am making a server with JavaFX so I can learn JavaFX and get more familiar with Java's networking libraries.

I have a server terminal Tab and additional tabs within a TabPane. I wanted to make classes that extend upon the main controller class to handle components in each tab.

While trying to implement this I found that the FXMLLoader won't be able to read things if the @FXML annotated variables are static. And the @FXML annotated event listener method won't be read if that is static either.

And if I try any kind of workaround I get nullpointerexceptions when trying to change text in the TextArea. I really don't want to have to use multiple FXML files but it's seeming like I'll have to because if I can't make these static then it just won't work.

Within the Server Terminal Tab there is a TextArea, a TextField, and a Button. Here's my working code:

 package me.Cronin.Keith.JavaServer;

 import java.io.IOException;
 import javafx.application.Application;
 import javafx.fxml.FXML;
 import javafx.fxml.FXMLLoader;
 import javafx.scene.Parent;
 import javafx.scene.Scene;
 import javafx.scene.control.Button;
 import javafx.scene.control.TextArea;
 import javafx.scene.control.TextField;
 import javafx.scene.input.MouseEvent;
 import javafx.stage.Stage;


public class JavaServer extends Application {

@FXML 
public Button btnSendCommand;
@FXML 
public TextField consoleInputField;
@FXML 
public TextArea serverTerminal;

public static FXMLLoader fxmlLoader = new FXMLLoader(JavaServer.class.getResource("JavaServer.fxml"));

public static void main(String[] args) 
{
    launch(args);
}

@Override
public void start(Stage stage) throws IOException
{
    Parent p = fxmlLoader.load();
    Scene scene = new Scene(p);
    stage.setTitle("Java Server v1.0");
    stage.setScene(scene);
    stage.show();
}

@FXML
public void clickSendCommand(MouseEvent event)
{
    serverTerminal.setText("I got clicked..");
}


}

Here's the other class that I don't know what to do with yet:

    package me.Cronin.Keith.JavaServer.Terminal;

    import me.Cronin.Keith.JavaServer.JavaServer;

  public class Terminal extends JavaServer {


  public static void logTerminal(String msg) 
  {

}

}

Is there anything I can do to change this to support what I want to do? I want to be able to control the variables (JavaFX Components from FXML) in JavaServer.class with my other classes that extend upon it.

I have seen this question here: Multiple controller for one FXML file

But it doesn't answer my question.

It's seeming like I'd have to put everything in the main controller class or have multiple Fxml files.

  • It's not really clear what you're trying to do. The `Application` class should not be a controller. There should be one controller class for each FXML file. If you want different components in different tabs, define an FXML file for each, with a controller class for each FXML file. I don't really see a scenario where the some controller classes would be subclasses of other controller classes. – James_D Nov 05 '17 at 00:41

1 Answers1

-1

I was able to make this work by replacing my Terminal class with this:

Terminal.java

   package me.Cronin.Keith.JavaServer.Terminal;

   import me.Cronin.Keith.JavaServer.JavaServer;

  public class Terminal extends JavaServer {


      public static void logTerminal(String msg) 
       {
         JavaServer mainController = fxmlLoader.getController();
         mainController.serverTerminal.setText(msg + "\n");
       }

}

So the answer is YES you can.

In JavaServer.java I just called Terminal.class statically and then used the static method logTerminal() within it which worked. I extended JavaServer.java in Terminal.java so I could statically call the controller's FXMLLoader.