This question already has answers here:
JavaFX 2.0 Activating a Menu like a MenuItem
(5 answers)
Closed 5 years ago.
I am beginner to javafx, I am trying to make a menu and when someone click on menuitem it will print out text
I have these codes
package sam;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author devby
*/
public class SaM extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("home.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
My controller looks like this
package sam;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
/**
*
* #author devby
*/
public class homeController implements Initializable {
#Override
public void initialize(URL location, ResourceBundle resources) {
//TODO
}
#FXML
public void callHome(ActionEvent event) {
System.out.println("Clicked on menu Home");
}
}
And my fxml file looks like this
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="401.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sam.homeController">
<children>
<MenuBar layoutY="2.0" prefHeight="26.0" prefWidth="600.0" AnchorPane.bottomAnchor="372.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="2.0">
<menus>
<Menu mnemonicParsing="false" onAction="#callHome" text="Home" />
<Menu mnemonicParsing="false" text="Library">
<items>
<MenuItem mnemonicParsing="false" text="Movies" />
<MenuItem mnemonicParsing="false" text="Serials" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Online" />
<Menu mnemonicParsing="false" text="Download" />
<Menu mnemonicParsing="false" text="Settings" />
</menus>
</MenuBar>
</children>
</AnchorPane>
When I run the program and click on Home menu button it does nothing.
I am using javafx 8, IDE is netbeans and I am building GUI with Scene Builder
Can anyone help ?
News:
I have added a button and tried him. It works so probably something wrong with a menu
I think that Menu cannot be bind to onAction, but MenuItem CAN!
Related
I have a button which display a menu containing only one custom menu item. This menu item contains a textfield and a button. Here is my code:
helloApplication.java:
package com.example.demo;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
#Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 320, 240);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
helloController.java:
package com.example.demo;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class HelloController {
#FXML
private Label welcomeText;
#FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to JavaFX Application!");
}
}
hello-view.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CustomMenuItem?>
<?import javafx.scene.control.MenuButton?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/18" fx:controller="com.example.demo.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
<children>
<MenuButton mnemonicParsing="false" text="MenuButton">
<items>
<CustomMenuItem hideOnClick="false" mnemonicParsing="false" text="Unspecified Action">
<content>
<HBox prefHeight="100.0" prefWidth="200.0">
<children>
<TextField />
<Button mnemonicParsing="false" text="Button" />
</children>
</HBox>
</content>
</CustomMenuItem>
</items>
</MenuButton>
</children>
</VBox>
This menu I want this menu item to be unselectable, just a pane poping to display the textfield. It is already not hidden when clicked. The problem is that when i enter some text in the textfield, and move the mouse cursor, the focus in the text field is lost because the menu item takes the focus:
How can I prevent the menu item to react and let the text field keep the focus ? Is a custom menu item a good solution if I want only one menu item containing components ?
I create javafx application and have to combine it with ServerSocket, but when I use function accept of ServerSocket the application is black out. what I expected is to let the application wait until there a Socket connect and run the next method. I have no idea what happen but when I comment the line of ServerSocket.accept() out it work just fine. I have try to read api doc of ServerSocket but I found no help in it or maybe I just too dull for it.
Main
package test;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.net.ServerSocket;
public class ProblemTest extends Application {
public static void main(String[] args) throws Exception{
launch(args);
}
public void start(Stage primaryStage)throws Exception{
FXMLLoader loader = new FXMLLoader(getClass().getResource("test.fxml"));
Parent root= loader.load();
Scene scene=new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
ServerSocket server=new ServerSocket(8000);
server.accept();
}
}
Fxml file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.VBox?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Clear" />
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
</menus>
</MenuBar>
<TextArea prefHeight="377.0" prefWidth="640.0" />
</children>
</VBox>
```
server.accept()
blocks application thread, you need to invoke accept() in another thread.
new Thread(() -> {
... new ServerSocket(8000).accept();
}).start()
I'm using Scene Builder for this example, I have a listview and I want it to be already filled when I run the application, but I don't seem to find a way to do it, it simply dosn't work and the listview dosn't appear.
Here's my FXMLTasker.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="557.0" prefWidth="1012.0" style="-fx-background-color: #0288D1;" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
<children>
<SplitPane dividerPositions="0.5" layoutX="-8.0" layoutY="35.0" prefHeight="529.0" prefWidth="1027.0" style="-fx-background-color: #EEEEEE;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="28.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<ListView fx:id="list_todo" editable="true" layoutX="14.0" layoutY="14.0" prefHeight="508.0" prefWidth="485.0" />
</children></AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="527.0" prefWidth="640.0" />
</items>
</SplitPane>
</children>
</AnchorPane>
Here's my Main.class
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
/**
*
* #author samuel
*/
public class JavaFXApplication3 extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLTasker.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
And here's my Controler
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
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.ListView;
import javax.swing.JOptionPane;
/**
*
* #author samuel
*/
public class FXMLDocumentController implements Initializable {
#FXML
private ListView list_todo;
private ObservableList<String> items = FXCollections.observableArrayList();
#Override
public void initialize(URL url, ResourceBundle rb) {
list_todo.setItems(items);
items.add("First task");
items.add("Second task");
}
}
The problem is that the list dosn't appear when I run the application, it should be simple but for some reason it dosn't work. Anyone can find why?
Specify the controller to your fxml file with all other details as below,
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="557.0" prefWidth="1012.0" style="-fx-background-color: #0288D1;" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FXMLDocumentController">
</AnchorPane>
Add controller class with full specified name (with package name, if u have any)
I have simple JavaFx project, with main class as eclipse JavaFx project default.
I have defined a controller , it looks like the skeleton generated by SceneBuilder, so everything is pretty much default.
When I run my application, In the UI I can't input data to the two textfields, or see the console output from my button event handlers.
A welcome.fxml file as shown below (deleted all other code to simplify)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.*?>
<?import javafx.scene.canvas.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mouseTransparent="true" prefHeight="720.0" prefWidth="1100.0" style="-fx-background-color: #000000;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Welcome_Controller">
<children>
<Button alignment="CENTER" contentDisplay="CENTER" depthTest="ENABLE" graphicTextGap="10.0" layoutX="496.0" layoutY="360.0" mouseTransparent="true" onAction="#OnSignInClick" opacity="0.82" prefHeight="38.0" prefWidth="109.0" style="-fx-background-radius: 100;" text="Sign In" textAlignment="CENTER" />
<Button alignment="CENTER" contentDisplay="CENTER" layoutX="496.0" layoutY="409.0" mnemonicParsing="false" opacity="0.82" prefHeight="38.0" prefWidth="109.0" style="-fx-background-radius: 1000;" text="Sign Up" textAlignment="CENTER" />
<Text fill="WHITE" layoutX="899.0" layoutY="702.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Copyright 2015, Dawood and Irtiza." />
<TextField fx:id="tf_username" layoutX="427.0" layoutY="277.0" prefHeight="25.0" prefWidth="279.0" promptText="Enter new Username if you dont have an account " />
<TextField fx:id="tf_password" layoutX="427.0" layoutY="312.0" prefHeight="25.0" prefWidth="279.0" promptText="Enter new password if you dont have an account" />
<Label layoutX="355.0" layoutY="281.0" text="Username :" textFill="WHITE">
<font>
<Font size="14.0" />
</font>
</Label>
<Label layoutX="355.0" layoutY="315.0" text="Password :" textFill="WHITE">
<font>
<Font size="14.0" />
</font>
</Label>
</children>
</Pane>
Welcome_controller.java looks like a default skeleton generated by scene builder, code below
package application;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class Welcome_Controller implements Initializable {
#FXML // fx:id="btn_xxx"
private Button btn_signin; // Value injected by FXMLLoader
#FXML
private Button btn_signup;
#FXML
private TextField tf_username;
#FXML
private TextField tf_password;
#Override // This method is called by the FXMLLoader when initialization is complete
public void initialize(URL fxmlFileLocation, ResourceBundle resources)
{
//assert btn_signin != null : "fx:id=\"btn_signin\" was not injected: check your FXML file 'welcome.fxml'.";
//assert btn_signup != null : "fx:id=\"btn_signup\" was not injected: check your FXML file 'welcome.fxml'.";
// initialize your logic here: all #FXML variables will have been injected
}
#FXML private void OnSignInClick(ActionEvent event) throws IOException
{
System.out.println("clicked");
}
#FXML
void OnSignupClick(ActionEvent event) {
System.out.println("clicked 2");
}
}
EDIT : This is the class with the main method.
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Pane root = (Pane) FXMLLoader.load(Main.class.getResource("welcome.fxml"));
Scene scene_1 = new Scene(root,1100,720);
//scene_1.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
//we can set the different scenes when it need to
primaryStage.setScene(scene_1);
primaryStage.setTitle("Translate Messenger");
primaryStage.show();
} catch(Exception e) {
System.out.println("main may exception");
e.printStackTrace();
}
}
public static void main(String[] args)
{
launch(args);
}
}
When I run my application, In the UI I can't input data to the two textfields, or see the console output from my button event handlers.
Any help would be appreciated.
You have made the root pane transparent to the mouse with mouseTransparent="true". This means that any mouse clicks on the root pane, or any of its descendent nodes (i.e. the whole UI) will be ignored. Consequently you cannot click the buttons or put focus on the text fields using the mouse. (Notice though you can navigate the UI using the tab key, and use the space key to generate a button click when it has the focus.)
Remove mouseTransparent="true" from the pane and from the "Sign In" button and it will work fine.
How do you create a new tab using JavaFX/FXML? I've created a tabpane in my FXML but I want to click a button that causes a new tab to come up.
Here is my FXML:
<?import javafx.scene.effect.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.layout.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<top>
<MenuBar BorderPane.alignment="CENTER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="New..." onAction="#btnNew"/>
<MenuItem mnemonicParsing="false" text="Save..." />
<MenuItem mnemonicParsing="false" text="Save As..." />
<MenuItem mnemonicParsing="false" text="Open..." />
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About Blank" onAction="#btnAbout"/>
</items>
</Menu>
</menus>
</MenuBar>
</top>
<center>
<TabPane prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" BorderPane.alignment="CENTER" fx:id="tabPane">
<tabs>
<Tab text="Untitled Tab 1">
<content>
<AnchorPane>
<children>
<TextFlow maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" />
</children>
</AnchorPane>
</content>
</Tab>
</tabs>
</TabPane>
Here is my code that I'm trying right now in my controller:
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
#FXML
private Button btnAbout;
#FXML
private Button btnNew;
#FXML
private TabPane tabPane;
//tab array
int intTabs = 0;
Tab[] openTabs;
#FXML
private void btnNew(ActionEvent event){
try{
intTabs++;
openTabs = new Tab[intTabs];
//System.out.println(openTabs.length);
tabAdder(intTabs, openTabs);
}catch(Exception e){
e.printStackTrace();
}
}
private TabPane tabAdder(int tabNum, Tab[] tabs){
//System.out.println(tabNum);
tabPane.getTabs().add(tabs[tabNum]);
return tabPane;
}
#FXML
private void btnAbout(ActionEvent event){
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Blank: Information");
alert.setHeaderText(null);
alert.setContentText("This is Blank, a simple and soon to be elegant cross platform text editor.");
alert.showAndWait();
}
public void initialize(URL url, ResourceBundle rb){
//tabPane.getTabs().add
}
}
I'm not really sure what the problem is I've been going through a bunch of resources and I know how to add a regular tab.
I know that if I make a tab like this:
Tab fapTab = new Tab();
I can add it like this:
tabPane.getTabs().add(fapTab);
But I want to create them dynamically because I don't know how many tabs my user's would want. So my approach was to create an array of tabs that gets bigger whenever a user clicks "new" and then have a function that adds that new tab to the gui. It's not working though and I've tried several different approaches, adapting people's code to my own.
So my question is does anyone know what I'm doing wrong?
Here are some of those sources:
javafx open a new fxml file in new tab dynamically
http://javafx-albert-af77.blogspot.com/2012/06/tabs-fxml.html
https://www.youtube.com/watch?v=NhoiSMk3f5U
You have already given the answer: just create a new tab and add it to the tab pane:
Tab tab = new Tab();
tabPane.getTabs().add(tab);
Complete example:
AddTabsExample.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1"
fx:controller="AddTabsController">
<center>
<TabPane fx:id="tabPane" />
</center>
<bottom>
<HBox alignment="center">
<Button text="Add tab" onAction="#addTab" />
<Button text="List tabs" onAction="#listTabs" />
</HBox>
</bottom>
</BorderPane>
AddTabsController.java:
import javafx.fxml.FXML;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
public class AddTabsController {
#FXML
private TabPane tabPane ;
public void initialize() {
tabPane.getTabs().add(new Tab("Tab 1"));
}
#FXML
private void addTab() {
int numTabs = tabPane.getTabs().size();
Tab tab = new Tab("Tab "+(numTabs+1));
tabPane.getTabs().add(tab);
}
#FXML
private void listTabs() {
tabPane.getTabs().forEach(tab -> System.out.println(tab.getText()));
System.out.println();
}
}
Application (AddTabsExample.java):
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class AddTabsExample extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
BorderPane root = FXMLLoader.load(getClass().getResource("AddTabsExample.fxml"));
primaryStage.setScene(new Scene(root, 800, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Use this instead. You have to override initialize() method:
#Override
public void initialize(URL location, ResourceBundle resources) {
tabPane.getTabs().add(new Tab("Tab 1"));
}
Not this:
public void initialize() {
tabPane.getTabs().add(new Tab("Tab 1"));
}