Flex 4. Output my component repeatedly - flex4

I create a Skin:
<s:Group id="brick">
<s:Rect width="40" height="20">
<s:fill>
<s:SolidColor color="{hostComponent.colorBrick}" />
</s:fill>
</s:Rect>
<s:Rect width="40" height="20">
<s:stroke>
<s:SolidColorStroke color="#000000" />
</s:stroke>
</s:Rect>
</s:Group>
How do I bring this component more than once?
It is a brick. I want create wall.

You can use a loop to create the same component more than once.
Here is your skin BrickSkin.mxml:
<?xml version="1.0"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Metadata>
<![CDATA[
[HostComponent("Brick")]
]]>
</fx:Metadata>
<fx:Script>
<![CDATA[
]]>
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="disabled"/>
</s:states>
<s:Group id="brick">
<s:Rect width="40" height="20">
<s:fill>
<s:SolidColor id="solidColor" />
</s:fill>
</s:Rect>
<s:Rect width="40" height="20">
<s:stroke>
<s:SolidColorStroke color="#000000" />
</s:stroke>
</s:Rect>
</s:Group>
</s:Skin>
Here is your Brick component Brick.as:
package {
import flash.events.Event;
import mx.graphics.SolidColor;
import spark.components.SkinnableContainer;
public class Brick extends SkinnableContainer{
public function Brick() {
super();
}
[SkinPart(required="true")]
public var solidColor:SolidColor;
override protected function partAdded(partName:String, instance:Object):void {
super.partAdded(partName, instance);
if(instance == solidColor)
{
solidColor.color = colorBrick;
}
}
[Bindable]
private var _colorBrick:uint;
[Bindable(event="colorBrickChanged")]
public function get colorBrick():uint {
return _colorBrick;
}
public function set colorBrick(value:uint):void {
if (_colorBrick == value) return;
_colorBrick = value;
dispatchEvent(new Event("colorBrickChanged"));
invalidateProperties();
}
override protected function commitProperties():void {
super.commitProperties();
if(solidColor)
solidColor.color = colorBrick;
}
}
}
You can create BrickCSS.css as below:
#namespace local "*";
local|Brick {
skinClass: ClassReference("BrickSkin");
}
Here is your Main.mxml:
<?xml version="1.0"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="100%"
height="100%"
creationComplete="{buildWall()}">
<fx:Style source="BrickCSS.css"/>
<fx:Script><![CDATA[
private function buildWall():void
{
for(var i = 0; i < 200; i++)
{
var brick:Brick = new Brick();
brick.colorBrick = 0xFF0000;
tileGroup.addElement(brick);
}
}
]]></fx:Script>
<s:TileGroup id="tileGroup" width="20%" height="90%" verticalCenter="0" horizontalCenter="0" horizontalGap="0" verticalGap="0" />
</s:Application>
Here is the output snap shot.

Related

When I want to insert data without image this error occurred java.lang.NullPointerException

