LWUIT button issue - java-me

import com.sun.lwuit.Button;
import com.sun.lwuit.Command;
import com.sun.lwuit.Display;
import com.sun.lwuit.Label;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.layouts.BorderLayout;
import com.sun.lwuit.plaf.UIManager;
import com.sun.lwuit.util.Resources;
import java.io.IOException;
public class Ruwwa extends javax.microedition.midlet.MIDlet implements ActionListener{
Form f;
Button mybutton1;
Button mybutton2;
Command exit;
Command ok;
public void startApp() {
Display.init(this);
f = new Form();
try {
Resources r = Resources.open("/mairuwa.res");
UIManager.getInstance().setThemeProps(r.getTheme("Mairuwa Theme"));
} catch (IOException ioe) {
ioe.printStackTrace();
}
mybutton1=new Button("Report A Problem");
mybutton2=new Button("Request Info");
f.setLayout(new BorderLayout());
f.addComponent(BorderLayout.CENTER, new Label("The Mairuwa Portal"));
ok = new Command("OK");
exit = new Command("Exit");
f.addCommand(ok);
f.addCommand(exit);
f.addCommandListener(this);
f.show();
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void actionPerformed(ActionEvent ae) {
notifyDestroyed();
}
}
I would like to add another label under the "The Mairuwa Portal" and also place two buttons("Report A Problem","Request Information") beneath this as well. An illustration of what i am describing is
label: The Mairuwa Portal
then another label beneath it: I want to:
Then two buttons beneath this Button:Report Problem Button: Request Information
I have been able to add OK and EXIT button to the project,but this above buttons i talked about should as I described.
These buttons will carry functionality. I hope this can be done in LWUIT.

It just simple. Use the BoxLayout.Y_AXIS for Form and add the labels to the form. Create the Container with BoxLayout.Y_AXIS (or x_AXIS, Its your needs) and add the buttons to this Container and set the margin for the Container. See the sample code for how to do,
Form form = new Form("form");
form.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
Label label1 = new Label("Label 1");
Label label2 = new Label("Label 2");
form.addComponent(label1);
form.addComponent(label2);
Container c = new Container(new BoxLayout(BoxLayout.X_AXIS));
int center = Display.getInstance().getDisplayWidth()/2;
c.getStyle().setMargin(0, 0, center , 0);
Button b1 = new Button("button 1");
Button b2 = new Button("button 2");
c.addComponent(b1);
c.addComponent(b2);
form.addComponent(c);
form.show();

Related

Why does adding JavaFX TableViews to a VBox make other nodes disappear?

EDIT: Forgot the code...
I have an app that let's the user select CSV files for viewing. I'm using JavaFX TableViews to display the data.
For one page, the user can type into a special text box. It's a custom class I made called AutoCompleteTextArea, which extends RichTextFX's StyleClassedTextArea. On other pages, this text box should be hidden. When I have just one TableView, things work fine.
vbox.getChildren().addAll(menuBar, title, subtitle, reqBox, reqTable);
But I need other pages with different TableViews. If I add another TableView to the VBox, my AutoCompleteTextArea goes away!
vbox.getChildren().addAll(menuBar, title, subtitle, reqBox, reqTable, tempTable);
The TableViews do not appear to be overlapping... Any idea why the AutoCompleteTextArea is disappearing? The other weird thing is that if I substitute a regular TextField for the AutoCompleteTextArea, things work fine!
Here's my code. You will need RichTextFX on your build path in order to run it. Use the View Menu to see the problem. The first menu item shows the AutoCompleteTextArea (in the working case). The second menu item shows a different TableView, but this is the broken case - the AutoCompleteTextArea is gone from the first page.
Line 132 is the line in question.
I hope someone is up for the challenge!
More background:
I originally wanted to have just one TableView, and update it's contents based on the user's selection in the View Menu. But I couldn't find a good way to do that, and now here I am again... (see this post: How do I clone a JavaFX TableView?)
package FLOOR;
// --- Imports
import java.util.LinkedList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.fxmisc.richtext.StyleClassedTextArea;
import javafx.application.Application;
import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
// --- Main Class
public class Example extends Application {
// --- All Pages
final Page[] pages = new Page[] {
new Page("Welcome!",
"Welcome Page"),
new Page("Page 1", "Shows Table_1"),
new Page("Page 2", "Shows Table_2"),
};
// --- All Tables
TableView<ObservableList<StringProperty>> reqTable = new TableView<>();
TableView<ObservableList<StringProperty>> tempTable = new TableView<>();
//TextField reqBox = new TextField();
AutoCompleteTextArea reqBox = new AutoCompleteTextArea();
// --- Current Page
final Label title = new Label();
final Label subtitle = new Label();
// --- Main
public static void main(String[] args) { launch(args); }
// --- Start
#Override
public void start(Stage stage) {
// --- Menus
// --- File Menu
// --- Import Submenu
Menu menuFile = new Menu("File");
Menu importMenu = new Menu("Import");
MenuItem reqOption = new MenuItem("Requirements");
MenuItem tempOption = new MenuItem("Templates");
importMenu.getItems().addAll(reqOption, tempOption);
//Import Requirements
reqOption.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
//TODO
}
});
//Import Templates
tempOption.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
//TODO
}
});
//Export
MenuItem export = new MenuItem("Export");
export.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
//TODO
}
});
//Exit
MenuItem exit = new MenuItem("Exit");
exit.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
System.exit(0);
}
});
menuFile.getItems().addAll(importMenu, export, new SeparatorMenuItem(), exit);
// --- View Menu
Menu menuView = new Menu("View");
//Page1
MenuItem viewRequirements = new MenuItem("Requirements");
viewRequirements.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
getPage1();
}
});
//Page2
MenuItem viewTemplates = new MenuItem("Templates");
viewTemplates.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
getPage2();
}
});
menuView.getItems().addAll(viewRequirements, viewTemplates);
// --- Menu Bar
MenuBar menuBar = new MenuBar();
menuBar.getMenus().addAll(menuFile, menuView);
// --- VBox
final VBox vbox = new VBox();
vbox.setAlignment(Pos.TOP_CENTER);
vbox.setSpacing(10);
reqTable.setMinHeight(300);
tempTable.setMinHeight(300);
reqTable.translateYProperty().set(30);
tempTable.translateYProperty().set(-275);
reqTable.setVisible(false);
tempTable.setVisible(false);
reqBox.setVisible(false);
// --- Welcome Page
title.setFont(new Font("Arial", 24));
title.translateYProperty().set(10);
title.setText(pages[0].title);
subtitle.setText(pages[0].subtitle);
subtitle.setMinHeight(30);
subtitle.setTextAlignment(TextAlignment.CENTER);
// --- Show FLOOR
vbox.getChildren().addAll(menuBar, title, subtitle, reqBox, reqTable);
//vbox.getChildren().addAll(menuBar, title, subtitle, reqBox, reqTable, tempTable);
Scene scene = new Scene(vbox, 900, 500);
stage.setScene(scene);
stage.setTitle("FLOOR");
stage.show();
}
// --- Methods
// Page Getters
private void getPage1() {
title.setFont(new Font("Arial", 24));
title.translateYProperty().set(10);
title.setText(pages[1].title);
subtitle.setText(pages[1].subtitle);
subtitle.setMinHeight(20);
reqBox.setVisible(true);
reqTable.setVisible(true);
tempTable.setVisible(false);
}
private void getPage2() {
title.setFont(new Font("Arial", 24));
title.translateYProperty().set(10);
title.setText(pages[2].title);
subtitle.setText(pages[2].subtitle);
subtitle.setMinHeight(20);
reqBox.setVisible(false);
reqTable.setVisible(false);
tempTable.setVisible(true);
}
// --- Classes
// Page
private class Page {
public String title;
public String subtitle;
public Page(String title, String subtitle) {
this.title = title;
this.subtitle = subtitle;
}
}
// AutoCompleteTextArea
public class AutoCompleteTextArea extends StyleClassedTextArea {
public final SortedSet<String> entries;
public ContextMenu entriesPopup;
public AutoCompleteTextArea() {
super();
entries = new TreeSet<>();
entriesPopup = new ContextMenu();
}
public SortedSet<String> getEntries() { return entries; }
public void populatePopup(List<String> searchResult) {
List<CustomMenuItem> menuItems = new LinkedList<>();
int maxEntries = 20;
int count = Math.min(searchResult.size(), maxEntries);
for (int i = 0; i < count; i++) {
final String result = searchResult.get(i);
Label entryLabel = new Label(result);
CustomMenuItem item = new CustomMenuItem(entryLabel, true);
menuItems.add(item);
}
entriesPopup.getItems().clear();
entriesPopup.getItems().addAll(menuItems);
}
}
}

