Cannot find symbol error when calling method from different class file - java

I'm trying to call a method form a separate class file to my main program java file but when I try to call the method on an object, I get the error symbol cannot be found for the method. Both files are in the same directory.
//This is my main java file for the program
package pwmanager;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author 176878
*/
public class PWManager extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Login.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Password Manager");
stage.setPrevStage(); //Error occurs here.
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
//This is the other .java file where the method is declared.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package pwmanager;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventType;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javax.xml.crypto.Data;
/**
*
* #author 176878
*/
public class FXMLDocumentController implements Initializable {
#FXML
private Button loginButton;
private Button addAcct;
private Button removeAcct;
#FXML
public Stage prevStage;
public Stage currentStage;
#FXML
public void loginButtonAction(ActionEvent event) throws IOException {
System.out.println("You clicked me, logging in!");
Stage stage = new Stage();
FXMLLoader loader = new FXMLLoader(getClass().getResource("MainScreen.fxml"));
Parent mainScreen = (Parent)loader.load();
Scene scene = new Scene(mainScreen);
stage.setScene(scene);
stage.setTitle("Password Manager");
//prevStage.close();
stage.show();
}
#FXML
public void addAcctAction(ActionEvent event) throws IOException {
System.out.println("You clicked me, adding account!");
}
#FXML
public void removeAcctAction(ActionEvent event) throws IOException {
System.out.println("You clicked me, removing account!");
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
I need to store the current stage so I can call it back or close the stage out.

setPrevStage is defined in FXMLDocumentController not Stage. You need to inject the former into the main PWManager class so that it can be invoked
controller.setPrevStage(stage);

Related

Cannot get both radio buttons to pass values to ObaservableList Java?

I am in the process of learning Java and I can't seem to make this function work. I am working on a project for an inventory system. Where parts are added to an observable list. In the add part screen, I have two radio buttons to select whether the part is an InHouse made or OutSourced. I have an if statement using a toggle group to check which radio button is selected. I was trying to use an else statement to pass the values if it was an outsourced part. Right now it will pass the values correctly if the radio button is set to InHouse, but when set to Outsource it throws a null pointer exception at the line the if statement is on.
Here is the code I am trying to make work.
package ViewController;
import Model.InHouse;
import Model.Inventory;
import Model.OutSource;
import Model.Part;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;
public class AddPart implements Initializable {
public RadioButton addPartInHouse;
public TextField partIDTxtbox;
public TextField partNameTxtbox;
public TextField invTxtbox;
public TextField pricePerUnitTxtbox;
public TextField maxQtyTxtbox;
public TextField minQtyTxtbox;
public Button addPartSaveButton;
public Button addPartCancelButton;
public RadioButton addPartOutSource;
public Label companyNameLabel;
public TextField companyNamePrompt;
public ToggleGroup switchfield;
public void addPartInHouse(ActionEvent actionEvent) {
companyNameLabel.setText("Machine ID");
companyNamePrompt.setPromptText("Machine ID");
addPartOutSource.setSelected(false);
}
public void addPartOutsource(ActionEvent actionEvent) {
companyNameLabel.setText("Company Name");
companyNamePrompt.setPromptText("Company Name");
addPartInHouse.setSelected(false);
}
public void addPartSaveButton(ActionEvent e) throws IOException {
/*this is my line 55 below*/
if (this.switchfield.getSelectedToggle().equals(this.addPartInHouse)) {
Part partadd = new InHouse(0, "", 0.0, 0,0,0,0);
if(partIDTxtbox.getText().isEmpty()){
partadd.setPartID(Inventory.getPartIDCount());
}
if (!partNameTxtbox.getText().isEmpty()){
partadd.setPartName(partNameTxtbox.getText());
}
if (!pricePerUnitTxtbox.getText().isEmpty()){
partadd.setPartPrice(Double.parseDouble(pricePerUnitTxtbox.getText()));
}
if (!invTxtbox.getText().isEmpty()){
partadd.setPartInStock(Integer.parseInt(invTxtbox.getText()));
}
if(!minQtyTxtbox.getText().isEmpty()){
partadd.setMin(Integer.parseInt(minQtyTxtbox.getText()));
}
if(!maxQtyTxtbox.getText().isEmpty()){
partadd.setMax(Integer.parseInt(maxQtyTxtbox.getText()));
}
if(!companyNamePrompt.getText().isEmpty()){
((InHouse)partadd).setMachineID(Integer.parseInt(companyNamePrompt.getText()));
}
Inventory.addPart(partadd);
}
else{
Part partaddout = new OutSource(0, "", 0.0, 0,0,0,"");
if(partIDTxtbox.getText().isEmpty()){
partaddout.setPartID(Inventory.getPartIDCount());
}
if (!partNameTxtbox.getText().isEmpty()){
partaddout.setPartName(partNameTxtbox.getText());
}
if (!pricePerUnitTxtbox.getText().isEmpty()){
partaddout.setPartPrice(Double.parseDouble(pricePerUnitTxtbox.getText()));
}
if (!invTxtbox.getText().isEmpty()){
partaddout.setPartInStock(Integer.parseInt(invTxtbox.getText()));
}
if(!minQtyTxtbox.getText().isEmpty()){
partaddout.setMin(Integer.parseInt(minQtyTxtbox.getText()));
}
if(!maxQtyTxtbox.getText().isEmpty()){
partaddout.setMax(Integer.parseInt(maxQtyTxtbox.getText()));
}
if(!companyNamePrompt.getText().isEmpty()){
((OutSource)partaddout).setCompanyName((companyNamePrompt.getText()));
}
Inventory.addPart(partaddout);
}
Parent addPartSave = FXMLLoader.load(getClass().getResource("MainScreen.fxml"));
Scene scene = new Scene(addPartSave);
Stage window = (Stage) ((Node) e.getSource()).getScene().getWindow();
window.setScene(scene);
window.show();
}
public void addPartCancelButton(MouseEvent mouseEvent) throws IOException {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setTitle("Cancel add part");
alert.setHeaderText("You are about to return to the Main screen!");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK) {
Parent addPartCancel = FXMLLoader.load(getClass().getResource("MainScreen.fxml"));
Scene scene = new Scene(addPartCancel);
Stage window = (Stage) ((Node) mouseEvent.getSource()).getScene().getWindow();
window.setScene(scene);
window.show();
}
else{
return;
}
}
#Override
public void initialize(URL location, ResourceBundle resources) {
switchfield = new ToggleGroup();
this.addPartInHouse.setToggleGroup(switchfield);
}
}
'''
This is not an answer but it is more readable as an answer than as a comment.
Either switchfield is null or switchfield.getSelectedToggle() returns null.
Add the following line of code before line 55.
System.out.println(switchfield)
Then run your code. If it shows that switchfield is not null, then change it to
System.out.println(switchfield.getSelectedToggle())
And run the code again.
That should show that switchfield.getSelectedToggle() returns null.
Then you need to look at the code for method getSelectedToggle() in class ToggleGroup and see when that method returns null.
My guess is that method addPartSaveButton() is being called before you have selected one of the radio buttons.

How to set text to a label on keyboard key press in JavaFX application?

I'm making JavaFX application with Scene Builder. I have Main Class that launch Controller with main window.
I have a label in the Controller class
I need to assign keyboard key press in main window.
Example: if I press '1' on keyboard the text of a label should be set as "key 1 is pressed.
If I press "2" on keyboard the text should be set as "key 2 is pressed"
How Can I do that?
I've tried to use this code in initialize method, but nothing happens:
category1.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent ke) {
KeyCode kc = ke.getCode();
if((kc.equals(KeyCode.D))) {
category1.setText("Key D is pressed");
}
}
});
Main Class:
package src.card;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.input.*;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
try {
Parent root = FXMLLoader.load(getClass().getResource("resources/fxml/card.fxml"));
Scene scene = new Scene(root, 1600, 600);
primaryStage.setScene(scene);
scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setMaximized(true);
primaryStage.setResizable(true);
primaryStage.getIcons().add(new Image("src/card/resources/logo-icon.png"));
primaryStage.show();
//adding resize and drag primary stage
ResizeHelper.addResizeListener(primaryStage);
//assign ALT+ENTER to maximize window
final KeyCombination kb = new KeyCodeCombination(KeyCode.ENTER, KeyCombination.CONTROL_DOWN);
scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (kb.match(event)) {
primaryStage.setMaximized(!primaryStage.isMaximized());
primaryStage.setResizable(true);
Controller cont = Context.getInstance().getController();
if (!primaryStage.isMaximized()) {
cont.getBtnFont().setPrefWidth(20);
cont.getBtnPalette().setPrefWidth(20);
cont.getBtnQuestCards().setPrefWidth(20);
cont.getBtnNonQuestCards().setPrefWidth(20);
} else if (primaryStage.isMaximized()){
cont.getBtnFont().setPrefWidth(50);
cont.getBtnPalette().setPrefWidth(50);
cont.getBtnQuestCards().setPrefWidth(50);
cont.getBtnNonQuestCards().setPrefWidth(50
);
}
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
Controller:
#FXML private Label category1
#FXML public void initialize(URL location, ResourceBundle resources) {
category1.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent ke) {
KeyCode kc = ke.getCode();
if((kc.equals(KeyCode.D))) {
category1.setText("Key D is pressed");
}
}
});
//register Controller in Context Class
Context.getInstance().setController(this);
}
EDIT:
I've tried to use it in initialize method:
category1.getScene().setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent ke) {
KeyCode kc = ke.getCode();
if((kc.equals(KeyCode.D))) {
category1.setText("Key D is pressed");
}
}
});
and I got errors:
javafx.fxml.LoadException:
/D:/IDEA%20Projects/CategoryCards/out/production/CategoryCards/src/card/resources/fxml/card.fxml
at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
If I remove getScene() from category1 - everything is going fine and application launch
It seems when I use getScene() it try to get fxml file from out folder, not my main folder, but how can I fix this?
You can do so by setting key press event(setOnKeyPressed) to parent of Label
instead of Scene. Trying to add event to Scene will give error because initialize will be called before creation of the Scene.
Let's say you have FXML file called sample.fxml and In that file you have GridPane having id root and a Label having id category1
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.GridPane?>
<GridPane fx:controller="Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10" fx:id="root">
<Label text="Category" fx:id="category1"/>
</GridPane>
And you have Controller class called Controller. To change label of category1 when any key is pressed, first you have to set category1 focus traversable by calling setFocusTraversable method on category1 and passing true. And then you have to add key press event on root(parent of category1), As shown below
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable{
#FXML private Label category1;
#FXML private GridPane root;
#Override
public void initialize(URL location, ResourceBundle resources){
category1.setFocusTraversable(true);
root.setOnKeyPressed(this::handle);
}
private void handle(KeyEvent keyEvent){
category1.setText("Key " + keyEvent.getCode().getName() + " is pressed");
}
}
And here is simple version of Main class
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application{
public static void main(String[] args){
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Scene scene = new Scene(root, 300, 275);
primaryStage.setScene(scene);
primaryStage.show();
}
}

How do I write the path to a FXML file in my JavaFX application?

I'm trying to write the path in the main class to load a FXML file MenuFXML.fxml but I can't figure out the correct way to do so. The FXML file is in the package com.developer.fxml and the main class is in com.developer.
I've already tried the path /com/developer/fxml/MenuFXML.fxml and /fxml/MenuFXML.fxml but neither of them work.
package com.developer;
import com.developer.exit.ExitApplication;
import com.developer.util.css.AddCSS;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
private Stage stage;
private Scene scene;
private final String title = "Stock Program 2.0";
private Parent root;
private final AddCSS addcss = new AddCSS();
#Override
public void start(Stage primaryStage) throws IOException {
stage = primaryStage;
stage.setTitle(title);
stage.setOnCloseRequest(e -> {
e.consume();
ExitApplication ep = new ExitApplication();
ep.closeProgram(stage);
});
//The part that I can't get to work
root = FXMLLoader.load(getClass().getResource("/fxml/MenuFXML.fxml"));
scene = new Scene(root);
addcss.setStylesheet(scene);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}

Editing Label from another Class (Java FX)

i have got a question:
i have got a simple Java FX Application where i have a button and when i hit the button a thread task starts which have to change a label every second:
MyController.java
package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit.*;
import java.util.*;
import java.text.DateFormat;
public class MyController implements Initializable{
#FXML
private Button myButton;
#FXML
private TextField myCountry;
#FXML
public Label myTime;
#Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
}
public void startTimeThread(ActionEvent event) {
ScheduledThreadPoolExecutor eventPool = new ScheduledThreadPoolExecutor(3);
eventPool.scheduleAtFixedRate
(new CheckSystemTime(), 0, 2, TimeUnit.SECONDS);
myButton.setDisable(true);
}
public void setLabel(String text) {
myTime.setText(text);
}
}
Main.java is the standart one
CheckSystemTime.java
package application;
import java.util.*;
import java.text.DateFormat;
public class CheckSystemTime implements Runnable {
//String locale;
public CheckSystemTime(/**String location**/) {
//this.locale = location;
}
public void run() {
Date rightNow;
DateFormat timeFormatter;
String timeOutput;
rightNow = new Date();
Locale currentLocale = new Locale("de");
timeFormatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, currentLocale);
timeOutput = timeFormatter.format(rightNow);
//e.g. MyController.setLabel(timeOutput); doesnt work
}
}
So my question is, how i am able to access the setLabel Method from the CheckSystemTime class?
i hope you are able to help me how i can solve this problem
Add the MyController or a Label or the textProperty of the Label to the constructor of CheckSystemTime. Then you can keep a local reference inside CheckSystemTime. Then you can access it inside your run method. But make sure to wrap every UI related calls inside Platform.runLater().

Why the items I add to my ObservableList are only accessible from the function they are declared

Context
I just started to learn JavaFX so I'm developing a program to discover it. The program I'm on needs a array, so I used ObservableList. But here is the problem, the items I add to the list are only accessible from the function itself.
Here is the situation :
package fr.cartes;
import fr.cartes.model.MapModel;
import fr.cartes.view.ListMapsController;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.ArrayList;
public class MainApp extends Application {
private Stage primaryStage;
private ObservableList<MapModel> maps = FXCollections.observableArrayList();
public static void main(String[] args){
launch(args);
}
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("/!\\ Explorateur /!\\");
this.primaryStage.setAlwaysOnTop(true);
initializationOfProgram();
}
public void initializationOfProgram(){
initializeListMaps();
maps.add(new MapModel("Les Etats-Unis d'Amérique", "EU.jpg"));
maps.add(new MapModel("La France d'aujourdh'ui", "FR.jpg"));
for(MapModel mapModel : maps){
System.out.println(mapModel.getMapName());
}
}
public void initializeListMaps(){
for(MapModel map : maps){
System.out.println(map.getMapName());
}
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/ListMaps.fxml"));
Scene scene = new Scene(loader.load());
primaryStage.setScene(scene);
primaryStage.show();
ListMapsController controller = new ListMapsController();
controller.setMainApp(this);
controller.loadMapsOnListView(maps);
}catch(IOException exception){exception.printStackTrace();}
}
public ObservableList<MapModel> getMapsLists(){
return maps;
}
}
For example, if I put a println() test in the initializationOfProgram(), I will have "Les Etats-Unis d'Amérique" and "La France d'aujourd'hui" written on the console, but if I do this println() test in initializeListMaps(), it won't display anything.
Am I missing something obvious here ? Can you help me ?

Categories

Resources