Javafx8 align controls in internal frame - alignment

I have recently shifted from c# to try Javafx2. I am also new to this forum.
I have been stuck trying to implement internal frames in Javafx.
I stumbled upon this link:
Internal Frames in JavaFX
I have managed to add jfxtras 8 jar file to my project as well as in scene builder 2.
However, am stuck in aligning the controls on the window.
This is the fxml file code:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import jfxtras.labs.scene.control.window.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="500.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="trials.MamaCont">
<children><Window fx:id="wini" layoutX="122.0" layoutY="105.0" prefHeight="190.0" prefWidth="313.0" title="Window" />
</children></AnchorPane>
and this is the controller class code:
package trials;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import jfxtras.labs.scene.control.window.CloseIcon;
import jfxtras.labs.scene.control.window.MinimizeIcon;
import jfxtras.labs.scene.control.window.Window;
/**
* FXML Controller class
*
* #author smoothie
*/
public class MamaCont implements Initializable {
/**
* Initializes the controller class.
*/
/*#FXML
private Button pb;
#FXML
private Label lb;*/
#FXML
private Window wini;
/*#FXML
void pressed(ActionEvent event) {
lb.setText("Gotcha!!!....");
}*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
wini.getLeftIcons().add(new CloseIcon(wini));
wini.getRightIcons().add(new MinimizeIcon(wini));
//wini.setVisible(false);
Button butt = new Button("Enter");
/*butt.setLayoutX(100);
butt.setLayoutY(100);*/
Label lab = new Label();
/*lab.setLayoutX(261);
lab.setLayoutY(192);*/
butt.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
lab.setText("I've been pressed!!!");
}
});
wini.getContentPane().getChildren().add(butt);
wini.getContentPane().getChildren().add(lab);
}
}
Now, does anyone know how I can be able to align the label so that its text appears below the button? When one clicks on the button the text from the label appears over the button instead of below it.
Has anyone been able to implement internal frames with javafx2 and could you please share how you have managed to put well arranged controls within the internal frames?
Lastly, does anyone know how to make a scene builder control a child of a custom control in scene builder?
I managed to add jfxtras controls to scene builder but unfortunately am not able to add javafx controls to the jfxtras window. In this case, I tried to add a javafx button to the jfxtras window via scene builder but it never worked because it was added to the anchor pane instead of the window resulting to the both the jfxtras window and javafx button being children of the anchor pane.