TextField type to Show Button in javafx

I am trying Show a Button on TextField look like Windows 8 Metro theme in javafx.
If TextField is empty button is invisible otherwise button show.
In this stage i'm little close to success. i use this code to make it.
#FXML
private TextField tfMyName;//fx:id="tfMyName"
#FXML
private Button btnClear;//fx:id="btnClear"
#Override
public void initialize(URL url, ResourceBundle rb) {
clearTextFieldByButton(tfMyName, btnClear);
}
public void clearTextFieldByButton(TextField value, Button btn){
btn.setVisible(false);
value.setOnKeyTyped(new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event) {
if ((value.textProperty().get().length() < 0) || (value.textProperty().get().equals(""))) {
btn.setVisible(false);
} else if (value.textProperty().get().length() > -1 || (!value.textProperty().get().equals(""))) {
btn.setVisible(true);
}
}
});
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
tfMyName.clear();
btn.setVisible(false);
tfMyName.requestFocus();
}
});
Using this code by default button is invisible but the button is only visible when i type more then one Characters.
But i need if anything input into the TextField to Button show.
But when i remove the condition under KeyEvent replace by
value.setOnKeyTyped(new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent event) {
btn.setVisible(true);
}
});
Then btn show if any character input into the TextField
You may also prefer to use JavaFX binding mechanism:
#Override
public void start( final Stage primaryStage )
{
TextField textfield = new TextField();
Button button = new Button( "my button" );
button.visibleProperty().bind( textfield.textProperty().isEmpty().not() );
final Scene scene = new Scene( new HBox( button, textfield ), 800, 600 );
primaryStage.setScene( scene );
primaryStage.show();
}
The actual problem in your code:
You have attached a listener to field when "OnKeyTyped", at this stage the newly typed text is not appended to the textfield's text value so your if-else condition will not see it. Instead, the correct way should be attaching the listener on "OnKeyReleased".
Add a listener to the textProperty() of the TextField. Check if the value is empty, hide the button else show it. It will be called whenever a character is added or removed from the textfield.
Here is a MCVE, you can just add the listener to the initialize method of the controller.
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class HideButtonOnTextEntered extends Application {
#Override
public void start(Stage stage) {
TextField textField = new TextField();
Button button = new Button("Button");
button.setVisible(false);
VBox root = new VBox(20, textField, button);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 200, 200);
stage.setScene(scene);
stage.show();
textField.textProperty().addListener((ov, oldValue, newValue) -> {
if (newValue.isEmpty()) {
button.setVisible(false);
} else {
button.setVisible(true);
}
});
}
public static void main(String[] args) {
launch(args);
}
}

