This question already has answers here:
How to Fix NoClassDefFoundError in JavaFX?
(1 answer)
I'm encounter a java.lang.NoClassDefFoundError and I don't know why it's occuring [duplicate]
(1 answer)
Closed 5 months ago.
I am working on a JavaFX project, and I am having trouble displaying the user interface. I keep getting this error:
Error: Could not find or load main class Main.SongApp
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application
I am confused because my directory has no files named 'application' or 'Application.'
I have these three files and I am not sure why this code does not run. This is the main file that I try to display the user interface from:
SongApp.java
public class SongApp extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
// create FXML loader
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/SongLibraryProject/ControllerTing/SongLib.fxml"));
// load fxml, root layout manager in fxml file is GridPane
AnchorPane root = (AnchorPane)loader.load();
// set scene to root
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This file has my front end code from Scene Builder and the anchor table I am trying to display: SongLib.fxml
<AnchorPane minHeight="400.0" minWidth="747.0" prefHeight="400.0" prefWidth="747.0" style="-fx-background-color: #263238;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="SongLibrary.View.Controller">
//front end(scenebuilder code)
</AnchorPane>
This is the the controller file: SongLibController.java
public class SongLibController {
#FXML ListView<Song> songList;
#FXML Button add;
#FXML Button edit;
#FXML Button delete;
#FXML Text name;
#FXML Text artist;
#FXML Text album;
#FXML Text year;
#FXML TextField nameField;
#FXML TextField artistField;
#FXML TextField albumField;
#FXML TextField yearField;
private ObservableList<String> obsList;
public void add(ActionEvent e) {
System.out.println("add");
}
public void edit(ActionEvent e) {
System.out.println("edit");
}
public void delete(ActionEvent e) {
System.out.println("delete");
}
}
Related
I'm making an application with JavaFX and Scene Builder.
I have Main class and controller that is called from main class.
I have a button in the controller that has width - 45 and height - 90
Toggle button is wrapped in StackPane and StackPane is wrapped in AnchorPane
How can I change buttonPrefWidth to 25 when application is not fullscreen and change button's prefWidth again to 45 when application is fullscreen?
Or can I change prefWidth of a button according to size of application?
Main Class:
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("/card/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("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);
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
Controller:
public class Controller implements Initializable {
#FXML private AnchorPane anchorRow;
#FXML private StackPane hBoxCat0;
#FXML private Button btnPalette;
#FXML
public void initialize(URL location, ResourceBundle resources) {
}
}
EDIT:
#Slaw it doesn't work
If you just want to change the prefWidth between two numbers based on whether or not the window is full screen, then you can listen to the fullScreen property of the Stage the Button belongs to.
import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
public class Controller {
#FXML private Button btnPallet;
#FXML
private void initialize() {
btnPallet.prefWidthProperty().bind(
Bindings.when(Bindings.selectBoolean(btnPallet.sceneProperty(), "window", "fullScreen"))
.then(45)
.otherwise(25)
);
}
}
This will give you warnings at first since the Button won't be part of a Scene or Window at this point of the application. While these warnings are annoying the code should still work.
Relevant Files: (apologies on any formatting, made many attempts to make it work)
If the files are not sufficient, the repository is here: https://github.com/TheeNinja/StockLookupTool
stock_lookup_tool_main.fxml
<BorderPane fx:id="borderPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="me.theeninja.stocklookuptool.gui.StockLookupToolApplicationController">
<top>
...
</top>
<left />
<center />
</BorderPane>
stock_information_center.fxml
<GridPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="me.theeninja.stocklookuptool.gui.selection.StockSearchSelectionController"
prefHeight="400.0" prefWidth="600.0"
fx:id="stockInformationCenter">
</GridPane>
favorite_stocks_sidebar.fxml
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="me.theeninja.stocklookuptool.gui.selection.StockSearchSelectionController" fx:id="verticalStockList">
...
</VBox>
StockLookupTool.java (Class with the start method)
public class StockLookupTool extends Application {
....
#Override
public void start(Stage stage) throws Exception {
...
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/fxml/stock_lookup_tool_main.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root, 250, 300);
stage.setTitle(APPLICATION_TITLE);
stage.setScene(scene);
stage.setFullScreen(true);
stage.show();
}
....
}
StockLookupToolApplicationController (controller for stock_lookup_tool_main.fxml)
public class StockLookupToolApplicationController {
...
#FXML public Label stockSearchLabel;
#FXML public Label newsLabel;
#FXML public Label settings;
#FXML public BorderPane borderPane;
#FXML public HBox topApplicationNavigation;
#FXML
public void handleStockSearchSelection() {
logger.log(Level.INFO, "Setting GUI View to Stock Search");
setView(StockSearchSelectionController.getInstance());
}
private void setView(Selection selection) {
borderPane.setLeft(selection.getLeft());
borderPane.setCenter(selection.getCenter());
borderPane.setRight(selection.getRight());
borderPane.setBottom(selection.getBottom());
}
}
StockSearchSelectionController.java (controller for both stock_information_center.fxml and favorite_stocks_sidebar.fxml)
public class StockSearchSelectionController implements Selection {
#FXML public Label favoriteStocksLabel;
#FXML public TextField addFavoriteStockInput;
#FXML public VBox verticalStockList;
#FXML public HBox addFavoriteStockInputContainer;
#FXML public GridPane stockInformationCenter;
#FXML
public void handleFavoriteStockInput(KeyEvent keyEvent) {
if (keyEvent.getCode() == KeyCode.ENTER) {
...
// makes visual changes to both stockInformationCenter AND verticalStockList, hence I need access to both fxml files (which is why this controls both).
}
}
#Override
public Node getLeft() {
return verticalStockList;
}
#Override
public Node getCenter() {
return stockInformationCenter;
}
}
More information:
The interface Selection has the methods getLeft() and getCenter() (among other irrelevant ones). Both of these returns Node. In stock_lookup_tool_main.fxml, in the top portion of the BorderPane I have a button (cut out in the provided snippet) that, when pressed, calls handleStockSearchSelection() (this method call indeed happens, I have verified it with a logger).
Now there is a controller, that controls both stock_information_center.fxml and favorite_stocks_sidebar.fxml. This controller implements Selection, and in turn, implements getLeft() and getCenter(). getLeft() returns the VBox variable
that correlates to favorite_stocks_sidebar.fxml, while getCenter() returns the GridPane variable that correlates to stock_information_center.fxml. When handleStockSearchSelection() is called, the left part of the borderPane object is set to the VBox, and the center is set to the GridPane. All these method calls/actions have been verified to occur. However, there is no visual change to the scene.
My question is: Why are these changes to borderPane not implemented visually in the scene? I have established a link between the scene <-> stock_lookup_tool_main.fxml through setting the loader's location. I have also established a link between stock_lookup_tool_main.fxml <-> its controller, hence they should share changes. I have modified the border pane in stock_lookup_tool_main.fxml in the controller by calling setLeft() and setCenter() on the variable (same name as the ID, borderPane). Yet, the scene visually does not change.
I have multiple tabs and one of them is my console output. I am trying to redirect System.out/err to TextArea loggerPane in that console output Tab using JavaFX. My question is how can I do that in a different thread because while it's outputting I can't navigate to the console tab.
Main App:
public initRootLayout(){
FXMLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource(RootLayout.fxml))
rootLayout = (BorderPane) loader.load();
scene = new Scene (rootLayout);
primaryStage.setScene(scene);
rootLayoutController = loader.getController();
rootLayoutController.setMainApp(this);
primaryStage.show();
}
I included the ConsoleController in RootController where I have all the tabs
#FXML private ConsoleController consoleController
RootLayoutFXML: I included the consoleFXML that uses its own controller
<Tab text="Console">
<content>
fx:include fx:id="myConsolePane" source="console.fxml"
</content>
</Tab>
ConsoleController
public class ConsoleController implements Initializable {
#FXML
private TextArea loggerPane;
public void appendText(String valueOf){
Platform.runLater(()-> loggerPane.appendText(valueOf))
}
#Override
public void initialize (URL ur, ResourceBundle rb){
OutputStream out = new OutputStream(){
#Override
public void write(int b) throws IOException{
appendText(String.valueOf((char)b));
}
};
System.setOut(out, true);
System.setErr(out, true);
}
Background Thread:
It's calling background class that interacts with a Rest API to
preform a function, sometime it outputs a long string as part of
the validation which I want to capture in the console tab.
Every time I ran JavaFX app I encounter the error below.
15:11:52.778 [JavaFX Application Thread] ERROR org.fhl.Manifesto - javafx.fxml.LoadException:
/C:/ManGenFX/target/classes/dataController.fxml
/C:/ManGenFX/target/classes/ManifestoMain.fxml:7
But it only happens if I add the initialize method on Main Controller.
public class MainController{
#FXML
GenerateController genCont;
#FXML
private Pane generatePane;
#FXML
AnchorPane mainFx;
private Node source;
//Other Button, TextFields and Labels declaration
#FXML
private void browseFile(ActionEvent x) {
//Browse file definition
}
#FXML
private void savePath(ActionEvent x) {
//Save file definition
}
//Problem with this method
#FXML
public void initialize() {
System.out.println("Initialize generate controller panel");
logger.info("Initialize generate controller panel");
genCont.init(this);
}
}
If I remove the initialize method on MainController class it will not throw any error but nothing happens either if I click on the generate button which is defined in GenerateController class below.
public class GenerateController {
#FXML
Button btnGenerate;
#FXML
Pane paneGen;
#FXML
public void generateMan(ActionEvent event) {
//generateMan body when Generate button is clicked
}
public void init(MainController mc) {
System.out.println("Init mainControl");
mainControl = mc;
}
public void validate() {
//Definition of method body here
}
}
This is the main Class
public class Man extends Application {
private Stage mainStage;
#Override
public void start(Stage primaryStage) {
this.mainStage = primaryStage;
this.mainStage.setTitle("Manifest");
try{
Parent root = FXMLLoader.load(getClass().getResource("/ManifestoMain.fxml"));
Scene sMain = new Scene(root);
mainStage.setScene(sMain);
mainStage.show();
}catch(IOException ioE) {
logger.error(ioE);
}
}
public static void main(String[] args) {
launch(args);
}
}
Also, I placed my dataController.fxml, ManifestoMain.fxml, and generateView.fxml under resources folder but it don't have any problem accessing the files. Appreciate help on this.
I'm trying to change a text in a label, a text which was entered in a text field in a different scene.
I made 2 FXML files, the first one contains a textfield and "ok" button, the second one contains a label(with the text "Label").
My goal is to enter a text in the textfield, and when I press "ok"-> open the new scene and the label will change it's text to the text I entered in the text field.
I easily changed the label text when the label, the textfield and the ok button were all in the same scene, but when I do it while opening a new scene I fail...
After some research, I made a controller for each FXML file, and a "MainController" that will communicate between them.
This is my main class:
public class MainBanana extends Application {
#Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("view/Welcome.fxml"));
Scene scene = new Scene(root);
primaryStage.setTitle("MokaApp");
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setResizable(false);
}
public static void main(String[] args) {
launch(args);
}
}
my first scene controller:
public class WelcomeController {
#FXML
public TextField nameField;
#FXML
private Button okButton;
private MainController main;
#FXML
public void okClicked(ActionEvent event) throws IOException{
Parent root = FXMLLoader.load(getClass().getResource("Person.fxml"));
okButton.getScene().setRoot(root);
System.out.println(nameField.getText());
main.setLblFromTf(nameField.getText());
}
public void init(MainController mainController) {
main=mainController;
}
}
second scene controller:
public class PersonController {
#FXML
public Label nameLabel;
private MainController main;
public void init(MainController mainController) {
main=mainController;
}
}
When I launch the program, The Welcome scene is opened, I enter a text to the textfield, but whenever I press the "ok" button, the scene changes to the second scene, but the label text stays the same(label) and I get a nullpointerexception error on this line(located in WelcomeController): main.setLblFromTf(nameField.getText());
Sorry for the long post..
You don't need the references to MainController all over the place.
The easiest way is:
public class PersonController {
#FXML
private Label nameLabel ;
public void setName(String name) {
nameLabel.setText(name);
}
}
Then you can do
public class WelcomeController {
#FXML
private TextField textField ;
#FXML
private Button okButton ;
#FXML
public void okClicked() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Person.fxml"));
Parent root = loader.load();
PersonController personController = loader.getController();
personController.setName(textField.getText());
okButton.getScene().setRoot(root);
}
}