I'm new to working with javaFX and recently ran into the following error when running the application through Eclipse.
My code:
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class WindowBetaV02 extends AbstractWindow{
public static void main(String[] args){
launch(args);
}
public void start(Stage mainStage){
height = 480;
width = 640;
mainStage = new Stage();
mainStage.setTitle("AMQ");
mainStage.setScene(drawGUIGameNormal());
mainStage.setResizable(false);
mainStage.show();
}
private Scene drawGUIGameNormal(){
//Draw gui
}
}
import javafx.application.Application;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.stage.Stage;
public abstract class AbstractWindow extends Application {
protected int height;
protected int width;
protected GameFunctions controller;
public abstract void start(Stage stage);
protected GridPane createPlayerPane(int width, int height){
GridPane playerPane = createPixelGridPane(width, height);
playerPane.getStyleClass().add("playerPane");
playerPane.add(createPlayerTable(), 10, 10, width-10, width-10);
return playerPane;
}
#SuppressWarnings({ "rawtypes", "unchecked" })
protected TableView createPlayerTable(){
TableView table = new TableView();
TableColumn points = new TableColumn("Points");
points.setMaxWidth(30);
points.setMinWidth(30);
points.setCellFactory(new PropertyValueFactory<Players, Integer>("points"));
TableColumn player = new TableColumn("Player");
player.setMaxWidth(100);
player.setMinWidth(100);
player.setCellFactory(new PropertyValueFactory<Players, String>("playerName"));
table.setItems(controller.getPlayers());
table.getColumns().addAll(player, points);
return table;
}
protected GridPane createPixelGridPane(int width, int height){
GridPane pane = new GridPane();
for(int i = 0; i < width; i++){
pane.getColumnConstraints().add(new ColumnConstraints(1));
}
for(int i = 0; i < height; i++){
pane.getRowConstraints().add(new RowConstraints(1));
}
return pane;
}
}
The error
Exception in thread "main" java.lang.RuntimeException: Application launch error
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:122)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.UnsatisfiedLinkError: com.sun.glass.ui.win.WinApplication._invokeLater(Ljava/lang/Runnable;)V
at com.sun.glass.ui.win.WinApplication._invokeLater(Native Method)
at com.sun.glass.ui.Application.invokeLater(Application.java:338)
at com.sun.javafx.tk.quantum.QuantumToolkit.defer(QuantumToolkit.java:620)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:173)
at com.sun.javafx.application.PlatformImpl.runAndWait(PlatformImpl.java:212)
at com.sun.javafx.application.PlatformImpl.tkExit(PlatformImpl.java:320)
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:421)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
... 1 more
Anyone know how to fix this error?
-Edit-
Added the code for the AbstractWindow class
You are in JavaFx, your Main class have to extends Application and not Window
Related
I'm having issues to render a SVG Image in a TableView with a CellFactory.
Im using this code here, but it don't work, the svg image is scaled, but it don't resize.
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.shape.SVGPath;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
public class SVGTable extends Application {
private ObservableList<SVGExample> examples;
public static void main(String[] args) {
launch(args);
}
public SVGTable() {
examples = FXCollections.observableArrayList();
examples.addAll(new SVGExample(289),
new SVGExample(42),
new SVGExample(120));
}
#Override
public void start(Stage primaryStage) throws Exception {
AnchorPane pane = new AnchorPane();
Scene scene = new Scene(pane);
TableView<SVGExample> tableView = new TableView<>();
tableView.setMinWidth(500);
tableView.setMinHeight(400);
tableView.setItems(examples);
final TableColumn<SVGExample, Integer> ping = new TableColumn<>("Ping");
ping.setCellValueFactory(new PropertyValueFactory<>("ping"));
ping.setCellFactory(param -> new PingCell());
tableView.getColumns().add(ping);
pane.getChildren().add(tableView);
primaryStage.setScene(scene);
primaryStage.show();
}
public class SVGExample {
private final IntegerProperty ping = new SimpleIntegerProperty();
public SVGExample(int ping) {
setPing(ping);
}
public int getPing() {
return ping.get();
}
public IntegerProperty pingProperty() {
return ping;
}
public void setPing(int ping) {
this.ping.set(ping);
}
}
public class PingCell extends TableCell<SVGExample, Integer> {
private HBox hBox = new HBox();
private Label label;
private int oldValue;
private PingCell() {
label = new Label();
hBox.setAlignment(Pos.CENTER_LEFT);
oldValue = Integer.MIN_VALUE;
}
#Override
protected void updateItem(final Integer item, final boolean empty) {
if (item != null) {
label.setText(item + "ms");
int i = (item + 50) / 100;
if (i < 1)
i = 1;
if (4 < i)
i = 4;
if (i != oldValue) {
SVGPath svgPath1 = new SVGPath();
svgPath1.setContent("M149.2,8.3L127-13.9c42.4-42.4,98.7-65.8,158.5-65.8c59.8,0,116.1,23.4,158.5,65.8L421.8,8.3c-36.5-36.5-84.9-56.6-136.3-56.6C234.1-48.2,185.7-28.1,149.2,8.3z");
SVGPath svgPath2 = new SVGPath();
svgPath2.setContent("M190.9,50.1l-22.2-22.2C200-3.4,241.4-20.6,285.5-20.6c44.1,0,85.5,17.2,116.8,48.4l-22.2,22.2c-25.3-25.3-58.9-39.2-94.6-39.2C249.8,10.8,216.2,24.8,190.9,50.1z");
SVGPath svgPath3 = new SVGPath();
svgPath3.setContent("M232.7,91.8l-22.2-22.2c20.1-20.1,46.7-31.1,75-31.1s55,11.1,75,31.1l-22.2,22.2c-14.1-14.1-32.9-21.9-52.8-21.9C265.6,69.9,246.8,77.7,232.7,91.8z");
SVGPath svgPath4 = new SVGPath();
svgPath4.setContent("M285.5,98.1c-12.8,0-24.5,5.2-32.9,13.6l32.9,32.9l32.9-32.9C310,103.3,298.3,98.1,285.5,98.1z");
Shape s = SVGPath.union(SVGPath.union(SVGPath.union(svgPath1, svgPath2), svgPath3), svgPath4);
s.setScaleX(0.1);
s.setScaleY(0.1);
hBox.getChildren().clear();
hBox.getChildren().addAll(s, label);
}
setGraphic(hBox);
}
}
}
}
After run, it's look like this:
You can wrap the Shape in a Group to force re-size of layout bounds.
hBox.getChildren().addAll(new Group(s), label);
Scale is a type of transform and according to Javadocs:
Any transform, effect, or state applied to a Group will be applied to all children of that group. Such transforms and effects will NOT be included in this Group's layout bounds, however if transforms and effects are set directly on children of this Group, those will be included in this Group's layout bounds.
What is the correct way to manipulate an Observable collection in a thread, where the collection is already bound to a JavaFX UI-node?
In my sample application, the connection between the collection and the nodes are broken before the thread can do any manipulation; and then they are re-connected after the thread is done. The methods are disconnectObservable() and connectObservable() respectively. Without these two methods, java.lang.IllegalStateException: Not on FX application thread is reported.
Ideally I would like ChangeObservableTask to make its changes to mWords, and then I would call some method to tell mObservable to refresh itself and notify its listeners. Is there such a thing?
Thanks.
package theapp;
import java.util.LinkedList;
import java.util.List;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ThreadObList extends Application {
private final List<String> mWords;
private final ObservableList<String> mObservable;
private ListView mListView;
private Label mCount;
public ThreadObList() {
mWords = new LinkedList<>();
mObservable = FXCollections.observableList(mWords);
mWords.add("park");
}
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Start thread");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
ChangeObservableTask task = new ChangeObservableTask();
Thread thd = new Thread(task);
disconnectObservable();
thd.start();
try {
task.get();
System.out.println("ChangeObservableTask exited normally.");
}
catch(Exception ex) {
System.out.println(ex.getMessage());
}
connectObservable();
}
});
mCount = new Label();
mListView = new ListView();
VBox root = new VBox(5, btn, mCount, mListView);
VBox.setVgrow(mListView, Priority.ALWAYS);
connectObservable();
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private void connectObservable() {
mListView.setItems(mObservable);
mCount.textProperty().bind(Bindings.size(mObservable).asString());
}
private void disconnectObservable() {
mListView.setItems(null);
mCount.textProperty().unbind();
}
private class ChangeObservableTask extends Task<Void> {
#Override
protected Void call() throws Exception {
mObservable.add("dart");
mObservable.add("truck");
mObservable.add("ocean");
return null;
}
}
}
Once the list is used as the contents of the ListView, you can only manipulate it from the FX Application Thread. See the Task javadocs for a bunch of usage examples.
You can create a copy of your ObservableList and pass it to your task, manipulate the copy and return the results. Then update the ObservableList with the results in the onSucceeded handler.
Also note that you shouldn't make any blocking calls, such as task.get() on the FX Application Thread, as you can make the UI unresponsive by doing so.
So you should do something along the lines of:
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
ChangeObservableTask task = new ChangeObservableTask(new ArrayList<>(mObservable));
Thread thd = new Thread(task);
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
mObservable.setAll(task.getValue());
}
});
thd.start();
}
});
and
private class ChangeObservableTask extends Task<List<String>> {
private final List<String> data ;
ChangeObservableTask(List<String> data) {
this.data = data ;
}
#Override
protected List<String> call() throws Exception {
data.add("dart");
data.add("truck");
data.add("ocean");
return data;
}
}
Application:
I'm trying to create a slide show inside my JavaFX application. To do this I created a thread and handle the image changes inside that thread. I use Thread.sleep(int) inside the thread to pause the transition between images.
Implementation:
I created the application in the Scene Builder so it's in FXML. The imageview starts out with an image and I gave the imageview an id. Here is a portion of the FXML where the imageview is located:
<Tab>
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="376.0" prefWidth="981.0">
<children>
<ImageView fx:id="myImage" fitHeight="197.0" fitWidth="294.0" layoutX="20.0" layoutY="151.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../Pictures/NevadaDesert.jpg" />
</image>
<effect>
<Glow />
</effect>
</ImageView>
I am getting the imageview inside my Java code with:
#FXML
private ImageView myImage;
Then I handle all the image changes inside the new runnable thread which I call after loading the FXML:
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MyResume.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
(new Thread(new PictureRunnable())).start();
}
The run method from PictureRunnable is shown here:
public void run() {
try {
File file1 = new File("C:/Users/Kyle/Documents/NetBeansProjects/MyResume/src/Pictures/activities.jpg");
File file2 = new File("C:/Users/Kyle/Documents/NetBeansProjects/MyResume/src/Pictures/foodService2.png");
File file3 = new File("C:/Users/Kyle/Documents/NetBeansProjects/MyResume/src/Pictures/NevadaDesert.jpg");
Image a = new Image(file1.toURI().toURL().toExternalForm());
Image b = new Image(file2.toURI().toURL().toExternalForm());
Image c = new Image(file3.toURI().toURL().toExternalForm());
for(int i=0; true; i++) {
//Pause for 5 seconds
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if( i%2 == 0 )
myImage.setImage(a);
else if( i%3 == 0 )
myImage.setImage(b);
else
myImage.setImage(c);
}
}
catch(MalformedURLException e) {
e.printStackTrace();
}
}
Problem:
I'm getting a NullPointerException on the lines where I set the images myImage.setImage(abc).
Is there a problem in my code with how I'm changing the images?
Or is the problem the thread, perhaps I cannot open a new thread and make changes to the Stage?
If you want to set an image on an imageView it has to be on the javafx thread: use Platform.runLater() from your thread or some other mechanism.
I just noticed that my simple slideshow post has a few hits over its history - sorry it had a couple of bugs and the final release of java8 changed the way it handled null pointers in animations. I've fixed those bugs and updated the post.
(i'm notzed)
Using just java
package sample;
import java.util.ArrayList;
import java.util.List;
import javafx.application.*;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.Cursor;
import java.lang.String;
import javafx.scene.layout.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.geometry.*;
import javafx.scene.paint.ImagePattern;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import com.jfoenix.controls.JFXButton;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
private List<String> list = new ArrayList<String>();
int j = 0;
JFXButton lbutton, rButton;
ImageView imageView;
#Override
public void start(Stage primaryStage) {
// images in src folder.
try {
list.add("/image/1.jpg");
list.add("/image/2.jpg");
list.add("/image/3.jpg");
list.add("/image/4.jpg");
list.add("/image/5.jpg");
list.add("/image/6.jpg");
list.add("/image/7.jpg");
list.add("/image/8.jpg");
GridPane root = new GridPane();
root.setAlignment(Pos.CENTER);
lbutton = new JFXButton("<");
rButton = new JFXButton(">");
Image images[] = new Image[list.size()];
for (int i = 0; i < list.size(); i++) {
images[i] = new Image(list.get(i));
}
imageView = new ImageView(images[j]);
imageView.setCursor(Cursor.CLOSED_HAND);
rButton.setOnAction(e -> {
System.out.print("hello");
j++;
if (j > list.size()-1)
{
j = list.size()-1;
imageView.setImage(images[j]);
}
else
{
imageView.setImage(images[j]);
}
});
lbutton.setOnAction(e -> {
System.out.print("hello");
j--;
if (j < 0)
{
j = 0;
imageView.setImage(images[j]);
}
else
{
imageView.setImage(images[j]);
}
});
imageView.setFitHeight(350);
//main controls
AnchorPane pane = new AnchorPane(imageView, rButton, lbutton);
AnchorPane.setTopAnchor(lbutton, 300.0);
AnchorPane.setLeftAnchor(lbutton, 210.0);
AnchorPane.setTopAnchor(rButton, 300.0);
AnchorPane.setRightAnchor(rButton, 210.0);
// Set the stage
Scene scene = new Scene(pane, 600, 600);
imageView.fitWidthProperty().bind(scene.widthProperty());
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.setTitle("Sample");
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I need to be able to call a separate thread. The thread analysis a file and pull stats from that.
The analyzing of the file can take up to 2 minutes and during the analysis data is printed to the logs.
I would like to have a TextArea on the front end that needs to print out the analysis (as it analysis) and I would also like to have a progress bar to indicate the progress. All of this is determined inside the separate thread.
What I have done is creating a method in the UI class to add a string to the Text Area and pass in a reference of this class to the launched thread.
My Main Class
package trymutilthread;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TryMutilThread extends Application {
TextArea ta;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Start");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
startScheduledExecutorService();
}
});
ta = new TextArea();
VBox vBox = new VBox();
vBox.getChildren().addAll(btn, ta);
StackPane root = new StackPane();
root.getChildren().add(vBox);
Scene scene = new Scene(root, 300, 750);
primaryStage.setScene(scene);
primaryStage.show();
}
private void startScheduledExecutorService() {
final TryMutilThread classI = this;
Task<Void> task = new Task<Void>() {
#Override protected Void call() throws Exception {
try {
ta.appendText("Starting Thread\n");
new SomeProcess(classI).doTheLogic();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
};
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
}
public void appendText(String string) {
ta.appendText(string);
}
}
The class that is executed in the thread
package trymutilthread;
public class SomeProcess {
TryMutilThread taClass = null;
public SomeProcess (TryMutilThread taClass) {
this.taClass = taClass;
}
public void doTheLogic() throws Exception{
taClass.appendText("Staring Thread");
for (int i = 0; i < 5000; i++) {
taClass.appendText(String.valueOf(i));
}
taClass.appendText("Ending Thread");
}
}
Now when I execute this it still only output the text to the TextArea once the thread has ended.
I did had a look at the following 2 posts:
JavaFX update textArea
Java client / server thread null pointer exception when quickly communicating messages
I am not able to get the data printed to logs until the process has ended.
I updated my code to create a Task.
But now I am getting the following error when it executes
Executing com.javafx.main.Main from F:\DEV\Projects\TryMutilThread\dist\run404234128\TryMutilThread.jar using platform C:\Program Files\Java\jdk1.7.0_10/bin/java
java.lang.NullPointerException
at com.sun.javafx.sg.prism.NGTextHelper$TextAttributes.computeLinePadding(NGTextHelper.java:405)
at com.sun.javafx.sg.prism.NGTextHelper$TextAttributes.access$200(NGTextHelper.java:292)
at com.sun.javafx.sg.prism.NGTextHelper.buildTextLines(NGTextHelper.java:2357)
at com.sun.javafx.sg.prism.NGTextHelper.validateText(NGTextHelper.java:1847)
at com.sun.javafx.sg.prism.NGTextHelper.getCaretShape(NGTextHelper.java:1435)
at javafx.scene.text.Text.getDecorationShapes(Text.java:1150)
at javafx.scene.text.Text.impl_geomChanged(Text.java:757)
at javafx.scene.text.Text$1.invalidated(Text.java:214)
at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:127)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:161)
at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:67)
at javafx.scene.text.Text.setText(Text.java:188)
at com.sun.javafx.scene.control.skin.TextAreaSkin$17.invalidated(TextAreaSkin.java:610)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:359)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:100)
at javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1034)
at javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1038)
at javafx.scene.control.TextInputControl$TextProperty.invalidate(TextInputControl.java:978)
at javafx.scene.control.TextInputControl$TextProperty.access$200(TextInputControl.java:950)
at javafx.scene.control.TextInputControl$1.invalidated(TextInputControl.java:119)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:155)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:100)
at javafx.scene.control.TextArea$TextAreaContent.insert(TextArea.java:196)
at javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:373)
at javafx.scene.control.TextInputControl.insertText(TextInputControl.java:308)
at javafx.scene.control.TextInputControl.appendText(TextInputControl.java:298)
at trymutilthread.TryMutilThread.appendText(TryMutilThread.java:80)
at trymutilthread.SomeProcess.doTheLogic(SomeProcess.java:26)
at trymutilthread.TryMutilThread$2.call(TryMutilThread.java:66)
at trymutilthread.TryMutilThread$2.call(TryMutilThread.java:62)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1259)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.lang.Thread.run(Thread.java:722)
I then google'd the error and it seems that I need to put the interaction code in a Platform.runlater().
Java client / server thread null pointer exception when quickly communicating messages
I changed the class to execute the thread to be
package trymutilthread;
import javafx.application.Platform;
public class SomeProcess {
TryMutilThread taClass = null;
public SomeProcess(TryMutilThread taClass) {
this.taClass = taClass;
}
public void doTheLogic() throws Exception {
taClass.appendText("Staring Thread");
for (int i = 0; i < 5000; i++) {
//remove this append line
//taClass.appendText(i + "\n");
//And replaced it with platform.runlater
Platform.runLater(new Runnable() {
#Override
public void run() {
taClass.appendText("AGREED" + "\n");
}
});
}
taClass.appendText("Ending Thread");
}
}
It executes without any errors but now it seems to be back to the start... The UI is frozen until all is added to the TextArea
The problem is just that you're flooding the FX Application Thread with too many requests; there's no actual work happening between your Platform.runLater(...) calls. This problem probably goes away with your real application instead of this test, but to mimic the actual long-running work, you can just put a Thread.sleep(...) in there:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class TextAreaBackgroundUpdateExample extends Application {
#Override
public void start(Stage primaryStage) {
final BorderPane root = new BorderPane();
final TextArea textArea = new TextArea();
final ProgressBar progress = new ProgressBar();
final Button startButton = new Button("Start");
final int maxCount = 5000 ;
startButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
for (int i = 1; i <= maxCount; i++) {
Thread.sleep(10);
final int count = i ;
Platform.runLater(new Runnable() {
#Override
public void run() {
textArea.appendText("Processed part " + count + " (of "+maxCount+")\n");
}
});
updateProgress(i, maxCount);
}
return null;
}
};
progress.progressProperty().bind(task.progressProperty());
Thread t = new Thread(task);
t.setDaemon(true);
t.start();
}
});
root.setCenter(textArea);
root.setTop(progress);
root.setBottom(startButton);
final Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
is there a way to have panels with different heights in an accordion in JavaFX? I would like to know how to do it. I've googled it but I haven't found what I need.
you can do this with setPrefHeight of pane....
try this.
pane.setPrefHeight(400);
Try this:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Accordion;
import javafx.scene.control.TitledPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class TitledPaneSample extends Application
{
final String[] imageNames = new String[]{
"Apples", "Flowers", "Leaves"};
final Image[] images = new Image[imageNames.length];
final ImageView[] pics = new ImageView[imageNames.length];
final TitledPane[] tps = new TitledPane[imageNames.length];
public static void main(String[] args)
{
launch(args);
}
#Override
public void start(Stage stage)
{
stage.setTitle("TitledPane");
Scene scene = new Scene(new Group(), 380, 380);
scene.setFill(Color.GHOSTWHITE);
final Accordion accordion = new Accordion();
for (int i = 0; i < imageNames.length; i++)
{
images[i] = new Image(getClass().getResourceAsStream(imageNames[i]
+ ".jpg"));
pics[i] = new ImageView(images[i]);
tps[i] = new TitledPane(imageNames[i], pics[i]);
tps[i].setMinHeight(i * 100);
}
accordion.getPanes().addAll(tps);
accordion.setExpandedPane(tps[0]);
Group root = (Group) scene.getRoot();
root.getChildren().add(accordion);
stage.setScene(scene);
stage.show();
}
}
All you need in addition to the above code is to have the three files placed at the correct location.