Inner Classes variable Access

In this case I'm a little confused as to why I can't use myFrame as the first parameter in the showMessageDialog function. Why doesn't this work?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BabyCalculator extends JFrame{
public BabyCalculator(){
//You set this up so that you can refer to the frame using the inner class below.
setDefaultCloseOperation(EXIT_ON_CLOSE);
setName("Baby Calculator");
setLayout(new GridLayout(3,0));
//add
JLabel addLabel = new JLabel("Amount to add:");
JTextField addField = new JTextField(10);
JButton addButton = new JButton("add");
addButton.addActionListener(new AddListener());
//multiply
JLabel multiplyLabel = new JLabel("Amount to multiply:");
JTextField multiplyField = new JTextField(10);
JButton multiplyButton = new JButton("multiply");
//total
JLabel totalLabel = new JLabel("Total");
JTextField totalField = new JTextField(10);
totalField.setEditable(false);
JButton stopButton = new JButton("Stop");
stopButton.addActionListener(new StopListener());
//Create Panels
JPanel topRow = new JPanel(new BorderLayout());
JPanel middleRow = new JPanel (new BorderLayout());
JPanel bottomRow = new JPanel (new FlowLayout());
//Add the top Row
topRow.add(addLabel,BorderLayout.WEST);
topRow.add(addField, BorderLayout.CENTER);
topRow.add(addButton, BorderLayout.EAST);
add(topRow);
middleRow.add(multiplyLabel,BorderLayout.WEST);
middleRow.add(multiplyField, BorderLayout.CENTER);
middleRow.add(multiplyButton, BorderLayout.EAST);
add(middleRow);
bottomRow.add(totalLabel);
bottomRow.add(totalField);
bottomRow.add(stopButton);
add(bottomRow);
pack();
setVisible(true);
}
public static void main (String[] args){
JFrame myFrame = new BabyCalculator();
}
public class AddListener implements ActionListener{
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(myFrame, "You Clicked the add button");
}
}
//end class AddListener
public class StopListener implements ActionListener{//this is an inner class
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(myFrame, "You Clicked the stop button");
}//end class StopListener
}
}
I know that this is an inner class, and I'm not exactly sure about the access privileges, but it seems like there should be some way to access the "myFrame" variable in the main function.
Add a declaration statement at the top within the BabyCalculator class as:
JFrame myFrame;
Or you could make it a public variable with:
public JFrame myFrame = ...