I managed to solve the issue after toying with the code for some time. What I did was to create the GUI using Scene Builder and linking it with the Java code using a controller.
Below are the fxml files:
tingiGUI.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="202.0" prefWidth="325.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ting.TingiCont">
<children><Button fx:id="si" layoutX="137.0" layoutY="112.0" mnemonicParsing="false" onAction="#Onyesha" text="Show" /><Label fx:id="lbi" layoutX="100.0" layoutY="70.0" prefHeight="17.0" prefWidth="124.0" />
</children></Pane>
tinGUI.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="325.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ting.TinCont">
<children><Button fx:id="bb" layoutX="137.0" layoutY="88.0" mnemonicParsing="false" onAction="#Boom" text="BOOM" /><Label fx:id="lbx" layoutX="84.0" layoutY="147.0" prefHeight="17.0" prefWidth="157.0" />
</children></Pane>
tingGUI.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="219.0" prefWidth="323.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ting.TingCont">
<children><Button fx:id="cmb" layoutX="127.0" layoutY="126.0" mnemonicParsing="false" onAction="#clicked" text="Click me..." /><Label fx:id="lb" layoutX="93.0" layoutY="80.0" prefHeight="17.0" prefWidth="121.0" />
</children></AnchorPane>
Below are the controllers. They extend the Main java class.
TinCont.java
package ting;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import jfxtras.labs.scene.control.window.CloseIcon;
import jfxtras.labs.scene.control.window.Window;
public class TinCont extends Main implements Initializable{
#FXML
private Button bb;
#FXML
private Label lbx;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
#FXML
void Boom(ActionEvent event) throws IOException {
lbx.setText("KAMIKAZE!!!!!!");
Pane coco = FXMLLoader.load(getClass().getResource("tingiGUI.fxml"));
Window x = new Window("TINGI WINDOW");
// set the window position to 10,10 (coordinates inside canvas)
x.setLayoutX(10);
x.setLayoutY(10);
// define the initial window size
x.setPrefSize(330, 210);
x.setResizableWindow(false);
// either to the left
x.getRightIcons().add(new CloseIcon(x));
// add some content
x.getContentPane().getChildren().add(coco);
anchor.getChildren().add(x);
}
}
TingiCont.java
package ting;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.event.ActionEvent;
/**
* Created by Udeman on 2/1/14.
*/
public class TingiCont {
#FXML
private Label lbi;
#FXML
private Button si;
#FXML
void Onyesha(ActionEvent event) {
lbi.setText("You made it...");
}
}
TingCont.java
package ting;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import jfxtras.labs.scene.control.window.CloseIcon;
import jfxtras.labs.scene.control.window.Window;
public class TingCont extends Main implements Initializable{
#FXML
private Label lb;
#FXML
private Button cmb;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
}
#FXML
void clicked(ActionEvent event) throws IOException {
lb.setText("I've been clicked...");
Pane balou = FXMLLoader.load(getClass().getResource("tinGUI.fxml"));
Window w = new Window("TIN WINDOW");
// set the window position to 10,10 (coordinates inside canvas)
w.setLayoutX(10);
w.setLayoutY(10);
// define the initial window size
w.setPrefSize(330, 210);
//w.setResizableWindow(false);
// either to the left
w.getRightIcons().add(new CloseIcon(w));
// add some content
w.getContentPane().getChildren().add(balou);
anchor.getChildren().add(w);
//((Node)(event.getSource())).getScene().getWindow().hide();
}
}
And this is the Main Class.
Main.java
package ting;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import jfxtras.labs.scene.control.window.CloseIcon;
import jfxtras.labs.scene.control.window.Window;
public class Main extends Application {
public static AnchorPane anchor = new AnchorPane();
#Override
public void start(Stage primaryStage) throws Exception{
Pane sunda = FXMLLoader.load(getClass().getResource("tingGUI.fxml"));
sunda.setLayoutX(130);
sunda.setLayoutY(60);
anchor.getChildren().add(sunda);
primaryStage.setTitle("TING");
primaryStage.setScene(new Scene(anchor, 600, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
To be able to properly align elements it is best to use the Scene builder. Since I was planning on using internal frames I downloaded JFXtras 8 labs jar file from the JFxtras team. JavaFx8 does not currently support internal frames.
In the Main java class, I created a static anchorpane which the other controllers could inherit because they extend the Main class.
From there, I created a JFXtras window and loaded the contents of my fxml file using an fxml loader on a pane. I added the pane to the Jfxtras window and lastly added the window to the anchorpane which was created from the Main class.
In summary, to properly align GUI elements one is best of using scene builder. In order to share the same anchorpane its best to create a static anchorpane in one class and the rest of the controllers to inherit from that class.
It is now possible to add custom UI elements to the current Scene Builder but one is limited on how to use them from the scene builder. You cannot only drag and drop the custom controls but not modify them from Scene Builder
A quick remark, jfxtras window is currently the closest way to have internal frames in JavaFx8. Oracle have not implemented internal frames in Javafx8. However, jfxtras windows for one reason or the other blow out of proportion GUI elements from the fxml file.
Well, am going to take a break from coding with Javafx8 until internal frames are introduced. I heavily rely on them. Am returning to c# for now....

Related

Vaadin Designer Tabs not correctly adding children "tab" to tabs object

I'm using Vaadin Deisgner 14.6.1 to create some super simple tabs. However, when I try to do some simple operations in the java class (eg selecting a tab), it throws an error which indicates that the "Tabs" object does not have the proper children "tab" components. Here's a simple test case below. (I discovered the issue when I was trying to add a addSelectedChangeListener() to the tabs class and discovered that it would never fire, presumably since the "tabs" class never properly had any children.) I tried a bunch of hacks, but nothing worked. (I have in the past gotten tabs to work if I stuck purely to a programmatic approach, but I really really really like using Designer, since it saves me tonnes of times and keeps the code quite modular and clean....when it works....)
import {html, PolymerElement} from '#polymer/polymer/polymer-element.js';
import '#vaadin/vaadin-ordered-layout/src/vaadin-vertical-layout.js';
import '#vaadin/vaadin-tabs/src/vaadin-tabs.js';
import '#vaadin/vaadin-tabs/src/vaadin-tab.js';
class MyTabtest extends PolymerElement {
static get template() {
return html`
<style include="shared-styles">
:host {
display: block;
height: 100%;
}
</style>
<vaadin-vertical-layout theme="spacing" style="width: 100%; height: 100%;">
<vaadin-tabs theme="equal-width-tabs" id="tabs" orientation="horizontal" selected="0">
<vaadin-tab id="tab1" selected>
Tab one
</vaadin-tab>
<vaadin-tab id="tab2">
Tab two with a longer title
</vaadin-tab>
<vaadin-tab id="tab3">
Tab three
</vaadin-tab>
</vaadin-tabs>
<label id="lbl1">page1</label>
<label id="lbl2">page2</label>
<label id="lbl3">page3</label>
</vaadin-vertical-layout>
`;
}
static get is() {
return 'my-tabtest';
}
static get properties() {
return {
// Declare your properties here.
};
}
}
customElements.define(MyTabtest.is, MyTabtest);
and
package com.deepsearch.fe.tab2vizdb.fpsgraphicaldetails.spectratab.hslspectrachartandalts;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.polymertemplate.Id;
import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.component.tabs.Tabs;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.templatemodel.TemplateModel;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
/**
* A Designer generated component for the my-tabtest template.
*
* Designer will add and remove fields with #Id mappings but
* does not overwrite or otherwise change this file.
*/
#Route("tabtest")
#Tag("my-tabtest")
#JsModule("./src/my-tabtest.js")
public class MyTabtest extends PolymerTemplate<MyTabtest.MyTabtestModel> {
#Id("tabs")
private Tabs tabs;
#Id("tab1")
private Tab tab1;
#Id("tab2")
private Tab tab2;
#Id("tab3")
private Tab tab3;
#Id("lbl1")
private Label lbl1;
#Id("lbl2")
private Label lbl2;
#Id("lbl3")
private Label lbl3;
/**
* Creates a new MyTabtest.
*/
public MyTabtest() {
// tabs.setSelectedTab(tab2); //throws error!
tabs.addSelectedChangeListener(e -> {
System.out.println("A tab got selected!"); //this never fires!!!!
});
}
/**
* This model binds properties between MyTabtest and my-tabtest
*/
public interface MyTabtestModel extends TemplateModel {
// Add setters and getters for template properties here.
}
}
Ultimately, I'm trying to capture a tab select event -- but it doens't seem to work when the tabs are created in Designer....is this true on Vaadin's side too? (ie is this reproducible?)
This is an unfortunate limitation of the component mapping to elements defined in a template. When mapping to Java, the parent-child relationships are not preserved and thus the tabs component does not realize that the tab is one of its child components.
See https://github.com/vaadin/flow/issues/7622
The way to make it work would be to create the Tabs and Tab instances in Java and the rest in Designer.

Vaadin Tabs based component created using Designer doesn't show data when bound using its Java companion file

Below is the Vaadin Designer code for simple tab functionality
import {html, PolymerElement} from '#polymer/polymer/polymer-element.js';
import '#vaadin/vaadin-tabs/src/vaadin-tabs.js';
import '#vaadin/vaadin-tabs/src/vaadin-tab.js';
class TestUi extends PolymerElement {
static get template() {
return html`
<style include="shared-styles">
:host {
display: block;
height: 100%;
}
</style>
<vaadin-tabs theme="equal-width-tabs" id="vaadinTabs">
<vaadin-tab id="vaadinTab">
Product Overview
</vaadin-tab>
<vaadin-tab id="vaadinTab1">
Product DetailView
</vaadin-tab>
<vaadin-tab id="vaadinTab2">
Reports
</vaadin-tab>
</vaadin-tabs>
`;
}
static get is() {
return 'test-ui';
}
static get properties() {
return {
// Declare your properties here.
};
}
}
customElements.define(TestUi.is, TestUi);
It's corresponding Java companion file looks as below
import com.vaadin.flow.component.polymertemplate.Id;
import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.component.tabs.Tabs;
import com.vaadin.flow.templatemodel.TemplateModel;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.polymertemplate.PolymerTemplate;
/**
* A Designer generated component for the test-ui template.
*
* Designer will add and remove fields with #Id mappings but
* does not overwrite or otherwise change this file.
*/
#Tag("test-ui")
#JsModule("./src/productdetailview/test-ui.js")
public class TestUi extends PolymerTemplate<TestUi.TestUiModel> {
#Id("vaadinTabs")
private Tabs vaadinTabs;
#Id("vaadinTab")
private Tab vaadinTab;
#Id("vaadinTab1")
private Tab vaadinTab1;
#Id("vaadinTab2")
private Tab vaadinTab2;
/**
* Creates a new TestUi.
*/
public TestUi() {
// You can initialise any data required for the connected UI components here.
vaadinTabs.addSelectedChangeListener(selectedChangeEvent -> {
selectedChangeEvent.getSelectedTab().getElement().getStyle().set("background-color":"blue");
});
}
/**
* This model binds properties between TestUi and test-ui
*/
public interface TestUiModel extends TemplateModel {
// Add setters and getters for template properties here.
}
}
In the above code, My thinking was to start writing the selectedChangeListener Handler directly without doing much but instead this doesn't work and below initialization code needs to be added.
//I have added for one tab but it requires all the tabs to be added
vaadinTabs = new Tabs();
vaadinTab = new Tab();
vaadinTabs.add(vaadinTab);
My question here is why would I need to initialize when the Polymer js code generated using Vaadin Designer clearly defines the tab and it's group?
This is the same issue with Vaadin Grid. Even after defining the columns in the Polymer js, I have to redefine it from the Java component end instead of directly start providing the data via data provider
TLDR; Unfortunately, you have encountered this issue IllegalArgumentException when switching tabs
which is closed as won't fix.
My question here is why would I need to initialize when the Polymer js code generated using Vaadin Designer clearly defines the tab and it's group?
Generally, you don't need to. But Tabs doesn't work as intended in this case. Thus, for this particular component, it's suggested to not mix template/Java logic.
For example, you can verify it with a <vaadin-text-field>, where event is fired correctly.
Java counterpart
#Id("vaadinTextField")
private TextField vaadinTextField;
/**
* Creates a new TestUi.
*/
public TestUi() {
// You can initialise any data required for the connected UI components here.
vaadinTextField.addValueChangeListener(event->{
System.out.println("Event has happened");
});
vaadinTextField.setValueChangeMode(ValueChangeMode.EAGER);
and snippet for the template right after the tabs:
<vaadin-vertical-layout id="vaadinVerticalLayout" style="width: 100%; height: 100%;">
<vaadin-text-field id="vaadinTextField"></vaadin-text-field>
</vaadin-vertical-layout>
Taken from the issue:
So all Tab related API methods in Tabs are completely broken in regard to injected Tabs.
and
Unfortunately we've concluded that there is no sensible way we can support this for now, thus this issue will be a known limitation with Tabs. It will not work as #Id mapped component when the child vaadin-tabs are created in the template file, so you should not try to mix client & server logic and content for the Tabs component.
As a workaround, you could try to use your own component for #Id mapping tabs like:
#Tag("vaadin-tabs")
public IdMappedTabs extends Component {
public IdMappedTabs() {
}
public Registration addSelectionListener(PropertyChangeListener listener) {
return getElement().addPropertyChangeListener("selected", listener);
}
public void setSelectedTabIndex(int index) {
getElement().setProperty("selected", index);
}
}
Edit:
What is the issue with Grid you are having? (There is a good tutorial about Designer, where Grid is used. It might be useful : Vaadin Designer tutorial)

React Native - Router Flux - Empty Scene For Key Error

I am getting an error when using the following code in my index.ios.js file:
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';
import { Actions, Router, Route, Scene } from 'react-native-router-flux';
import {Categories} from './Components/Categories';
import {CarRacing} from './Components/CarRacing';
const scenes = Actions.create(
<Scene key="root">
<Scene key="Categories" name="Categories" component={Categories} title="Categories" initial={true}/>
<Scene key="CarRacing" name="CarRacing" component={CarRacing} title="CarRacing"/>
</Scene>
);
export default class Motorsport extends Component {
render() {
return (
<Router scenes={scenes}/>
);
}
}
AppRegistry.registerComponent('Motorsport', () => Motorsport);
Categories are a list of categories in a tableview done by 'react-native-tableview'. When clicking on the the CarRacing TableView row, I get the following error:
route.children.forEach is not a function. (In 'route.children.forEach(function(r,i) {(0,_Util.assert)(scenes[r],'Empty scene for key='+route.key);if*scenes[r].inital) {index=i;}})','route.children.forEach' is undefined)
I am not sure what I have done wrong here. I understand the error, but I don't quite get what I did in my code to mess this up.
Any ideas? Thanks!

How to know which text string is selected by user in JavaFX TextArea

I need to allow the user to highlight text (select a range with the mouse), then I want to give them the ability to apply some setting to that text form a drop down right click menu.
I know the latter part. But how do I get which text string is selected from a Text Area in JavafX?
Also, would I be able to apply different styles to different strings?
Use getSelectedText() to get the selected text.
The answer to your second question is yes.
The getSelectedText() method can be used like I have done here:
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TextAreaDemo extends Application
{
#Override
public void start(Stage stage)
{
final TextArea textArea = new TextArea("Text Sample");
textArea.setPrefSize(200, 40);
textArea.setOnContextMenuRequested(new EventHandler<Event>()
{
#Override
public void handle(Event arg0)
{
System.out.println("selected text:"
+ textArea.getSelectedText());
}
});
VBox vBox = new VBox();
vBox.getChildren().addAll(textArea);
stage.setScene(new Scene(vBox, 300, 250));
stage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
Once you launch this application, it shows a TextArea with some text (Text Sample). I selected some part of the text and did a right click. It printed the selected text. Does this fit your requirement?

JavaFX: Tooltip - Can't get tooltip's to show at all

I'm in the middle of a project where i'm supposed to write a login system using JavaFX 2.0.
And right now i'm trying to write a tooltip with a connection to the password field, but the tooltip NEVER shows at all.. I'm using the FXML-LoginDemo project from the 'javafx-samples-2.0.3'. And then I tried to use: http://docs.oracle.com/javafx/2.0/ui_controls/tooltip.htm#BABHCHGG example 19.1.
If you need more code to see this problem please say so.. because I don't really know where the problem is..
Here's my code so far:
package demo;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
/**
* Login Controller.
*/
public class LoginController {
#FXML private TextField userId;
#FXML private PasswordField password;
#FXML private Label errorMessage;
#FXML final Tooltip tooltip = new Tooltip();
#FXML protected void processLogin(ActionEvent event) {
tooltip.setText("\nYour password must be\n at least 8 characters in length\n");
password.setTooltip(tooltip);
if(!App.getInstance().userLogging(userId.getText(), password.getText())){
errorMessage.setText("Invalid username or password: " + userId.getText());
}
//Replaces inputed password with an empty String.
password.setText("");
}
}
Define an initialize method on the controller and, in that method, set the tooltip text and associate the tooltip with the password field. If you wait until the processLogin action is called to set the Tooltip, the scene has already been displayed and the user has already tried to login.
Also, you don't need to place the #FXML annotation in front of the Tooltip unless you are defining Tooltip properties in FXML, which is probably not necessary in this case.

Resources