I am working on a library Management System (LMS) project. I am using Apache NetBeans 11.3 and JDK 8 and I have a problem in inserting data into MySQL, when I want to insert students table data into MySQL without image this NullPointerException error occurred. I know this errors says me to insert image with my data too, but sometimes I want to insert students table data into database without any images, what can I do for it to work well.
This error occurred:
java.lang.NullPointerException
at ulms.ui.addStudents.AddStudentsController.addStudents(AddStudentsController.java:226)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:410)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$4(WinApplication.java:186)
at java.lang.Thread.run(Thread.java:748)
AddStudentsController.java
package ulms.ui.addStudents;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXComboBox;
import com.jfoenix.controls.JFXTextField;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.Random;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;
import java.sql.*;
import javafx.scene.control.Alert;
import javafx.stage.Stage;
import java.io.*;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.FileChooser;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
public class AddStudentsController implements Initializable {
Connection con;
PreparedStatement pst;
ResultSet rs;
#FXML
private AnchorPane rootAnchorS;
#FXML
private JFXTextField txtSID;
#FXML
private JFXTextField txtSName;
#FXML
private JFXTextField txtSFName;
#FXML
private JFXComboBox<String> cbxSFaculty;
#FXML
private JFXComboBox<String> cbxSDep;
#FXML
private JFXComboBox<String> cbxSYear;
#FXML
private JFXComboBox<String> cbxSSemister;
#FXML
private JFXButton btnCancelS;
#FXML
private JFXButton btnSaveS;
#FXML
private ImageView viewSImage;
#FXML
private JFXButton btnSImage;
private FileChooser fileChooser;
private File file;
private Stage stage;
private Image image;
private FileInputStream fis;
private BufferedImage bimg;
#Override
public void initialize(URL url, ResourceBundle rb) {
Random();
SFaculty();
SDep();
SYear();
SSemister();
}
public void Random(){
Random rand = new Random();
txtSID.setText("" + rand.nextInt(1000000 + 1));
}
public void SFaculty(){
cbxSFaculty.getItems().add(("کمپیوترساینس"));
cbxSFaculty.getItems().add(("علوم اجتماعی"));
cbxSFaculty.getItems().add(("اقتصاد"));
cbxSFaculty.getItems().add(("زراعت"));
cbxSFaculty.getItems().add(("حقوق و علوم سیاسی"));
cbxSFaculty.getItems().add(("انجنیری"));
cbxSFaculty.getItems().add(("تعلیم و تربیه"));
cbxSFaculty.getItems().add(("ادبیات"));
cbxSFaculty.getItems().add(("شرعیات"));
cbxSFaculty.getItems().add(("طب"));
}
public void SDep(){
cbxSDep.getItems().add(("مهندسی نرم افزار"));
cbxSDep.getItems().add(("فناوری اطلاعات"));
cbxSDep.getItems().add(("فناوری اطلاعات و ارتباطات"));
cbxSDep.getItems().add(("دیتابیس"));
cbxSDep.getItems().add(("مهندسی شبکه"));
cbxSDep.getItems().add(("----------"));
cbxSDep.getItems().add(("تاریخ"));
cbxSDep.getItems().add(("جفرافیه"));
cbxSDep.getItems().add(("جامعه شناسی"));
cbxSDep.getItems().add(("----------"));
cbxSDep.getItems().add(("منجمنت و اداره تشبثات"));
cbxSDep.getItems().add(("امور مالی و بانکی"));
cbxSDep.getItems().add(("----------"));
cbxSDep.getItems().add(("جنگلات و منابع طبیعی"));
cbxSDep.getItems().add(("علوم حیوانی"));
cbxSDep.getItems().add(("هارتیکلچر یا باغداری"));
cbxSDep.getItems().add(("----------"));
cbxSDep.getItems().add(("قضا و ثارنوالی"));
cbxSDep.getItems().add(("اداره و دیپلوماسی"));
cbxSDep.getItems().add(("----------"));
cbxSDep.getItems().add(("سیول"));
cbxSDep.getItems().add(("میخانیک"));
cbxSDep.getItems().add(("مهندسی"));
cbxSDep.getItems().add(("طراحی شهری"));
cbxSDep.getItems().add(("برق و الکترونیک"));
cbxSDep.getItems().add(("انرژی"));
cbxSDep.getItems().add(("----------"));
cbxSDep.getItems().add(("ریاضی"));
cbxSDep.getItems().add(("فیزیک"));
cbxSDep.getItems().add(("کیمیا"));
cbxSDep.getItems().add(("بیولوژی"));
cbxSDep.getItems().add(("----------"));
cbxSDep.getItems().add(("زبان و ادبیات فارسی دری"));
cbxSDep.getItems().add(("زبان و ادبیات پشتو"));
cbxSDep.getItems().add(("زبان و ادبیات انگلیسی"));
cbxSDep.getItems().add(("زبان و ادبیات عربی"));
cbxSDep.getItems().add(("ژورنالیزم"));
cbxSDep.getItems().add(("----------"));
cbxSDep.getItems().add(("تعلیمات اسلامی"));
cbxSDep.getItems().add(("----------"));
cbxSDep.getItems().add(("طب عمومی"));
}
public void SYear(){
cbxSYear.getItems().add("1");
cbxSYear.getItems().add("2");
cbxSYear.getItems().add("3");
cbxSYear.getItems().add("4");
cbxSYear.getItems().add("5");
cbxSYear.getItems().add("6");
cbxSYear.getItems().add("7");
}
public void SSemister(){
cbxSSemister.getItems().add("1");
cbxSSemister.getItems().add("2");
cbxSSemister.getItems().add("3");
cbxSSemister.getItems().add("4");
cbxSSemister.getItems().add("5");
cbxSSemister.getItems().add("6");
cbxSSemister.getItems().add("7");
cbxSSemister.getItems().add("8");
cbxSSemister.getItems().add("9");
cbxSSemister.getItems().add("10");
cbxSSemister.getItems().add("11");
cbxSSemister.getItems().add("12");
cbxSSemister.getItems().add("13");
cbxSSemister.getItems().add("14");
}
#FXML
private void cancelStudents(ActionEvent event) {
stage = (Stage) rootAnchorS.getScene().getWindow();
stage.close();
}
#FXML
private void addStudents(ActionEvent event) {
String SID = txtSID.getText();
String SName = txtSName.getText();
String SFName = txtSFName.getText();
String SFaculty = cbxSFaculty.getItems().toString();
String SDep = cbxSDep.getItems().toString();
String SYear = cbxSYear.getItems().toString();
String SSemister = cbxSSemister.getItems().toString();
if(SID.isEmpty() || SName.isEmpty() || SFName.isEmpty() || SFaculty.isEmpty() || SDep.isEmpty() ||
SYear.isEmpty() || SSemister.isEmpty()){
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText(null);
alert.setTitle("خطا");
alert.setContentText("لطفا تمام فیلد ها را پر کنید");
alert.showAndWait();
}
else{
String addStudent = "insert into students (SID, SName, SFName, Faculty, Department, Year, Semister, SImage) values (?,?,?,?,?,?,?,?)";
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = ("jdbc:mysql://localhost:3306/ulms");
String user = "root";
String pass = "Mysql786";
con = DriverManager.getConnection(url, user, pass);
pst = con.prepareStatement(addStudent);
pst.setString(1, txtSID.getText());
pst.setString(2, txtSName.getText());
pst.setString(3, txtSFName.getText());
pst.setString(4, (String)cbxSFaculty.getSelectionModel().getSelectedItem());
pst.setString(5, (String)cbxSDep.getSelectionModel().getSelectedItem());
pst.setString(6, (String)cbxSYear.getSelectionModel().getSelectedItem());
pst.setString(7, (String)cbxSSemister.getSelectionModel().getSelectedItem());
pst.setBinaryStream(8, (InputStream)fis, (int)file.length());
pst.executeUpdate();
pst.close();
con.close();
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText(null);
alert.setTitle("اطلاعات");
alert.setContentText("دانشجو جدید موفقانه ایجاد شد");
alert.showAndWait();
txtSID.setText("");
txtSName.setText("");
txtSFName.setText("");
SFaculty();
SDep();
SYear();
SSemister();
viewSImage.setImage(null);
Random();
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException | SQLException e) {
e.printStackTrace();
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText(null);
alert.setTitle("خطا");
alert.setContentText("دانشجو جدید ایجاد نشد");
alert.showAndWait();
} catch(NullPointerException e){
e.printStackTrace();
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText(null);
alert.setTitle("خطا");
alert.setContentText("لطفا تصویر را انتخاب کنید");
alert.showAndWait();
}
}
}
#FXML
private void openImageS(ActionEvent event) {
fileChooser = new FileChooser();
FileChooser.ExtensionFilter ext1 = new FileChooser.ExtensionFilter("JPG files(*.jpg)", "*.JPG");
FileChooser.ExtensionFilter ext2 = new FileChooser.ExtensionFilter("PNG files(*.png)", "*.PNG");
FileChooser.ExtensionFilter ext3 = new FileChooser.ExtensionFilter("ICON files(*.ico)", "*.ICO");
fileChooser.getExtensionFilters().addAll(ext1, ext2, ext3);
stage = (Stage) rootAnchorS.getScene().getWindow();
file = fileChooser.showOpenDialog(stage);
if(file != null){
String p = file.getAbsolutePath();
try {
fis = new FileInputStream(file);
bimg = ImageIO.read(file);
image = SwingFXUtils.toFXImage(bimg, null);
image = new Image(file.getAbsoluteFile().toURI().toString(), viewSImage.getFitWidth(), viewSImage.getFitHeight(), true, true);
viewSImage.setImage(image);
viewSImage.setPreserveRatio(true);
} catch (IOException e) {
e.printStackTrace();
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText(null);
alert.setTitle("خطا");
alert.setContentText("تصویر وارد نشد");
alert.showAndWait();
}
}
}
}
addStudents.java
package ulms.ui.addStudents;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class addStudents extends Application {
#Override
public void start(Stage stage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("addStudents.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
stage.setTitle("ایجاد دانشجو جدید");
}
public static void main(String[] args) {
launch(args);
}
}
addStudents.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXComboBox?>
<?import com.jfoenix.controls.JFXTextField?>
<?import java.net.URL?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<AnchorPane id="AnchorPane" fx:id="rootAnchorS" prefHeight="393.0" prefWidth="600.0" styleClass="mainFxmlClass" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ulms.ui.addStudents.AddStudentsController">
<stylesheets>
<URL value="#addstudents.css" />
</stylesheets>
<children>
<VBox layoutX="255.0" prefHeight="399.0" prefWidth="345.0">
<children>
<JFXTextField fx:id="txtSID" alignment="CENTER_RIGHT" disable="true" editable="false" labelFloat="true" promptText="آی دی">
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="20.0" />
</VBox.margin>
<font>
<Font size="13.0" />
</font>
</JFXTextField>
<JFXTextField fx:id="txtSName" alignment="CENTER_RIGHT" labelFloat="true" layoutX="10.0" layoutY="10.0" promptText="نام">
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</VBox.margin>
<font>
<Font size="13.0" />
</font>
</JFXTextField>
<JFXTextField fx:id="txtSFName" alignment="CENTER_RIGHT" labelFloat="true" layoutX="10.0" layoutY="35.0" promptText="نام پدر">
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</VBox.margin>
<font>
<Font size="13.0" />
</font>
</JFXTextField>
<JFXComboBox fx:id="cbxSFaculty" labelFloat="true" prefWidth="325.0" promptText="دانشکده">
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</VBox.margin>
</JFXComboBox>
<JFXComboBox fx:id="cbxSDep" labelFloat="true" layoutX="20.0" layoutY="226.0" prefWidth="325.0" promptText="بخش">
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</VBox.margin>
</JFXComboBox>
<JFXComboBox fx:id="cbxSYear" labelFloat="true" layoutX="20.0" layoutY="177.0" prefWidth="325.0" promptText="سال">
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</VBox.margin>
</JFXComboBox>
<JFXComboBox fx:id="cbxSSemister" labelFloat="true" layoutX="20.0" layoutY="222.0" prefWidth="325.0" promptText="سمستر">
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</VBox.margin>
</JFXComboBox>
<HBox prefHeight="66.0" prefWidth="345.0">
<children>
<JFXButton fx:id="btnCancelS" alignment="CENTER" cancelButton="true" contentDisplay="RIGHT" onAction="#cancelStudents" prefHeight="55.0" prefWidth="180.0" stylesheets="#addstudents.css" text="لغو کردن" textAlignment="CENTER">
<font>
<Font name="B Nazanin Bold" size="15.0" />
</font>
<HBox.margin>
<Insets top="10.0" />
</HBox.margin>
</JFXButton>
<JFXButton fx:id="btnSaveS" alignment="CENTER" contentDisplay="RIGHT" defaultButton="true" layoutX="10.0" layoutY="10.0" onAction="#addStudents" prefHeight="55.0" prefWidth="180.0" stylesheets="#addstudents.css" text="ذخیره کردن" textAlignment="CENTER">
<font>
<Font name="B Nazanin Bold" size="15.0" />
</font>
<HBox.margin>
<Insets top="10.0" />
</HBox.margin>
</JFXButton>
</children>
</HBox>
</children>
</VBox>
<ImageView fx:id="viewSImage" fitHeight="187.0" fitWidth="197.0" layoutX="25.0" layoutY="21.0" pickOnBounds="true" preserveRatio="true" />
<JFXButton fx:id="btnSImage" layoutX="58.0" layoutY="227.0" onAction="#openImageS" prefHeight="38.0" prefWidth="131.0" stylesheets="#addstudents.css" text="وارد کردن تصویر">
<font>
<Font name="B Nazanin Bold" size="14.0" />
</font>
</JFXButton>
</children>
</AnchorPane>

JavaFX Scene Builder Expand ScrollPane area at runtime when adding components to attached AnchorPane

I haven't been able to find info on this, but I've created a layout in Scene Builder, and I've placed an AnchorPane inside an empty ScrollPane, and added text, a slider, and a label in rows, and then added a button for the user to add a new entry of the above.
Basically a typical preference elicitation UI where the user can also add new entries and specify their own preference values as well.
When pressed, for testing purposes, the button creates a new label, adds it to the AnchorPane, and relocates it to a Y position outside the AnchorPane, and then resizes the AnchorPane so that the new label is included.
The problem that I'm having is that the ScrollPane doesn't adjust and expand the scrollable area to fit the new AnchorPane height, so I can't scroll down to where the new label is visible. In Scene Builder, on the other hand, if I resize the AnchorPane so that it's larger than the ScrollPane, the latter dynamically adjusts the scrollable area, so I'm not sure what the problem is.
Any help is appreciated.
EDIT:
As requested, below is a minimally reproducible version of the project.
Class that loads the FXML and creates the scene
package main;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.TitledPane;
import javafx.stage.Stage;
public class Registration_Page extends Application {
private Stage primaryStage;
private TitledPane mainLayout;
#Override
public void start(Stage primaryStage) throws IOException {
this.primaryStage = primaryStage;
showMainView();
}
private void showMainView() throws IOException {
FXMLLoader loader = new FXMLLoader(Registration_Page.class.getResource("resources/Registration_Page.fxml"));
mainLayout = loader.load();
Scene scene = new Scene(mainLayout);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Class that acts as the button controller, using FXML-defined components.
package main;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.AnchorPane;
public class ButtonController {
#FXML
private Button plus;
#FXML
private AnchorPane prefValuesAnchorPane;
#FXML
private ScrollPane scrollPane;
#FXML
protected void plusAction(ActionEvent event) {
Label lbl1 = new Label("Hello");
prefValuesAnchorPane.getChildren().add(lbl1);
lbl1.relocate(18, 250);
System.out.println(prefValuesAnchorPane.getHeight());
System.out.println(lbl1.getLayoutY());
if (lbl1.getLayoutY() >= prefValuesAnchorPane.getHeight())
{
prefValuesAnchorPane.resize(prefValuesAnchorPane.getWidth(), lbl1.getLayoutY() + 3);
}
}
}
The FXML document
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<TitledPane animated="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" text="User Registration" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.ButtonController">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TextField layoutX="52.0" layoutY="79.0" />
<Text layoutX="14.0" layoutY="96.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Name" />
<Text layoutX="14.0" layoutY="130.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Preference Values">
<font>
<Font size="14.0" />
</font>
</Text>
<ScrollPane fx:id="scrollPane" layoutX="14.0" layoutY="137.0" prefHeight="223.0" prefWidth="332.0">
<content>
<AnchorPane fx:id="prefValuesAnchorPane" minHeight="0.0" minWidth="0.0" prefHeight="217.0" prefWidth="329.0">
<children>
<Text layoutX="15.0" layoutY="30.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Val1:" />
<Slider blockIncrement="1.0" layoutX="115.0" layoutY="15.0" majorTickUnit="1.0" max="10.0" minorTickCount="0" prefWidth="140.0" showTickLabels="true" snapToPixel="false" snapToTicks="true" />
<Label layoutX="280.0" layoutY="12.0" text="0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Text layoutX="15.0" layoutY="62.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Val2:" />
<Slider blockIncrement="1.0" layoutX="115.0" layoutY="50.0" majorTickUnit="1.0" max="10.0" minorTickCount="0" prefWidth="140.0" showTickLabels="true" snapToTicks="true" />
<Label layoutX="280.0" layoutY="48.0" text="0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Text layoutX="15.0" layoutY="97.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Val3:" />
<Slider blockIncrement="1.0" layoutX="115.0" layoutY="85.0" majorTickUnit="1.0" max="10.0" minorTickCount="0" prefWidth="140.0" showTickLabels="true" snapToTicks="true" />
<Label layoutX="280.0" layoutY="82.0" text="0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Text layoutX="15.0" layoutY="133.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Val4:" />
<Slider blockIncrement="1.0" layoutX="115.0" layoutY="120.0" majorTickUnit="1.0" max="10.0" minorTickCount="0" prefWidth="140.0" showTickLabels="true" snapToTicks="true" />
<Label layoutX="280.0" layoutY="118.0" text="0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Label>
<Button fx:id="plus" graphicTextGap="1.0" layoutX="289.0" layoutY="153.0" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" onAction="#plusAction" prefHeight="0.0" prefWidth="30.0" text="+" textAlignment="CENTER" textOverrun="CENTER_ELLIPSIS" AnchorPane.topAnchor="153.0">
<font>
<Font name="System Bold" size="14.0" />
</font>
</Button>
</children>
</AnchorPane>
</content>
</ScrollPane>
<Button layoutX="532.0" layoutY="335.0" mnemonicParsing="false" text="Next" />
</children></AnchorPane>
</content>
</TitledPane>
The solution to this is to instead have a ScrollPane containing an AnchorPane (as it was), and for every entry added, create an AnchorPane or BorderPane or any other container pane (afaik), and add whatever to it, rather than adding components such as buttons or labels directly onto the original AP that's attached to the SP.

TableView: the last line becomes unselectable after row deletion -Is this a bug

for more information see this link Sometimes TableView cannot select last row after row deletion.
the problem only appears when the TableView must contain exactly 6 lines. if I delete the fourth or fifth line, the last line (necessarily fifth) becomes inaccessible (not selectable). as soon as I make another line suppression, the line that was not unreachable becomes selectable !!.
My Controller has the following code:
public class FXMLIssueController implements Initializable {
#FXML
private TableView<User> userTable;
#FXML
private TableColumn<User, String> nameCol;
#FXML
private TableColumn<User, LocalDate> birthdayCol;
#FXML
private TableColumn<User, String> emailCol;
#FXML
private TextField name;
#FXML
private TextField email;
#FXML
private DatePicker birthday;
private ObservableList<User> data;
private LocalDate birth;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
data = FXCollections.observableArrayList();
birthday.setOnAction((ActionEvent evnt) -> {
birth = birthday.getValue();
});
userTable.getSelectionModel().selectedItemProperty().addListener(userListener);
configureColumn();
fill_in();
}
#FXML
private void newUser(ActionEvent event) {
userTable.getSelectionModel().clearSelection();
userTable.getSelectionModel().selectedItemProperty().removeListener(userListener);
name.clear();
birthday.valueProperty().set(null);
email.clear();
userTable.getSelectionModel().selectedItemProperty().addListener(userListener);
}
#FXML
private void addUser(ActionEvent event) {
User u = new User();
u.setName(name.getText());
u.setEmail(email.getText());
u.setBirthday(birthday.getValue());
data.add(u);
}
#FXML
private void deleteUser(ActionEvent event) {
User u = userTable.getSelectionModel().selectedItemProperty().getValue();
if (u != null) {
data.remove(u);
}
}
#FXML
private void populate() {
data.clear();
fill_in();
}
private void configureColumn() {
nameCol.setCellValueFactory(new PropertyValueFactory<User, String>("name"));
emailCol.setCellValueFactory(new PropertyValueFactory<User, String>("email"));
birthdayCol.setCellValueFactory(new PropertyValueFactory<User, LocalDate>("birthday"));
birthdayCol.setCellFactory(p -> {
return new TableCell<User, LocalDate>() {
#Override
protected void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
} else {
final DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MM/yyyy");
setText(item.format(format));
}
}
};
});
}
private final ChangeListener<User> userListener = (value, oldV, newV) -> {
if (oldV != null) {
name.textProperty().unbindBidirectional(oldV.nameProperty());
email.textProperty().unbindBidirectional(oldV.emailProperty());
birthday.valueProperty().unbindBidirectional(oldV.birthdayProperty());
}
if (newV != null) {
name.textProperty().bindBidirectional(newV.nameProperty());
email.textProperty().bindBidirectional(newV.emailProperty());
birthday.valueProperty().bindBidirectional(newV.birthdayProperty());
}
};
private void fill_in(){
for (int i = 0; i < 6; i++) {
User u = new User();
u.setName("u"+i);
u.setBirthday(LocalDate.now().plusDays(i));
u.setEmail("mail"+i+"#gmail.com");
data.addAll(u);
}
userTable.setItems(data);
userTable.getSelectionModel().select(0);
}
}
My FXML File:
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="381.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="issue.FXMLIssueController">
<bottom>
<TableView fx:id="userTable" prefHeight="141.0" prefWidth="381.0" BorderPane.alignment="CENTER">
<columns>
<TableColumn fx:id="nameCol" prefWidth="75.0" text="Name" />
<TableColumn fx:id="birthdayCol" prefWidth="163.0" text="Birthday" />
<TableColumn fx:id="emailCol" prefWidth="141.0" text="Email" />
</columns>
</TableView>
</bottom>
<top>
<HBox alignment="CENTER_RIGHT" prefHeight="40.0" prefWidth="381.0" spacing="10.0" BorderPane.alignment="CENTER">
<children>
<HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="213.0">
<children>
<Button mnemonicParsing="false" onAction="#populate" text="Populate" />
</children>
</HBox>
<Button mnemonicParsing="false" onAction="#newUser" text="New" />
<Button mnemonicParsing="false" onAction="#addUser" text="Add" />
<Button mnemonicParsing="false" onAction="#deleteUser" text="Delete" />
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</HBox>
</top>
<center>
<GridPane prefHeight="100.0" prefWidth="600.0" BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="294.0" minWidth="10.0" prefWidth="91.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="477.0" minWidth="10.0" prefWidth="387.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Name:" />
<Label text="Birthday" GridPane.rowIndex="1" />
<Label text="email" GridPane.rowIndex="2" />
<TextField fx:id="name" prefHeight="25.0" prefWidth="375.0" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" />
<TextField fx:id="email" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="2" />
<DatePicker fx:id="birthday" prefHeight="25.0" prefWidth="346.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children>
<padding>
<Insets bottom="7.0" left="7.0" right="7.0" top="7.0" />
</padding>
</GridPane>
</center>
</BorderPane>
Here is the code of the User Class:
public class User {
private final StringProperty name = new SimpleStringProperty();
private final StringProperty email = new SimpleStringProperty();
private final ObjectProperty<LocalDate> birthday = new SimpleObjectProperty<>();
public StringProperty nameProperty() {
return name;
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public StringProperty emailProperty() {
return email;
}
public String getEmail() {
return email.get();
}
public void setEmail(String email) {
this.email.set(email);
}
public ObjectProperty<LocalDate> birthdayProperty() {
return birthday;
}
public LocalDate getBirthday() {
return birthday.get();
}
public void setBirthday(LocalDate birthday) {
this.birthday.set(birthday);
}
}
class Main:
public class Test extends Application {
#Override
public void start(Stage stage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("/issue/FXMLIssue.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.setResizable(false);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}}
I invite you to test the program as follows:
delete the fourth or fifth line.
try to select the last line using the mouse.
if no problem, click the button populate and try again.
Use the following links to download and test the program:
complete project
executable file

External javascript call from Brightcove BEML

Is there any way to reference a custom javascript function from BEML? I'd like to keep away from Flash since what ever I do needs to work in the HTML5 player as well.
<Runtime>
<Layout width="800" height="600" id="backgroundTemplate">
<Canvas>
<VideoDisplay id="videoPlayer" width="788" height="487" x="9" y="13"/>
<MediaControls x="5" y="509" width="791" height="87" id="mediaControls">
<VBox>
<Canvas height="25" padding="20">
<Playhead mediaController="{videoPlayer}" autohideSlider="false" useTimeToolTip="true"/>
</Canvas>
<HBox padding="10">
<HBox id="leftBtn_container" hAlign="left">
<ToggleButton id="playButton" width="60" height="60" x="0" y="0" showBack="true" click="{videoPlayer.play()}" toggledClick="{videoPlayer.pause()}" toggled="{videoPlayer.playing}"/>
</HBox>
<HBox id="rightBtn_container" hAlign="right">
<Button width="60" height="60" id="cite_btn" click="{someFunction.doSomething()}"/>
</HBox>
</HBox>
</VBox>
</MediaControls>
</Canvas>
</Layout>
</Runtime>
You would need to create a custom component.Creating Custom Player Components
Call custom component in BEML.
<Modules>
<Module file="http://urltocustomcomponent.com/my_component.swf" />
</Modules>
Button in BEML
<ToggleButton id="my_button" width="40" height="40" />
Actionscript for custom component.
package
{
import com.brightcove.api.APIModules;
import com.brightcove.api.BrightcoveModuleWrapper
import com.brightcove.api.CustomModule;
import com.brightcove.api.modules.ExperienceModule;
import com.brightcove.api.events.BEMLMouseEvent;
import flash.events.Event;
import flash.external.ExternalInterface;
import com.brightcove.api.components.Button;
public class yogaComponent extends CustomModule
{
override protected function initialize():void
{
// Get the experience module
var experienceModule:ExperienceModule = player.getModule(APIModules.EXPERIENCE) as ExperienceModule;
// Define Info Button
var button:Button = experienceModule.getElementByID("my_button") as Button;
// Our listener that calls the function
button.addEventListener(BEMLMouseEvent.CLICK, myCustomFunc);
}
// Custom Function
private function myCustomFunc(event:Event):void
{
if(ExternalInterface.available)
{
// this calls a javascript function in your html
ExternalInterface.call('myJavascriptAlertFunction');
}
}
}
}
Javascript function that is called on event click.
function myJavascriptAlertFunction()
{
alert('it works!');
}

HTML content inside TabNavigator

I have a case where I'm adding tabNavigator tabs dynamically and I can't figure out how to add HTML styling to some of the words.
I really only need BOLD or UNDERLINE on a few words, but I can't get any HTML formatting to work inside the NavigatorContent tag.
Can anyone help me with this? I have been looking for many hours and found nothing.
Here's what I have so far. (the content is being pulled from an external XML file).
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="500" height="600" creationComplete="initApp()">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:HTTPService id="chatlist" result="resultHandler(event)"
url="http://localhost/FlexLiveChat/LiveChat2/chat.xml"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
private function initApp():void
{
chatlist.send();
}
private function resultHandler(event:ResultEvent):void
{
var dp:ArrayCollection = event.result.chatsession.chat as ArrayCollection;
for(var i:int = 0; i < dp.length; i++) {
var t:TextField = new TextField( );
t.htmlText = "This field contains <B>HTML!</B>";
var label:Label = new Label();
label.text = dp.getItemAt(i).message;
var context:NavigatorContent = new NavigatorContent();
context.label = dp.getItemAt(i).chatperson;
context.addElement(label);
tn.addChild(context);
}
}
]]>
</fx:Script>
<s:BorderContainer left="10" right="10" top="10" bottom="10" height="100%" borderVisible="false">
<s:VGroup id="mainBG" x="0" y="0" width="100%" height="100%" textAlign="center">
<mx:TabNavigator id="tn" width="100%" height="100%" color="0x323232">
<!-- Define each panel using a VBox container. -->
<s:NavigatorContent label="Home">
<s:Label text="This panel is always available \n\n container panel 1"/>
<mx:Text text="This is a text control."/>
</s:NavigatorContent>
</mx:TabNavigator>
<s:TextArea width="100%" height="62" textAlign="left"/>
<s:Button label="Post Message"/>
</s:VGroup></s:BorderContainer>
</s:WindowedApplication>
You could use a text flow:
<?xml version="1.0" encoding="utf-8"?>
<s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="100%"
height="100%"
gap="0">
<fx:Script>
<![CDATA[
import flashx.textLayout.conversion.TextConverter;
import flashx.textLayout.elements.TextFlow;
private const text:String =
"<b>bold text</b><br />" +
"<br />" +
"<u>underlined text</u><br />" +
"<br />" +
"<ul>" +
"<li>list item<br /></li>" +
"<li>list item<br /></li>" +
"<li>list item<br /></li>" +
"</ul>" +
"<a href='http://www.google.com'>a link</a><br />" +
"<br />";
]]>
</fx:Script>
<s:RichEditableText editable="false"
selectable="true"
textFlow="{TextConverter.importToFlow(text, TextConverter.TEXT_FIELD_HTML_FORMAT)}"
buttonMode="true"
width="100%"
height="100%" />
</s:VGroup>
Per your comment, you should abstract the navigator content view in to a component.
Based upon your example:
Your main application
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="500"
height="600"
creationComplete="initApp()">
<fx:Declarations>
<s:HTTPService id="chatlist"
result="resultHandler(event)"
url="http://localhost/FlexLiveChat/LiveChat2/chat.xml" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
private function initApp():void
{
chatlist.send();
}
private function resultHandler(event:ResultEvent):void
{
var dp:ArrayCollection = event.result.chatsession.chat as ArrayCollection;
for (var i:int = 0; i < dp.length; i++)
{
var htmlNavigatorContent:HtmlNavigatorContent = new HtmlNavigatorContent();
// attach result you want in the html text,
// including other properties.
htmlNavigatorContent.htmlText = "This field contains <B>HTML!</B>";
tn.addChild(htmlNavigatorContent);
}
}
]]>
</fx:Script>
<s:BorderContainer left="10"
right="10"
top="10"
bottom="10"
height="100%"
borderVisible="false">
<s:VGroup id="mainBG"
x="0"
y="0"
width="100%"
height="100%"
textAlign="center">
<mx:TabNavigator id="tn"
width="100%"
height="100%"
color="0x323232">
<!-- Define each panel using a VBox container. -->
<s:NavigatorContent label="Home">
<s:Label text="This panel is always available \n\n container panel 1" />
<mx:Text text="This is a text control." />
</s:NavigatorContent>
</mx:TabNavigator>
<s:TextArea width="100%"
height="62"
textAlign="left" />
<s:Button label="Post Message" />
</s:VGroup>
</s:BorderContainer>
</s:WindowedApplication>
Create a MXML Component named: HtmlNavigatorContent
<?xml version="1.0" encoding="utf-8"?>
<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="100%"
height="100%">
<fx:Script>
<![CDATA[
import flashx.textLayout.conversion.TextConverter;
import flashx.textLayout.elements.TextFlow;
[Bindable]
public var htmlText:String;
]]>
</fx:Script>
<s:RichEditableText editable="false"
selectable="true"
textFlow="{TextConverter.importToFlow(htmlText, TextConverter.TEXT_FIELD_HTML_FORMAT)}"
buttonMode="true"
width="100%"
height="100%" />
</s:NavigatorContent>

Resources