JavaFX -- after modal dialog cursor left in incorrect state and cannot be corrected

I have a modal dialog that I pop up, which contains text boxes. If the user has the mouse over the text box (so the TEXT cursor shows) and then hits Enter to close the dialog, the cursor gets left in the TEXT state. So far I have found no way programmatically to change it back to the DEFAULT state. If I try some other cursor on the main scene (like HAND or MOVE) it works. But DEFAULT does not.
I'm using JavaFx / JDK 1.7 that was "fresh" when I downloaded within the last couple of months. I'm on Windows 8.1.
I've searched the web a fair bit and haven't found any mention of it. Is this a known bug? Can anybody suggest a workaround or explain what is going on?
Code sample follows. Simply click on the text edit in the dialog, keep the mouse over the textbox so the cursor is TEXT, and hit Enter.
package jfxtest;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class Jfxtest extends Application {
public static void main(String[] args) {
launch(args);
}
#Override public void start(final Stage primaryStage) {
Button btn = new Button();
btn.setText("Open Dialog");
btn.setOnAction(
new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
final Stage dialog = new Stage();
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(primaryStage);
final TextField txt = new TextField("Hit Enter while I have focus and the mouse is over me!");
txt.setMinWidth(280);
Button btnOk = new Button("OK");
btnOk.setDefaultButton(true);
btnOk.setOnAction(
new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
// these don't work
txt.setCursor(Cursor.DEFAULT);
dialog.getScene().setCursor(Cursor.DEFAULT);
primaryStage.getScene().setCursor(Cursor.DEFAULT);
dialog.close();
// and these don't work
txt.setCursor(Cursor.DEFAULT);
dialog.getScene().setCursor(Cursor.DEFAULT);
primaryStage.getScene().setCursor(Cursor.DEFAULT);
}
} );
VBox dialogVbox = new VBox(20);
dialogVbox.getChildren().add(txt);
dialogVbox.getChildren().add(btnOk);
Scene dialogScene = new Scene(dialogVbox, 300, 200);
dialog.setScene(dialogScene);
dialog.showAndWait();
// and these doesn't work
dialogScene.setCursor(Cursor.DEFAULT);
primaryStage.getScene().setCursor(Cursor.DEFAULT);
// but this works as expected (!), although it doesn't solve my problem
// primaryStage.getScene().setCursor(Cursor.HAND);
}
} );
VBox vbox = new VBox(20);
vbox.getChildren().add(btn);
Scene scene = new Scene (vbox, 400, 300);
primaryStage.setScene(scene);
primaryStage.show();
}
}

Internal Frames in JavaFX

