JavaFX: How to update the center view of a borderpane with new values - eclipse

I am creating a program which has a row of buttons on the top, and a row of buttons on the side.
The top buttons control the view, and the side buttons control what object to reference in the view.
My main/root view is a borderpane.
The point is to, as I click on any of these buttons, to change a value in my MainController, and then reload the center view with these new values. I thought it would be so simple as to write a method that would change the value and then set a new center according to these values.
However, as I test it, it can display the two values I have already asked it to display, but gives me a huge load of red error code whenever I run.
My MainViewController looks as follows:
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class MainViewController extends Application {
#FXML
private Button cabin1;
#FXML
private Button cabin2;
#FXML
private Button tab1;
#FXML
private Button tab2;
#FXML
public void setCabinOne() throws IOException {
cabinIndex=1;
setCenterView();
}
#FXML
public void setCabinTwo() throws IOException {
cabinIndex=2;
setCenterView();
}
#FXML
public void setTabOne() throws IOException {
tabIndex=1;
setCenterView();
}
#FXML
public void setTabTwo() throws IOException {
tabIndex=2;
setCenterView();
}
public int getCabinIndex() {
return cabinIndex;
}
public int getTabIndex() {
return tabIndex;
}
private int tabIndex=0;
private int cabinIndex=1;
public Stage primaryStage;
private BorderPane mainPane;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage=primaryStage;
primaryStage.setTitle("Test");
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainViewController.class.getResource("MainView.fxml"));
mainPane = loader.load();
setCenterView();
Scene scene = new Scene(mainPane);
primaryStage.setScene(scene);
primaryStage.show();
}
public void setCenterView() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainViewController.class.getResource("TestView.fxml"));
AnchorPane testPane = loader.load();
TestViewController tvc = loader.<TestViewController>getController();
tvc.changeLabel(getCabinIndex());
tvc.changeIndex(getTabIndex());
mainPane.setCenter(testPane);
}
}
and my TestViewController looks as follows:
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class TestViewController {
#FXML
private Label cabinIndex;
#FXML
private Label tabIndex;
public void initialise() {
this.changeLabel(0);
this.changeIndex(0);
}
public void changeLabel(int n) {
cabinIndex.setText("Cabin "+Integer.toString(n));
}
public void changeIndex(int n) {
tabIndex.setText("Tab "+Integer.toString(n));
}
}
What am I doing wrong?

Your application is basically structurally wrong: you are using the application subclass as the controller, and this simply won't work (at least, not easily). You need to refactor this with a startup class (subclass of Application) that is distinct from the controller. Virtually any complete example will work as a template for you, but the Oracle tutorial is a good place to start.
What is happening is as follows:
When you call Application.launch() in MainViewController.main(...), the FX toolkit is started, an instance of your application class MainViewController is created, the FX Application Thread is started, and the start() method belonging to the MainViewController instance is invoked on the FX Application Thread.
When you call the FXMLLoader's load() method, it parses the FXML file at the specified location. When it sees the fx:controller attribute, which I'm assuming is fx:controller="MainViewController", it creates an instance of the specified controller class. Once the FXML is parsed, any matching #FXML-annotated fields (belonging to that instance) are initialized with the corresponding objects from the FXML file, and then the initialize() method is called on that instance.
So notice now you actually have two instances of MainViewController: the one from which FXMLLoader.load() was called, and the one created by the FXMLLoader. The #FXML-annotated fields in the instance created by the FXMLLoader are initialized, but the ones in the original instance remain set to the default value of null. Conversely, the mainPane field is initialized in the start method in the original MainViewController instance, but is never initialized in the instance created by the FXMLLoader. So when you press the button and invoke setCenterView() (I assume this is how your FXML is set up), you end up calling mainPane.setCenter() when mainPane is still null.
You could probably just about force it to work like this. Something like: remove the fx:controller attribute from MainView.fxml, and call loader.setController(this). But when you stray that far from the usual patterns used by a framework, your code becomes hard to maintain and debug. I would recommend following the design intended by the API.

