I created a swing GUI, and a graph using JavaFX. I would like to open the graph by clicking a button on the swing GUI. My Code is below. Thank you for your help.
This is what I have to open the FX GUI from the swing GUI.
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Test Graph = new Test();
Graph.GrpahScreen();
}
});
FX class
public class Test extends Application {
#Override
public void start(Stage stage) {
// TODO
}
public static void main(String args []) {
launch(args);
}
}
The Application class represents a JavaFX Application. Since you are writing a Swing application (with JavaFX content embedded in it), it makes no sense to create an Application subclass.
Additionally, it is highly recommended not to use both JavaFX Stages and Swing JFrames in the same application. You should place the JavaFX content in a JFXPanel and display the JFXPanel in a JFrame. You need to be careful to obey the threading restrictions of both toolkits: as usual, Swing components must be created on the AWT event dispatch thread, and JavaFX components must be created on the JavaFX application Thread. This is all covered in detail in the JFXPanel documentation, but in essence:
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JFrame frame = new JFrame();
JFXPanel jfxPanel = new JFXPanel();
Platform.runLater(() -> {
Parent root = ... ; // create JavaFX content, can be in a separate class
Scene scene = new Scene(root);
jfxPanel.setScene(scene);
});
frame.add(jfxPanel);
frame.setSize(...);
frame.setVisible(true);
}
});
Related
I would like to change the cursor to use the drag and drop "move" and "move and copy" cursors in my application on a panel when I perform certain actions. The area is using swing inside of a swing node so a swing (Apply to panel) or JavaFx (Applying to swing node) solution would work.
I did find swing cursors DragSource.DefaultMoveDrop and DragSource.DefaultCopyDrop but when I apply them my cursor doesn't change. (And I know I am applying the cursor correctly as applying other cursors work fine)
EDIT: Note that when not nested in a SwingNode and in a JFrame instead the cursor does change to what I want. I have amended the code example to emulate the environment I am in where it doesn't work:
public class Temp extends Application {
public static void main(String[] args) {
Application.launch();
}
#Override
public void start(Stage primaryStage) throws Exception {
SwingNode swingNode = new SwingNode();
SwingUtilities.invokeLater(() -> {
JPanel panel = new JPanel();
panel.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); //Change this
swingNode.setContent(panel);
});
Scene scene = new Scene(new BorderPane(swingNode));
primaryStage.setScene(scene);
primaryStage.show();
}
}
Ok turns out it works DragSource.DefaultMoveDrop and DragSource.DefaultCopyDrop actually work in a normal swing application, just not on JPanel inside a SwingNode which the environment I am working in uses. (I can't change this)
Therefore if you run into this issue and you are NOT mixing the frameworks this forms an answer.
I'm making a java proyect using eclipse and the windowbuilder plugin. After finishing the logic I've created an Application Window and execute the project, everything is fine. But now i want to modify the window, so i change the title for example. In the visual view, i can see these changes, but when i execute the application, there are no changes, it's always the same window. This is the code:
public class Application {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Application window = new Application();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Application() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("My Application");
}
}
I've just added one line so I don't know what could be wrong. I also want to know if this is the best way to make a gui application (using Application Window) or if there are better ways.
EDIT: I add some images to show which is the problem
Window when i execute:
Window in windowbuilder:
You can set title using two ways:
1.Set title using JFrame setTitle() method : frame.setTitle("My Application");
2.Set title using JFrame(String Title) constructor: frame = new JFrame("My Application");
According to my opinion both ways work to set title but still if you are struggling with first option, you can try second option. May be this code works for you.
private void initialize() {
frame = new JFrame("My Application");
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
After setting changes, go frame.dispose()
and after that You can
frame.repaint();
frame.revalidate();
Please try this:
try {
Application window = new Application();
window.frame.setVisible(true);
window.frame.setTitle("My Application");
} catch (Exception e) {
e.printStackTrace();
And let me know the result.
Edit:
remove setTitle() from initialize method.
Edit:
If you are beginner you can try JavaFX. It is also simple as Java Swing but has some more potential, better design options and stuff. Its something I have tryed with when I was started Java learning.
I think that you should delete your swing and install it again. Because any solution is not working and there is no other reason not to. Just try to reinstall swing.
I have a Java project that plays a .flv media file through JavaFX Media Player, and it's working fine. Recently, I've been wanting to experiment by adding GUI components to this Project (JPanel, JLabel). However, I've failed in all my attempts and after doing some research turns out it's not as simple as i first thought.. I've tried borderPane.setTop(JLabel) but I get a "Cannot convert Jlabel to Node" error.. I feel that I'm missing something
If anyone has any idea why this isnt working for me, I would greatly appreciate any form of explanation or examples.. :)
Here is the code if it might be of use to you!
#Override
public void start(Stage stage){
String path = "Data/Video/Clip.flv";
Media media = new Media(new File(path).toURI().toString());
MediaPlayer mediaPlayer = new MediaPlayer(media);
MediaView mediaView = new MediaView(mediaPlayer);
BorderPane borderPane = new BorderPane();
borderPane.setCenter(mediaView);
//borderPane.add(logoPanel); <<<<<<< Error
Scene scene = new Scene(borderPane, 1024, 800);
scene.setFill(javafx.scene.paint.Color.BLACK);
stage.setTitle("Media Player");
stage.setScene(scene);
stage.show();
mediaPlayer.setAutoPlay(true);
BorderPane is a JavaFX Node whereas JPanel is a Java Swing Component.
You cannot add a JPanel to a BorderPane, what you are looking for instead is the JavaFX equivalent of the JPanel which is the Pane class.
If you are developing using JavaFX it is easier to just use JavaFX components. If you must use Swing components then you can use the SwingNode class.
What you basically want to achieve: add some Swing components to an JavaFX application.
You have to use SwingNode class to "wrap" a JComponent.
SwingNode Class
JavaFX 8 introduces the SwingNode class, which is located in the
javafx.embed.swing package. This class enables you to embed Swing
content in a JavaFX application. To specify the content of the
SwingNode object, call the setContent method, which accepts an
instance of the javax.swing.JComponent class.
You can check this tutorial how embed Swing component into JavaFX application.
Small example to put a Swing Button into the center of a BorderPane:
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
SwingNode swingNode = new SwingNode();
JButton jButton = new JButton("I am a Swing button");
jButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Message from Swing");
}
});
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
swingNode.setContent(jButton);
}
});
root.setCenter(swingNode);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
By the way, BorderPane has no method "add" (as in your commented line):
You can use setCenter, setTop, setBottom, setLeft and setRight to add Nodes into it (as you used to fill the center).
If your goal was not to embed Swing into JavaFX, just to use JavaFX controls, you can check this article what controls JavaFX has by default.
The starting point for a JavaFX application is start method. But in the sample JavaFX applications, there is a main method included as well. What is the use of main method in this particular case and why was there a need to define start() as starting point for JavaFX. Couldn't we simply use the main method to define a starting point like Swings?
A sample HelloWorld application:
public class HelloWorld extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button("Hello World");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
From Oracle Docs ,
The main() method is not required for JavaFX applications when the JAR
file for the application is created with the JavaFX Packager tool,
which embeds the JavaFX Launcher in the JAR file. However, it is
useful to include the main() method so you can run JAR files that were
created without the JavaFX Launcher, such as when using an IDE in
which the JavaFX tools are not fully integrated. Also, Swing
applications that embed JavaFX code require the main() method.
What is the best practice way to start a java swing application? Maybe there is another way to do it.
I want to know if i have to use the SwingUtilities class to start the application (secound possibility) or not (first possibility).
public class MyFrame extends JFrame {
public void createAndShowGUI() {
this.setSize(300, 300);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
// add components and stuff
this.setVisible(true);
}
public static void main(String[] args) {
// First possibility
MyFrame mf = new MyFrame();
mf.createAndShowGUI();
// Secound possibility
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
MyFrame mf = new MyFrame();
mf.createAndShowGUI();
}
});
}
}
Only the second way is correct. Swing components must be created and accessed only in the event dispatch thread. See concurrency in swing. The relevant quote:
Why does not the initial thread simply create the GUI itself? Because almost all code that creates or interacts with Swing components must run on the event dispatch thread. This restriction is discussed further in the next section.
So yes, you need to use invokeLater().