I found this example of Internal Frames
http://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html
Is it possible to make the same internal Frames in JavaFX?
With JFXtras there is a Window control, where you can add content and handle the internal window behavior.
First you will need to put in your classpath the jfxtras library. They have some instructions where you can get the library. If you are using maven, just need to add:
<dependency>
<groupId>org.jfxtras</groupId>
<artifactId>jfxtras-labs</artifactId>
<version>2.2-r5</version>
</dependency>
Or download the library and put it into your project classpath, whatever.
Now I put a sample of the demo of the Window with a little difference, allowing generation of several windows.
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import jfxtras.labs.scene.control.window.CloseIcon;
import jfxtras.labs.scene.control.window.MinimizeIcon;
import jfxtras.labs.scene.control.window.Window;
public class WindowTests extends Application {
private static int counter = 1;
private void init(Stage primaryStage) {
final Group root = new Group();
Button button = new Button("Add more windows");
root.getChildren().addAll(button);
primaryStage.setResizable(false);
primaryStage.setScene(new Scene(root, 600, 500));
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
// create a window with title "My Window"
Window w = new Window("My Window#"+counter);
// set the window position to 10,10 (coordinates inside canvas)
w.setLayoutX(10);
w.setLayoutY(10);
// define the initial window size
w.setPrefSize(300, 200);
// either to the left
w.getLeftIcons().add(new CloseIcon(w));
// .. or to the right
w.getRightIcons().add(new MinimizeIcon(w));
// add some content
w.getContentPane().getChildren().add(new Label("Content... \nof the window#"+counter++));
// add the window to the canvas
root.getChildren().add(w);
}
});
}
public double getSampleWidth() {return 600;}
public double getSampleHeight() {return 500;}
#Override
public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {launch(args);}
}
In the original demo, the event code was in the init method, and no button was included. I add the button to create dynamically windows and adding them to the screen.
Here is a snapshot of the result of the application:
I totally recommend you try the demo of jfxtras. They have really great stuff. Hope it helps.
You can implement simple internal window themselves. Main idea, that InternalWindow class just skeleton, that has internal frame like functionality. You can apply any content to it.
1) Declare class
public class InternalWindow extends Region
2) You should be able to set content in window
public void setRoot(Node node) {
getChildren().add(node);
}
3) You should be able to bring window to front if many window exist
public void makeFocusable() {
this.setOnMouseClicked(mouseEvent -> {
toFront();
});
}
4) Now we need dragging functionality
//just for encapsulation
private static class Delta {
double x, y;
}
//we can select nodes that react drag event
public void makeDragable(Node what) {
final Delta dragDelta = new Delta();
what.setOnMousePressed(mouseEvent -> {
dragDelta.x = getLayoutX() - mouseEvent.getScreenX();
dragDelta.y = getLayoutY() - mouseEvent.getScreenY();
//also bring to front when moving
toFront();
});
what.setOnMouseDragged(mouseEvent -> {
setLayoutX(mouseEvent.getScreenX() + dragDelta.x);
setLayoutY(mouseEvent.getScreenY() + dragDelta.y);
});
}
5) Also we want able to resize window (I show only simple right-bottom resizing)
//current state
private boolean RESIZE_BOTTOM;
private boolean RESIZE_RIGHT;
public void makeResizable(double mouseBorderWidth) {
this.setOnMouseMoved(mouseEvent -> {
//local window's coordiantes
double mouseX = mouseEvent.getX();
double mouseY = mouseEvent.getY();
//window size
double width = this.boundsInLocalProperty().get().getWidth();
double height = this.boundsInLocalProperty().get().getHeight();
//if we on the edge, change state and cursor
if (Math.abs(mouseX - width) < mouseBorderWidth
&& Math.abs(mouseY - height) < mouseBorderWidth) {
RESIZE_RIGHT = true;
RESIZE_BOTTOM = true;
this.setCursor(Cursor.NW_RESIZE);
} else {
RESIZE_BOTTOM = false;
RESIZE_RIGHT = false;
this.setCursor(Cursor.DEFAULT);
}
});
this.setOnMouseDragged(mouseEvent -> {
//resize root
Region region = (Region) getChildren().get(0);
//resize logic depends on state
if (RESIZE_BOTTOM && RESIZE_RIGHT) {
region.setPrefSize(mouseEvent.getX(), mouseEvent.getY());
} else if (RESIZE_RIGHT) {
region.setPrefWidth(mouseEvent.getX());
} else if (RESIZE_BOTTOM) {
region.setPrefHeight(mouseEvent.getY());
}
});
}
6) Usage. First we construct all layout. Then apply it to InternalWindow.
private InternalWindow constructWindow() {
// content
ImageView imageView = new ImageView("https://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Cheetah4.jpg/250px-Cheetah4.jpg");
// title bar
BorderPane titleBar = new BorderPane();
titleBar.setStyle("-fx-background-color: green; -fx-padding: 3");
Label label = new Label("header");
titleBar.setLeft(label);
Button closeButton = new Button("x");
titleBar.setRight(closeButton);
// title bat + content
BorderPane windowPane = new BorderPane();
windowPane.setStyle("-fx-border-width: 1; -fx-border-color: black");
windowPane.setTop(titleBar);
windowPane.setCenter(imageView);
//apply layout to InternalWindow
InternalWindow interalWindow = new InternalWindow();
interalWindow.setRoot(windowPane);
//drag only by title
interalWindow.makeDragable(titleBar);
interalWindow.makeDragable(label);
interalWindow.makeResizable(20);
interalWindow.makeFocusable();
return interalWindow;
}
7) And how add window to layout
#Override
public void start(Stage primaryStage) throws Exception {
Pane root = new Pane();
root.getChildren().add(constructWindow());
root.getChildren().add(constructWindow());
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
Result
Full code: gist
Upd about close button:
You can add method to InternalWindow
public void setCloseButton(Button btn) {
btn.setOnAction(event -> ((Pane) getParent()).getChildren().remove(this));
}
And when construct:
interalWindow.setCloseButton(closeButton);

Resources