Related

JavaFx Change main class to another main class (seperate class)

I'm new to JavaFx and have to create a small game. My JavaFx classes works fine but I can't figure out have to change between them. I created a package in eclipse where I have all the display classes (Menu screen class, lauding Screen class, Game display...). Every classes has their main and display fine. But now I can't change from one class to another class. Like from Start menu to game display. I tried initiating the game display class in the menu class and then setScene to game display's scene but it does not work. I'm also confused with either I have to change from stage, scenes or panes.
#Override
public void start(Stage primaryStage) throws Exception {
stage = primaryStage;
scene = new Scene(createContent());
primaryStage.setTitle("Menu Screen");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
2nd Class:
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Bucanneer");
// Setting up Stage, Scene and root
// Group root = new Group();
theScene = new Scene(createContent());
primaryStage.setScene(theScene);
primaryStage.setResizable(true);
primaryStage.show();
}
Last try:
I put this in the menu class when you press a button
private void backToMenu(){
Test test = new Test();
stage.setScene(test.getTheScene());
}
Any advice plz, all I can find are with FXML..
Ps: Sorry for bad english. Not my native language.

How to position controls binding there position into the stage's size using the controller class in JavaFx?

I found some thing similar in this link
How to call functions on the stage in JavaFX's controller file
and here is what I found in one of the answers
StageTrackingSample.java
public class StageTrackingSample extends Application {
#Override public void start(final Stage stage) throws Exception {
final FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"stagetracking.fxml"
)
);
final Parent root = (Parent) loader.load();
final StageTrackingController controller = loader.getController();
controller.initData(stage);
stage.setScene(new Scene(root));
stage.show();
}
public static void main(String[] args) { launch(args); }
}
StageTrackingController.java
public class StageTrackingController {
#FXML private Label stageX;
public void initialize() {}
public void initData(final Stage stage) {
stageX.textProperty().bind(
Bindings.format(
"(%1$.2f, %2$.2f)",
stage.xProperty(),
stage.yProperty()
)
);
}
}
I wanted to position the progressIndicator in the middle of the window, so I tried this in my controller class
Controller.java
public void initInterface(Stage stage) {
progressIndicator.layoutXProperty().bind(stage.widthProperty().divide(2));
progressIndicator.layoutYProperty().bind(stage.heightProperty().divide(2));
}
and this in Main.java
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
final FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
final Parent root = loader.load();
final Controller controller = loader.getController();
final Scene scene = new Scene(root);
controller.initInterface(primaryStage);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
it doesn't work even when I tried passing the scene or the anchorpane(which is defined in the fxml file) as a parameter into initInterface method, it seems that it has problem with binding progressIndicator properties
by using the layoutXProperty and layoutYProperty and binding them to the Stage's width and height you must be trying to put it in the lower right hand corner of the stage. You can achieve this much easier, and JavaFX insists you do so, by using layouts in your scene and making the scene fill the entire area in question.
"From the Javadocs for the layoutX property:
If the node is managed and has a Region as its parent, then the layout region will set layoutX according to its own layout policy. If the node is unmanaged or parented by a Group, then the application may set layoutX directly to position it.
What this means is that the LayoutX/Y properties are controlled by the parent (and so it should be able to 'set' them). However, when you bind them they cannot be set anymore resulting in " A bound value cannot be set" exception."
Here is a good tutorial on regions and how to get things to layout in SceneBuilder as you please. If you're not using SceneBuilder I recommend it.
https://www.youtube.com/watch?v=zvgWgpGZVKc&list=PL6gx4Cwl9DGBzfXLWLSYVy8EbTdpGbUIG&index=35

JFrame and JPanel problems with calling between

