Only the newest javafx button object works - java

Im trying to create a program that 'clones' itself, by making a new window and button etc. My issue is that only the newest created button functions. The previously made windows only generate an error, and not a window.
HelloController.java
package com.example.vboxes;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.Random;
import static javafx.stage.StageStyle.DECORATED;
public class Controller
{
public static Random rand = new Random();
public static Rectangle2D bounds = Screen.getPrimary().getVisualBounds();
public HelloApplication hello = new HelloApplication();
public VBox[] boxes = new VBox[99999];
public Scene[] scenes = new Scene[99999];
public Stage[] stages = new Stage[99999];
public static int i = 0;
#FXML
private VBox box;
#FXML
public Button button;
#FXML
private Label text;
#FXML
protected void onClick() throws IOException
{
boxes[i] = new VBox();
scenes[i] = new Scene(hello.loader.load(), 320, 240);
stages[i] = new Stage(DECORATED);
stages[i].setScene(scenes[i]);
stages[i].setTitle("Dont click too many!");
stages[i].show();
double x = bounds.getMinX() + (bounds.getWidth() - scenes[i].getWidth());
double y = bounds.getMinY() + (bounds.getHeight() - scenes[i].getHeight());
stages[i].setX(rand.nextDouble(x));
stages[i].setY(rand.nextDouble(y));
System.out.println(i);
i++;
}
}
HelloApplication.java
package com.example.vboxes;
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
{
public FXMLLoader loader = new FXMLLoader(getClass().getResource("hello-view.fxml"));
#Override
public void start(Stage stage) throws IOException
{
Scene scene = new Scene(loader.load(), 320, 240);
stage.setTitle("Don't exit!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args)
{
launch();
}
}
hello-view.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<VBox fx:id="box" alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="com.example.vboxes.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
</padding>
<Label fx:id="text"/>
<Button fx:id="buttons" text="Click me and more will appear!" onAction="#onClick"/>
</VBox>
HelloController.java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>VBOXES</artifactId>
<version>1.0-SNAPSHOT</version>
<name>VBOXES</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.8.2</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-web</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>17.0.1</version>
</dependency>
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>11.1.1</version>
</dependency>
<dependency>
<groupId>com.dlsc.formsfx</groupId>
<artifactId>formsfx-core</artifactId>
<version>11.3.2</version>
<exclusions>
<exclusion>
<groupId>org.openjfx</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.synedra</groupId>
<artifactId>validatorfx</artifactId>
<version>0.2.1</version>
<exclusions>
<exclusion>
<groupId>org.openjfx</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.kordamp.ikonli</groupId>
<artifactId>ikonli-javafx</artifactId>
<version>12.3.0</version>
</dependency>
<dependency>
<groupId>org.kordamp.bootstrapfx</groupId>
<artifactId>bootstrapfx-core</artifactId>
<version>0.4.0</version>
</dependency>
<dependency>
<groupId>eu.hansolo</groupId>
<artifactId>tilesfx</artifactId>
<version>11.48</version>
<exclusions>
<exclusion>
<groupId>org.openjfx</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.almasb</groupId>
<artifactId>fxgl</artifactId>
<version>17</version>
<exclusions>
<exclusion>
<groupId>org.openjfx</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>com.example.vboxes/com.example.vboxes.HelloApplication</mainClass>
<launcher>app</launcher>
<jlinkZipName>app</jlinkZipName>
<jlinkImageName>app</jlinkImageName>
<noManPages>true</noManPages>
<stripDebug>true</stripDebug>
<noHeaderFiles>true</noHeaderFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I attempted creating a button array that way each button functions, but I couldnt figure out how to link the button array to hello-view.fxml

I don't really understand the purpose of a lot of the code you wrote. If you just want the controller to be able to reload the same FXML, you can just do exactly that in the button handler.
The code you wrote fails if you try to use the same button twice. The reason is that each controller instance has a reference to one instance of the HelloApplication class, and via that reference accesses the FXMLLoader instance exposed by that object.
(As an aside, it's always wrong to instantiate the Application class.)
So if you press the same button twice, you attempt to call load(...) on the same FXMLLoader instance twice, and this won't work, at least with your setup, because the FXMLLoader can't load your FXML file when the root is already set (which it will be from the previous invocation of load()). (You could probably work around this by calling setRoot(null) on the loader, but the FXMLLoader is simply not designed to be used this way.)
Here's a working version of the Application class:
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 loader = new FXMLLoader(getClass().getResource("hello-view.fxml"));
Scene scene = new Scene(loader.load(), 320, 240);
stage.setTitle("Don't exit!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args)
{
launch();
}
}
And then all you need in the controller is
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.Random;
import static javafx.stage.StageStyle.DECORATED;
public class HelloController
{
private static final Random rand = new Random();
// As things stand, you don't actually need any of the #FXML-annotated fields:
// #FXML
// private VBox box;
// #FXML
// private Button button;
// #FXML
// private Label text;
#FXML
protected void onClick() throws IOException
{
FXMLLoader loader = new FXMLLoader(getClass().getResource("hello-view.fxml"));
int width = 320 ;
int height = 240 ;
Scene scene = new Scene(loader.load(), width, height);
Stage stage = new Stage(DECORATED);
stage.setScene(scene);
stage.setTitle("Dont click too many!");
Rectangle2D bounds = Screen.getPrimary().getBounds();
double x = bounds.getMinX() + (bounds.getWidth() - width);
double y = bounds.getMinY() + (bounds.getHeight() - height);
stage.setX(rand.nextDouble(x));
stage.setY(rand.nextDouble(y));
stage.show();
}
}
If you want to avoid hard-coding the location of the FXML a second time, you can inject it into the controller:
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.Random;
import static javafx.stage.StageStyle.DECORATED;
public class HelloController
{
private static final Random rand = new Random();
#FXML
private URL location;
#FXML
protected void onClick() throws IOException
{
FXMLLoader loader = new FXMLLoader(location);
int width = 320 ;
int height = 240 ;
Scene scene = new Scene(loader.load(), width, height);
Stage stage = new Stage(DECORATED);
stage.setScene(scene);
stage.setTitle("Dont click too many!");
Rectangle2D bounds = Screen.getPrimary().getBounds();
double x = bounds.getMinX() + (bounds.getWidth() - width);
double y = bounds.getMinY() + (bounds.getHeight() - height);
stage.setX(rand.nextDouble(x));
stage.setY(rand.nextDouble(y));
stage.show();
}
}

Related

JavaFx zooming and panning an image with overlaid fixed scale labels

I am a doctor at a University and I am developing X-ray analysis software in which a user defines anatomical points with small circles by placing them on an X-ray image. I'm satisfied so far, but I need to implement zooming and panning using a mouse wheel, according to the mouse position.
I simplified my code to be clear, the original one is way complicated than that.
In this algorithm, points should NOT move according to the image while zooming and panning so their position is maintained and the Label near the point has to stay in the same font size while zooming (we don't want to see gigantic Label). I am stuck at this point.
Please help can you just generate this algorithm?
Here is the sample:
Here is my java code:
package main.java;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Circle;
public class ZoomClass {
#FXML
AnchorPane xRayAnchorPane;
#FXML
ImageView xRayImage;
#FXML
ScrollPane xRayScrollPane;
#FXML
Label pointsLabel;
public void initialize() {
xRayImage.setOnMouseClicked(mouseEvent ->
{
if(mouseEvent.getButton().equals(MouseButton.PRIMARY)) // ADD POINTS
{
Circle circle = new Circle();
circle.setCenterX(mouseEvent.getX()+58); // Some Offset values to proper positioning
circle.setCenterY(mouseEvent.getY()+75); // Some Offset values to proper positioning
circle.setRadius(2);
xRayAnchorPane.getChildren().add(circle); // Adding circle to mainFrame
pointsLabel.setText("A"); // Defining the point's name
pointsLabel.setLayoutX(circle.getCenterX()+5); // Some Offset values to proper positioning
pointsLabel.setLayoutY(circle.getCenterY()); // Some Offset values to proper positioning
}
});
}
}
And my FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="650.0" prefWidth="851.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.java.ZoomClass" fx:id="xRayAnchorPane">
<children>
<ScrollPane layoutX="56.0" layoutY="71.0" prefHeight="533.0" prefWidth="743.0" fx:id="xRayScrollPane">
<content>
<ImageView fitHeight="736.0" fitWidth="739.0" pickOnBounds="true" preserveRatio="true" fx:id="xRayImage">
<image>
<Image url="#ceph2.jpg" />
</image>
</ImageView>
</content>
</ScrollPane>
<Label fx:id="pointsLabel" layoutX="14.0" layoutY="138.0" />
</children>
</AnchorPane>
According to this question, you need to create a group element for the elements you want to zoom in. When you create new circles, you should add to zoom group. Finally, apply zoom on the group element you created
Does this help?
The scale factor is set only on the ImageView by using the mouse wheel with CTRL held down.
The labels are placed in the AnchorPane outside of the ScrollPane, so they are not effected by the pan and zoom as you require.
package com.stackoverflow.zoom;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.input.ZoomEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Zoomer extends Application {
private AnchorPane ap;
private ImageView imgView;
private char markTxt = 'A';
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
ap = new AnchorPane();
Image img = new Image("https://upload.wikimedia.org/wikipedia/commons/d/dc/Medical_X-Ray_imaging_SEQ07_nevit.jpg");
imgView = new ImageView(img);
ScrollPane sp = new ScrollPane(imgView);
AnchorPane.setTopAnchor(sp, 0.0);
AnchorPane.setLeftAnchor(sp, 0.0);
AnchorPane.setBottomAnchor(sp, 0.0);
AnchorPane.setRightAnchor(sp, 0.0);
ap.getChildren().add(sp);
imgView.setOnMouseClicked(this::onClick);
imgView.setOnScroll(this::imageScrolled);
Scene scene = new Scene(ap);
primaryStage.setTitle("Zoom Image");
primaryStage.setScene(scene);
primaryStage.show();
}
public void onClick(MouseEvent event) {
if (event.getButton() == MouseButton.PRIMARY) {
placeMarker(event.getSceneX(), event.getSceneY());
}
}
private void imageScrolled(ScrollEvent event) {
// When holding CTRL mouse wheel will be used for zooming
if (event.isControlDown()) {
double delta = event.getDeltaY();
double adjust = delta / 1000.0;
double zoom = Math.min(10, Math.max(0.1, imgView.getScaleX() + adjust));
setImageZoom(zoom);
event.consume();
}
}
private void placeMarker(double sceneX, double sceneY) {
Circle circle = new Circle(2);
circle.setStroke(Color.RED);
circle.setTranslateY(-12);
Label marker = new Label(String.valueOf(markTxt), circle);
marker.setTextFill(Color.RED);
markTxt++;
Point2D p = ap.sceneToLocal(sceneX, sceneY);
AnchorPane.setTopAnchor(marker, p.getY());
AnchorPane.setLeftAnchor(marker, p.getX());
ap.getChildren().add(marker);
}
private void setImageZoom(double factor) {
imgView.setScaleX(factor);
imgView.setScaleY(factor);
}
}

Cannot change the width of a button below a certain minimum

I have this code:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.Image;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundImage;
import javafx.scene.layout.BackgroundSize;
import javafx.scene.layout.TilePane;
import javafx.stage.Stage;
public class ToggleButtonSize extends Application {
#Override
public void start(Stage stage) throws Exception {
var toggleButton = new ToggleButton();
toggleButton.setMaxHeight(10);
toggleButton.setMaxWidth(10);
// tried also
toggleButton.setStyle("-fx-max-width: 10; -fx-pref-width: 10;");
var pane = new FlowPane(toggleButton);
var scene = new Scene(pane);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This code works fine, but when I use MobileApplication instead the minimum width does not go to 10:
How can I shrink the size like when using Application?

how to combine fxml file with 3d Box and PerspectiveCamera

As a newbie I'm trying to do some my own projects to practice Java, JavaFX and Raspberry coding. Ma latest goal which I set for myself is 3D visualization of force from tensometric beam. I managed to achieve simple chart and and simple visualization of actual pressure force (in circle).
(https://imagizer.imageshack.com/img922/2663/spBwMs.gif)
Now I'd like to represent it as 3D bar.
I tried to understood some examples from Ensemble: jnlps://download.oracle.com/otndocs/products/javafx/8/samples/Ensemble/Ensemble.jnlp
and I managed to do something like that:
(https://imagizer.imageshack.com/img921/2766/12te0a.gif)
but I'd like to achieve something similar using FXML file.
I tried to code it but no effect so far. I'd like you use some Hbox to place 2 boxes next to each other, but then I don't know where to place Camera properly. Actually 3D with javaFX is a little bit of black magic for me ;)
Main.java:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root,800,800, true, SceneAntialiasing.BALANCED));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller.java:
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.fxml.FXML;
import javafx.scene.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.util.Duration;
public class Controller{
#FXML
private AnchorPane pane;
#FXML
private Box box;
#FXML
private PerspectiveCamera camera;
final Rotate rx = new Rotate(0, Rotate.X_AXIS);
final Rotate ry = new Rotate(0, Rotate.Y_AXIS);
final Rotate rz = new Rotate(0, Rotate.Z_AXIS);
private Timeline animation;
#FXML
void initialize() {
box.setMaterial(new PhongMaterial(Color.ORANGE));
/* box.setDepth(100);
box.setWidth(100);
box.setHeight(100);*/
rx.setAngle(90);
ry.setAngle(25);
box.getTransforms().addAll(rz, ry, rx);
animation = new Timeline();
animation.getKeyFrames().addAll(
new KeyFrame(Duration.ZERO,
new KeyValue(box.depthProperty(), 0d),
new KeyValue(box.translateYProperty(),400d)),
new KeyFrame(Duration.seconds(5),
new KeyValue(box.depthProperty(), 800d),
new KeyValue(box.translateYProperty(), 0d)));
animation.setCycleCount(Timeline.INDEFINITE);
camera.getTransforms().addAll (
new Rotate(-35, Rotate.X_AXIS),
new Translate(0, 0, 10)
);
box.sceneProperty().addListener(new InvalidationListener() {
#Override
public void invalidated(Observable observable) {
box.getScene().setCamera(camera);
box.sceneProperty().removeListener(this);
}
});
animation.play();
}
}
main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.PerspectiveCamera?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Box?>
<AnchorPane fx:id="pane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="check.brakes.Controller">
<children>
<Box fx:id="box" depth="100.0" height="100.0" layoutX="380.0" layoutY="673.0" width="100.0">
</Box>
<PerspectiveCamera fx:id="camera" farClip="70.0" fieldOfView="35.0" nearClip="0.5" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
I expect the bars should look like from the example I provided.
Update
I did it, I'm sure it's not perfect at all, but somehow I have to start.
BTW.
Why is that, when i resize application window, camera angle is changing ?

Java OpenGL window closes as soon as it opens

I'm using maven to import the jogamp dependencies.
Here is the pom.xml content :
<dependencies>
<dependency>
<groupId>org.jogamp.gluegen</groupId>
<artifactId>gluegen-rt-main</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.jogamp.jogl</groupId>
<artifactId>jogl-all-main</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
The code below should create a window.
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLProfile;
public class Renderer {
private static GLWindow window = null;
public static void init(){
GLProfile.initSingleton();
GLProfile profile = GLProfile.get(GLProfile.GL2);
GLCapabilities caps = new GLCapabilities(profile);
window = GLWindow.create(caps);
window.setSize(640, 360);
window.setResizable(false);
window.setVisible(true);
}
public static void main(String[] args){
init();
}
}
In my case, it creates a window that closes as soon as it opens, and it says Process finished with exit code 0. I followed these instructions, but even by adding the joal and jocl support into maven it did not work.
You need FPSAnimator
public static void init(){
GLProfile.initSingleton();
GLProfile profile = GLProfile.get(GLProfile.GL2);
GLCapabilities caps = new GLCapabilities(profile);
window = GLWindow.create(caps);
window.setSize(640, 360);
window.setResizable(false);
window.setVisible(true);
FPSAnimator animator = new FPSAnimator(window, 30);
animator.start();
}

Neo4j - Lucene - maven shade plugin - Works fine through the Netbeans but doesnt work as jar

I created a maven java application to execute some neo4j queries. I have a class in which neo4j queries are executing and one more in which i made a gui with Swing so i can use a button to execute a query and show the results in a textArea. Everything works fine if i run the project in Netbeans but when i'm using maven shade plugin to create a fat jar of this project, something happens and the neo4j commands dont work. I think that the problem is at lucene jars(from apache folder and neo4j folder) so i used some code in the pom.xml file to fix it, with no luck. Maybe the problem is because of same class name conflict in the classpath.
myJFrame.java
package com.mycompany.neo4jqueries;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
/**
*
* #author Dar309
*/
public class myJFrame extends JPanel {
private JComboBox firstComboBox;
private JTextArea queryTextArea, resultTextArea, infoTextArea;
private String[] comboBoxItems, queryList;
private JButton executeButton;
private Font monosSpacedFont = new Font("monospaced", Font.PLAIN, 12);
private JProgressBar progressBar;
private Task myTask;
private long miliBeforeExec = 0, miliAfterExec = 0, execTime = 0;
public myJFrame() {
super(new BorderLayout());
JPanel firstPanel = new JPanel();
BorderLayout fpL = new BorderLayout();
firstPanel.setLayout(fpL);
JPanel topPanel = new JPanel();
topPanel.setLayout(new BorderLayout());
JPanel topPanel1 = new JPanel();
topPanel1.setLayout(new FlowLayout(FlowLayout.CENTER));
comboBoxItems = new String[]{"1",
"The Top 10 Stack Overflow Users",
"The Top 5 tags That Jon Skeet Used in Asking Questions"};
queryList = new String[]{"match (n) \nreturn head(labels(n)) as label, count(*)",
"match (u:User) \nwith u,size( (u)-[:POSTED]->()) as posts order by posts desc limit 10 \nreturn u.name, posts",
"match (u:User)-[:POSTED]->()-[:HAS_TAG]->(t:Tag) \nwhere u.name = 'Jon Skeet' \nreturn t,count(*) as posts order by posts desc limit 5"};
firstComboBox = new JComboBox(comboBoxItems);
firstComboBox.setSelectedIndex(0);
firstComboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
queryTextArea.setText(queryList[firstComboBox.getSelectedIndex()]);
}
});
topPanel1.add(firstComboBox);
JPanel topPanel2 = new JPanel();
topPanel2.setLayout(new FlowLayout());
queryTextArea = new JTextArea();
queryTextArea.setText(queryList[0]);
queryTextArea.setFont(monosSpacedFont);
queryTextArea.setEditable(false);
JScrollPane queryScrollPane = new JScrollPane(queryTextArea);
queryScrollPane.setPreferredSize(new Dimension(450, 110));
topPanel2.add(queryScrollPane);
JPanel topPanel3 = new JPanel();
topPanel3.setLayout(new FlowLayout());
progressBar = new JProgressBar(0, 100);
progressBar.setValue(0);
progressBar.setString("No progress yet");
progressBar.setStringPainted(true);
executeButton = new JButton("Execute");
executeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
executeButton.setEnabled(false);
progressBar.setIndeterminate(true);
firstComboBox.setEnabled(false);
progressBar.setString("Loading...");
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
miliBeforeExec = System.currentTimeMillis();
//Instances of javax.swing.SwingWorker are not reusuable, so
//we create new instances as needed.
myTask = new Task();
myTask.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress" == evt.getPropertyName()) {
// int progress = (Integer) evt.getNewValue();
// progressBar.setValue(progress);
}
}
});
myTask.execute();
}
});
topPanel3.add(progressBar);
topPanel3.add(executeButton);
topPanel.add(topPanel1, BorderLayout.NORTH);
topPanel.add(topPanel2, BorderLayout.CENTER);
topPanel.add(topPanel3, BorderLayout.SOUTH);
firstPanel.add(topPanel, BorderLayout.NORTH);
JPanel resultPanel = new JPanel();
resultPanel.setLayout(new BorderLayout());
resultTextArea = new JTextArea();
resultTextArea.setFont(monosSpacedFont);
resultTextArea.setText("");
resultTextArea.setEditable(false);
JScrollPane centerScrollPane = new JScrollPane(resultTextArea);
centerScrollPane.setPreferredSize(new Dimension(550, 200));
centerScrollPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0));
resultPanel.add(centerScrollPane, BorderLayout.CENTER);
infoTextArea = new JTextArea();
infoTextArea.setRows(2);
infoTextArea.setFont(monosSpacedFont);
infoTextArea.setEditable(false);
resultPanel.add(infoTextArea, BorderLayout.SOUTH);
firstPanel.add(resultPanel, BorderLayout.CENTER);
add(firstPanel, BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame();
// frame.setSize(650, 550);
frame.setSize(Toolkit.getDefaultToolkit().getScreenSize().width / 2,Toolkit.getDefaultToolkit().getScreenSize().height / 2);
frame.setMinimumSize(new Dimension(frame.getWidth(), frame.getHeight()));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Execute your Neo4j queries");
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
frame.setLocation(x, y);
//Create and set up the content pane.
JComponent newContentPane = new myJFrame();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
class Task extends SwingWorker<Void, Void> {
/*
* Main task. Executed in background thread.
*/
#Override
public Void doInBackground() {
// Random random = new Random();
// int progress = 0;
//Initialize progress property.
setProgress(0);
System.out.println("popo");
resultTextArea.append("popo");
myQuery mq = new myQuery();
mq.run(myJFrame.this);
resultTextArea.append("metaaaa");
System.out.println("metaaa");
// setProgress(Math.min(progress, 100));
return null;
}
/*
* Executed in event dispatching thread
*/
#Override
public void done() {
Toolkit.getDefaultToolkit().beep();
progressBar.setIndeterminate(false);
executeButton.setEnabled(true);
firstComboBox.setEnabled(true);
// resultTextArea.setCaretPosition(resultTextArea.getText().length());
setCursor(null); //turn off the wait cursor
miliAfterExec = System.currentTimeMillis();
execTime = miliAfterExec - miliBeforeExec;
// execTime += 11140000;
if (execTime < 60 * 1000) {
infoTextArea.setText("Total time: " + (double) (execTime / 1000.000) + "s");
}
// else if(execTime >= (60 * 1000) && execTime < (3600 * 1000) ){
else if (execTime >= (60 * 1000)) {
long temp = execTime;
for (long i = 0; i < execTime / (60 * 1000); i++) {
temp -= (60 * 1000);
}
infoTextArea.setText("Total time: " + (execTime / (60 * 1000)) + ":" + (double) (temp / 1000.000) + "s");
}
Date date = new Date();
infoTextArea.append("\nFinished at: " + date.toString());
progressBar.setString("Done!");
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
public JTextArea getResultTextArea() {
return resultTextArea;
}
public JTextArea getQueryTextArea() {
return queryTextArea;
}
}
myQuery.java
/*
* 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 com.mycompany.neo4jqueries;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.JFrame;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Result;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.neo4j.helpers.collection.Iterators;
/**
*
* #author Dar309
*/
public class myQuery {
private static final File DB_PATH = new File("D:/IU/Διπλωματική/neo4j-community-3.1.2/data/databases/graph.db");
String resultString;
String columnsString;
String nodeResult;
String rows = "";
void run(myJFrame myFrame) {
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);
myFrame.getResultTextArea().append("sdadsdsadsads");
System.out.println("naiiiii");
try (Transaction ignored = db.beginTx();
// Result result = db.execute("match (u:User) with u,size( (u)-[:POSTED]->()) as posts order by posts desc limit 10 return u.name, posts")) {
Result result = db.execute(myFrame.getQueryTextArea().getText() ) ) {
// START SNIPPET: columns
List<String> columns = result.columns();
// END SNIPPET: columns
columnsString = columns.toString();
// resultString = db.execute( "match (u:User) with u,size( (u)-[:POSTED]->()) as posts order by posts desc limit 10 return u.name, posts" ).resultAsString();
resultString = result.resultAsString();
System.out.println("\n\ncolumnsString\n------------------------------------------");
System.out.println(columnsString);
System.out.println("\n\nresultString\n------------------------------------------");
System.out.println(resultString);
myFrame.getResultTextArea().append(resultString);
try {
PrintWriter writer = new PrintWriter("the-file-name.txt", "UTF-8");
writer.print(resultString);
writer.close();
} catch (IOException e) {
// do something
}
}
db.shutdown();
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>Neo4jQueries</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
<name>neo4jQueries</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>shaded</shadedClassifierName>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>org.apache.lucene</pattern>
<shadedPattern>shaded_lucene_5_5_0.org.apache.lucene</shadedPattern>
</relocation>
<relocation>
<pattern>org.neo4j</pattern>
<shadedPattern>shaded_neo4j.org.neo4j</shadedPattern>
</relocation>
</relocations>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.mycompany.neo4jqueries.myJFrame</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>neo4j-repo</id>
<name>Neo4j Repository</name>
<url>http://m2.neo4j.org/content/repositories/releases</url>
</repository>
</repositories>
</project>
When i double click on jar, i see the gui and all works fine till myQuery class is called, then no neo4j commands are executing but no error message showed.
Does anyone can help me solve this please?
Your program hardcodes the path to the neo4j DB.
So, if you are not running the jar file on the same machine on which you developed your code, it would not be able to find the DB and will throw an exception.
However, as the doc for InvokeLater says, if the Runnable you pass to it:
throws an uncaught exception the event dispatching thread will unwind
(not the current thread)
That means that your thread will never see any uncaught exceptions unless you explicitly tell Swing to use an exception handler that you provide. See this question and its 2 top-scoring answers for how to do that (depending on which version of Java you are using).

Categories