package pozivanjeProzora;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class MainPanel extends JPanel {
SidePanel panel ;
MainWindow instanca;
public MainPanel()
{
super();
JButton button = new JButton("Pozdrav iz main panela");
add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
instanca.add(panel);
}
});
}
}
So, I extend JFrame in my MainWindow and I created instance of it. I am in MainPanel class which is called in MainWindow right now. But if I come in MainPanel and if I click on this button I want to my MainWindow(which extends JFrame) to add panel from SidePanel class(which has one button and extends JPanel also).
But if I click on button it shows me only NullPointerException. Where is my foult? MainWindow only has couple of lines about location of window and visible and I added MainPanel there as a first panel when I run my program. But, when I call another panel from MainPanel and when I try to add that panel with instance of MainWindow it shows error.
Your variable instanca is never initialised. Perhaps pass it in the constructor.
i.e.
public MainPanel(MainWindow mainWindow)
{
instanca = mainWindow;

GWT editor frame work is not working

I have a bean named SignUpBean and it's editor is SignUpBeanEditor and following is its Driver interface.
public interface SignUpDriver extends SimpleBeanEditorDriver<SignUpBean, SignUpEditor>{
}
Following is entry point class
public class Signup implements EntryPoint {
private SignUpDriver signUpDriver;
private SignUpEditor signUpEditor;
private SignUpBean signUpBean;
private VerticalPanel verticalPanel;
private Label signUpLbl;
private Button submitButton;
private Button cancelButton;
private RequestBuilder requestBuilder;
final SignUpConverter signUpConverter=GWT.create(SignUpConverter.class);
public void onModuleLoad() {
signUpLbl = new Label("Sign Up");
signUpDriver = GWT.create(SignUpDriver.class);
signUpBean = new SignUpBean();
signUpEditor = new SignUpEditor();
submitButton = new Button("Submit");
cancelButton = new Button("Cancel");
signUpDriver.initialize(signUpEditor);
signUpDriver.edit(signUpBean);
System.out.println(signUpBean.getUserName());
submitButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
SignUpBean signUpBeanEdited=signUpDriver.flush();
}
}
}
}
I am getting only null value from signUpBeanEdited after giving value in UI. If i am initializing SignUpBean with constructor then also data is not binding to UI. My problem is I cant bind data in GWT UI using editor framework.
The fields( sub editors ) declared in SignUpEditor should be of at least DEFAULT scope. I guess you declared them as private. If so, the Editor Impl classes generated cannot access the fields to bind the data.
Changing scope to at least DEFAULT might solve your problem.

accessing array with object

hi i have two classes in android and in one class i have write an array and i want to access it in the main class but the error is give me that "force closed" here is my code
package com.semanticnotion.DAO;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class DAO extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
WordsDAO DAO = new WordsDAO(new String[] "Arte","Arquitectura","Familia","Moda","Cotilleos","Cine","Libros","Historia","Pintura","Musica","Tendencies","Modernimso","Pop art","Masteialismo","realities","filosofia","moda","fotografia","religion"});
Button next = (Button) findViewById(R.id.Button01);
next.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent myIntent = new Intent(view.getContext(), WordsDAO.class);
startActivity(myIntent);
}
});
}
}
and the second class code is
package com.semanticnotion.DAO;
public class WordsDAO
{
String[] words = new String[] "Arte","Arquitectura","Familia","Moda","Cotilleos","Cine","Libros","Historia","Pintura","Musica","Tendencies","Modernimso","Pop art","Masteialismo","realities","filosofia","moda","fotografia","religion"};
public WordsDAO(String[] words )
{
this.words=words;
}
}
please any one tell what well be the error in this code thaks
First of all: the constructor in your second class would not be used. The way to pass parameters to another activity is to use Intent.putExtra in the code calling the other activity and in your other activity use
Bundle extras = getIntent().getExtras();
if(extras !=null)
{
String value = extras.getString("keyName");
}
to get the data in onCreate.
That said, I guess the problem arises from your second class not providing an explicit parameterless constructor.