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

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

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 8 - table pagination issue stack overflow

This is the layout I want to make
This is fxml file: category.main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Pagination?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<AnchorPane prefHeight="381.0" prefWidth="899.0" styleClass="background-white" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.ciro.hm.controller.CategoryMainController">
<children>
<VBox prefHeight="400.0" prefWidth="573.0" style="-fx-min-width: 80%;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="321.0" AnchorPane.topAnchor="10.0">
<children>
<BorderPane>
<center>
<TableView fx:id="table" prefHeight="323.0" prefWidth="573.0">
<columns>
<TableColumn fx:id="colId" editable="false" minWidth="30.0" prefWidth="75.0" resizable="false" styleClass="table-cell" text="%tbl.id" />
<TableColumn fx:id="colName" editable="false" prefWidth="253.0" resizable="false" styleClass="table-cell" text="%tbl.name" />
<TableColumn fx:id="colInOut" editable="false" minWidth="0.0" prefWidth="155.0" styleClass="table-cell" text="%tbl.in.out" />
<TableColumn fx:id="colBtn" editable="false" minWidth="0.0" prefWidth="90.0" resizable="false" sortable="false" styleClass="table-cell" text="#" />
</columns>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</TableView>
</center>
</BorderPane>
<Pagination fx:id="pagination" prefHeight="51.0" prefWidth="573.0" />
</children>
</VBox>
<VBox layoutX="448.0" maxWidth="203.0" minWidth="-Infinity" prefHeight="400.0" prefWidth="300.0" AnchorPane.rightAnchor="7.0" AnchorPane.topAnchor="10.0">
<children>
<TitledPane animated="false" collapsible="false" prefHeight="264.0" prefWidth="400.0" text="%app.pane.category">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="230.0" prefWidth="201.0">
<children>
<Button fx:id="btnSave" layoutX="17.0" layoutY="151.0" mnemonicParsing="false" text="%app.lbl.save" AnchorPane.leftAnchor="0.0" />
<Label layoutX="14.0" layoutY="14.0" text="%app.lbl.name" AnchorPane.leftAnchor="0.0" />
<ComboBox fx:id="fldInOut" layoutX="17.0" layoutY="101.0" prefWidth="150.0" promptText="%app.generic.selection" AnchorPane.leftAnchor="0.0" />
<Label layoutX="71.0" layoutY="80.0" text="%app.lbl.in.out" AnchorPane.leftAnchor="0.0" />
<TextField fx:id="fldName" layoutX="14.0" layoutY="35.0" AnchorPane.leftAnchor="0.0" />
</children>
</AnchorPane>
</content>
</TitledPane>
</children>
</VBox>
</children>
</AnchorPane>
This is controller
package com.ciro.hm.controller;
import com.ciro.hm.model.Category;
import com.ciro.hm.service.CategoryService;
import com.ciro.hm.to.CategoryTO;
import de.jensd.fx.glyphs.GlyphsDude;
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
#Component
#Slf4j
public class CategoryMainController extends BaseController implements Initializable {
ObservableList<Category> data;
#FXML
BorderPane mainBorder;
#Value("${app.hm.in-out-value}")
List<String> inOut;
#FXML
TableView<Category> table;
#FXML
TextField fldName;
#FXML
ComboBox<String> fldInOut;
#FXML
TableColumn<Category, Integer> colId;
#FXML
TableColumn<Category, String> colName;
#FXML
TableColumn<Category, String> colInOut;
#FXML
TableColumn<Category, String> colBtn;
private CategoryService categoryService;
#Autowired
public CategoryMainController(CategoryService categoryService){
this.categoryService = categoryService;
}
#Override
public void initialize(URL location, ResourceBundle resources) {
super.initialize(location, resources);
data = categoryService.findAll();
fldInOut.getItems().removeAll();
fldInOut.getItems().addAll(inOut);
btnSave.setOnAction(this::save);
pagination.setCurrentPageIndex(0);
pagination.setPageCount(getPageSize(data));
pagination.setPageFactory(this::createPage);
table.setItems(FXCollections.observableArrayList(data.subList(0, paginationSize)));
colId.setCellValueFactory(new PropertyValueFactory<>("idCategory"));
colName.setCellValueFactory(new PropertyValueFactory<>("name"));
colInOut.setCellValueFactory(new PropertyValueFactory<>("inOut"));
colBtn.setCellFactory(getEditCellFactory());
}
private Callback<TableColumn<Category, String>, TableCell<Category, String>> getEditCellFactory() {
return new Callback<TableColumn<Category, String>, TableCell<Category, String>>() {
#Override
public TableCell<Category,String> call(final TableColumn<Category, String> param) {
return new TableCell<Category, String>() {
Button btn = getEditBtn();
{
btn.setOnAction((ActionEvent event) -> {
Category data = getTableView().getItems().get(getIndex());
save(event);
});
}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
setText(null);
} else {
setGraphic(btn);
setText(null);
}
}
};
}
};
}
#Override
public Button getEditBtn(){
Button b = GlyphsDude.createIconButton(FontAwesomeIcon.EDIT,btnEditText,iconSize,fontSize, ContentDisplay.GRAPHIC_ONLY);
btnEditCssClass.forEach(s->b.getStyleClass().add(s));
return b;
}
private void save(ActionEvent event) {
log.debug(event.toString());
CategoryTO categoryTO = new CategoryTO(fldName.getText(), (String) fldInOut.getValue());
categoryService.save(categoryTO);
}
private Node createPage(int pageIndex) {
int fromIndex = pageIndex * paginationSize;
int toIndex = Math.min(fromIndex + paginationSize, data.size());
pagination.setCurrentPageIndex(pageIndex);
table.setItems(FXCollections.observableArrayList(data.subList(fromIndex, toIndex)));
return mainBorder;
}
}
The first problem is that during the initialization of the controller the createPage method is executed twice. Which seems pretty strange to me. The initialization of the parent class requires only the assignment of the boundle source to a property of the class. The second problem is that at the click of a single page the call to the createPage method goes into a loop generating a stack overflow. As with the guides, the method returns the container in which the table is included. The pagination element is external to it and therefore should not be cyclically reloaded. Some advice?
In any case, the entire application is based on spring boot
EDIT: CHANGE METHOD
I modified this
private Node createPage(int pageIndex) {
log.info("Page index: " + pageIndex);
int fromIndex = pageIndex * paginationSize;
int toIndex = Math.min(fromIndex + paginationSize, data.size());
table.setItems(FXCollections.observableArrayList(data.subList(fromIndex, toIndex)));
return table;
}
and it's initialized and execute once ...but layout explode
Ok instead of
pagination.setPageFactory
just use
pagination.currentPageIndexProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
createPage(newValue.intValue());
}
});
then change createPage method in this way
private void createPage(int pageIndex) {
log.info("Page index: " + pageIndex);
int fromIndex = pageIndex * paginationSize;
int toIndex = Math.min(fromIndex + paginationSize, data.size());
table.setMinHeight(400);
table.getItems().clear();
table.setItems(FXCollections.observableArrayList(data.subList(fromIndex, toIndex)));
}
moreover
private void createPage(int pageIndex) {
int fromIndex = pageIndex * paginationSize;
int toIndex = Math.min(fromIndex + paginationSize, data.size());
table.getItems().clear();
table.setItems(FXCollections.observableArrayList(data.subList(fromIndex, toIndex)));
}
moreover borderpane node is not necessary

JavaFX and Spring - Reusable FXML component

I am building a GUI with Scene Builder in JavaFX and Spring Boot. Several of my scenes have one element in common, which is a simple KPI indicator, called PerformanceBeacon. Depending on the configuration, done by the controller class, the beacon can be used e.g. for project parameters like budget, time and so one. Ideally, even a single scene may have multiple of this elements.
The issue is, having multiple KPI beacons in a single scene does somehow not work, since all embedded controllers are pointing to the same memory and hence, I can only manipulate one - which is the last - KPI beacon.
The snipped from the fxml file looks like this:
...
<VBox layoutX="301.0" layoutY="325.0" spacing="6.0" AnchorPane.leftAnchor="2.0" AnchorPane.topAnchor="24.0">
<children>
<fx:include source="PerformanceBeacon.fxml" fx:id="embeddedTimeKPI" />
<fx:include source="PerformanceBeacon.fxml" fx:id="embeddedBudgetKPI"/>
<fx:include source="PerformanceBeacon.fxml" fx:id="embeddedResourcesKPI"/>
<fx:include source="PerformanceBeacon.fxml" fx:id="embeddedScopeKPI"/>
<fx:include source="PerformanceBeacon.fxml" fx:id="embeddedEffortKPI"/>
<fx:include source="PerformanceBeacon.fxml" fx:id="embeddedQualityKPI"/>
</children>
</VBox>
...
The embedded controllers are defined in the controller class of the enclosing UI and the code should "only" set the label of each of the Hyperlinks in each PerformanceBeacon.
#Controller
public class ProductManagerCtrl implements Initializable {
...
#FXML protected PerformanceBeaconCtrl embeddedTimeKPIController;
#FXML protected PerformanceBeaconCtrl embeddedBudgetKPIController;
#FXML protected PerformanceBeaconCtrl embeddedResourcesKPIController;
#FXML protected PerformanceBeaconCtrl embeddedScopeKPIController;
#FXML protected PerformanceBeaconCtrl embeddedEffortKPIController;
#FXML protected PerformanceBeaconCtrl embeddedQualityKPIController;
...
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
...
initializePerformanceIndicator();
...
}
protected void initializePerformanceIndicator() {
embeddedBudgetKPIController.setHyperlink("Budget", null);
embeddedScopeKPIController.setHyperlink("Scope", null);
embeddedTimeKPIController.setHyperlink("Time", null);
embeddedQualityKPIController.setHyperlink("Quality", null);
embeddedResourcesKPIController.setHyperlink("Resources", null);
embeddedEffortKPIController.setHyperlink("Effort estimates", null);
}
When I debug the code, each of these embedded controllers points to the same memory. So effectively I have one controller and can only manipulate the last element. In the end the last beacon has the "Effort estimates" label and all others are unchanged.
The PerformanceBeacon.fxml is rather simple. I copy it, in case you want to try yourself
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.Double?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.shape.Polygon?>
<GridPane styleClass="pane" stylesheets="#../stylesheets/PerformanceBeacon.css" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.agiletunes.productmanager.controllers.PerformanceBeaconCtrl">
<children>
<Circle fx:id="beacon" fill="#1fff4d" radius="10.0" stroke="BLACK" strokeType="INSIDE" GridPane.columnIndex="1" GridPane.valignment="CENTER">
<GridPane.margin>
<Insets bottom="12.0" left="12.0" right="6.0" top="12.0" />
</GridPane.margin>
</Circle>
<Polygon fx:id="trendArrow" fill="#11ff1c" rotate="45.0" stroke="#2e229a" strokeType="INSIDE" GridPane.columnIndex="2" GridPane.valignment="CENTER">
<points>
<Double fx:value="-10.0" />
<Double fx:value="10.0" />
<Double fx:value="-5.0" />
<Double fx:value="10.0" />
<Double fx:value="-5.0" />
<Double fx:value="15.0" />
<Double fx:value="5.0" />
<Double fx:value="15.0" />
<Double fx:value="5.0" />
<Double fx:value="10.0" />
<Double fx:value="10.0" />
<Double fx:value="10.0" />
<Double fx:value="0.0" />
<Double fx:value="-10.0" />
</points>
<GridPane.margin>
<Insets bottom="12.0" left="12.0" right="12.0" top="12.0" />
</GridPane.margin>
</Polygon>
<Hyperlink fx:id="hyperlink" onAction="#showDetails" text="Subject">
<GridPane.margin>
<Insets left="24.0" />
</GridPane.margin>
</Hyperlink>
</children>
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" minWidth="170.0" />
<ColumnConstraints minWidth="10.0" />
<ColumnConstraints minWidth="10.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
</GridPane>
And last but not least the Controller of the PerformanceBeacon
#Controller
public class PerformanceBeaconCtrl {
#FXML protected Circle beacon;
#FXML private Polygon trendArrow;
#FXML private Hyperlink hyperlink;
#FXML
public void showDetails(ActionEvent event) {
// TODO
}
public void setHyperlink(String label, URL url) {
Platform.runLater(() -> {
hyperlink.setText(label);
});
}
public void setBeaconColor(Color color) {
Platform.runLater(() -> {
beacon.setFill(color);
});
}
public void setTrend(Double angle) {
Platform.runLater(() -> {
trendArrow.rotateProperty().set(angle);
});
}
}
I am successfully using embedded UI elements / controller also elsewhere in my code. But never the same element multiple times.
I am not sure whether this is a Spring side effect?
What am I doing wrong? Thank you in advance.
The described observation suggests that the issue was related to a singleton somewhere in the design. My suspicion regarding the Spring influence was right. The ProductManagerCtrl controller class gets created using
fxmlLoader.setControllerFactory(c -> ProdMgrApp.springContext.getBean(c));
and as it turns out, this approach creates singletons by default. Therefore all embedded controller are also singletons. The way to fix it is to annotate the PerformanceBeaconCtrl controller class also with
#Scope("prototype")

Link subreport connected to database with mainreport that is sent by controller it won't work even with adding parameter?

I have 3 entities orderclient and orderlineclient: relation one-to-many
and orderlineclient and product: relation many-to-many. I send orderlines to jasper file with this method:
#GetMapping("/pdf/{id}")
public ModelAndView report(#PathVariable("id") Long id) throws JRException {
JasperReportsPdfView view = new JasperReportsPdfView();
view.setUrl("classpath:clientreport.jrxml");
view.setApplicationContext(appContext);
Map<String, Object> params = new HashMap<>();
Client client = clientRepository.findOne(id);
List<OrderClient> ordersClient = orderClientRepository.findByClient(client);
List<OrderLineClient> orderLines = new ArrayList<>();
for (OrderClient order : ordersClient) {
orderLines.addAll(order.getOrderLineClients());
}
params.put("source", orderLines);
return new ModelAndView(view, params);
}
Then I create a sub-report and I link it directly to the database. After, I create a param and run the following SQL:
SELECT product.id,
product.name,
product.price,
order_line_client.id,
order_line_client.price,
order_line_client.quantities,
order_line_client.tooths
FROM product,
order_line_products,
order_line_client
WHERE
product.id = order_line_products.product_id
AND order_line_products.order_line_id = order_line_client.id
AND order_line_client.order_client_id = $P{orderid}
But when I run the app I get exceptions. Can someone please help me get the following:
date of order
number of order
product
quantities
price
totalPrice
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
#Entity
public class OrderClient {
// Attributes
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String number;
private Date orderDate;
private String notes;
private String patientName;
#ManyToOne
private Client client;
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "orderClient")
private List<OrderLineClient> orderLineClients = new ArrayList<>();
// Getters & Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public String getPatientName() {
return patientName;
}
public void setPatientName(String patientName) {
this.patientName = patientName;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public List<OrderLineClient> getOrderLineClients() {
return orderLineClients;
}
public void setOrderLineClients(List<OrderLineClient> orderLineClients) {
this.orderLineClients = orderLineClients;
}
/**
* equals method
*
* #param o
* #return
*/
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OrderClient order = (OrderClient) o;
return Objects.equals(id, order.id);
}
/**
* hashCode method
*
* #return
*/
#Override
public int hashCode() {
return Objects.hash(id);
}
}
order line client
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
#Entity
public class OrderLineClient {
#Id
#GeneratedValue
private Long id;
private String quantities;
private Double price;
private String tooths;
#ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinTable(name="orderLine_products", joinColumns=#JoinColumn(name="orderLine_id"), inverseJoinColumns=#JoinColumn(name="product_id"))
private List<Product> products = new ArrayList<>();
#ManyToOne
private Category category;
#ManyToOne
private OrderClient orderClient;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public String getQuantities() {
return quantities;
}
public void setQuantities(String quantities) {
this.quantities = quantities;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getTooths() {
return tooths;
}
public void setTooths(String tooths) {
this.tooths = tooths;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public OrderClient getOrderClient() {
return orderClient;
}
public void setOrderClient(OrderClient orderClient) {
this.orderClient = orderClient;
}
public List<Double> getQuantitiesValues(){
if (getQuantities() == null ) return null;
if (getQuantities().contains("/"))
return CollectionUtils.convertList( Arrays.asList(getQuantities().split("/")), s -> Double.parseDouble(s) );
else {
return Collections.singletonList(Double.parseDouble(getQuantities()));
}
}
public List<String> getToothsValues(){
if (getTooths() == null) return null;
if (getTooths().contains("/"))
return Arrays.asList(getTooths().split("/"));
else
return Collections.singletonList(getTooths());
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OrderLineClient that = (OrderLineClient) o;
return Objects.equals(id, that.id);
}
#Override
public int hashCode() {
return Objects.hash(id);
}
}
product
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
#Entity
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false)
private String name;
private Double price;
private String unit;
private Double quantity;
private Double quantityMin;
private Double quantityMax;
private String picture;
#ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "products")
private List<OrderLineClient> orderLineClients = new ArrayList<>();
#ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinTable(name="product_category", joinColumns=#JoinColumn(name="product_id"), inverseJoinColumns=#JoinColumn(name="category_id"))
private List<Category> categories = new ArrayList<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public Double getQuantity() {
return quantity;
}
public void setQuantity(Double quantity) {
this.quantity = quantity;
}
public Double getQuantityMin() {
return quantityMin;
}
public void setQuantityMin(Double quantityMin) {
this.quantityMin = quantityMin;
}
public Double getQuantityMax() {
return quantityMax;
}
public void setQuantityMax(Double quantityMax) {
this.quantityMax = quantityMax;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
public List<OrderLineClient> getOrderLineClients() {
return orderLineClients;
}
public void setOrderLineClients(List<OrderLineClient> orderLineClients) {
this.orderLineClients = orderLineClients;
}
public List<Category> getCategories() {
return categories;
}
public void setCategories(List<Category> categories) {
this.categories = categories;
}
public Category getParentCategory(){
return getCategories().isEmpty() ? null : getCategories().get(0).getParentCategory();
}
public boolean isOneCategory(Category category ){
return categories.stream().anyMatch(category::equals);
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Product product = (Product) o;
return Objects.equals(id, product.id);
}
#Override
public int hashCode() {
return Objects.hash(id);
}
}
this is the exception
net.sf.jasperreports.engine.JRException: Resource not found at: src/main/resources/underreport.jasper.
at net.sf.jasperreports.repo.RepositoryUtil.getResourceFromLocation(RepositoryUtil.java:153) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.repo.RepositoryUtil.getReport(RepositoryUtil.java:112) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRFillSubreport.loadReport(JRFillSubreport.java:402) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateReport(JRFillSubreport.java:369) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateSubreport(JRFillSubreport.java:431) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluate(JRFillSubreport.java:345) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:383) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:533) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:2549) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:791) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:252) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:99) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:609) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.BaseReportFiller.fill(BaseReportFiller.java:405) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:140) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:667) ~[jasperreports-6.5.1.jar:6.5.1]
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:983) ~[jasperreports-6.5.1.jar:6.5.1]
at org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView.fillReport(AbstractJasperReportsView.java:681) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView.renderMergedOutputModel(AbstractJasperReportsView.java:566) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1286) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1041) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:984) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.16.jar:8.5.16]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) ~[spring-boot-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110) ~[spring-boot-actuator-1.5.6.RELEASE.jar:1.5.6.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.16.jar:8.5.16]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
this is the main report
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.5.0.final using JasperReports Library version 6.5.0 -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="clientreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="f5644a3e-c1ef-42f5-b449-e1d38e2d0fd8">
<queryString>
<![CDATA[]]>
</queryString>
<field name="orderClient.id" class="java.lang.Long"/>
<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="79" splitType="Stretch">
<staticText>
<reportElement x="227" y="24" width="100" height="30" uuid="e75f9094-468e-4cf0-83ad-ed751fddd3fd"/>
<textElement textAlignment="Center">
<font size="18" isBold="true"/>
</textElement>
<text><![CDATA[Facture]]></text>
</staticText>
</band>
</title>
<pageHeader>
<band height="35" splitType="Stretch"/>
</pageHeader>
<columnHeader>
<band height="241" splitType="Stretch">
<line>
<reportElement x="-40" y="10" width="615" height="1" uuid="97823373-89aa-42e5-b490-093c4c733c8d"/>
</line>
<line>
<reportElement x="-40" y="61" width="615" height="1" uuid="0db72487-cd75-44f9-adfa-960ba7228c69"/>
</line>
<line>
<reportElement x="71" y="10" width="1" height="51" uuid="361295c4-4882-4557-a9fb-7ebc9cb2f85e"/>
</line>
<line>
<reportElement x="167" y="10" width="1" height="51" uuid="d955e6d9-f764-4beb-9dd3-9894d1c63e1b"/>
</line>
<line>
<reportElement x="280" y="11" width="1" height="50" uuid="a3695a4f-8c97-416c-8eaf-0969e89928dd"/>
</line>
<staticText>
<reportElement x="-20" y="20" width="100" height="30" uuid="fb2c51d1-f35f-4c81-8cb6-26bdfc788bbe">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="a0b6a2a6-515d-45cd-a542-2dc271b1b56f"/>
</reportElement>
<text><![CDATA[orderClient.id]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="233" splitType="Stretch">
<textField>
<reportElement x="-20" y="0" width="100" height="30" uuid="cacba138-4c84-4a2d-9f82-dd47a2685203">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="a0b6a2a6-515d-45cd-a542-2dc271b1b56f"/>
</reportElement>
<textFieldExpression><![CDATA[$F{orderClient.id}]]></textFieldExpression>
</textField>
<subreport>
<reportElement x="250" y="30" width="200" height="151" uuid="3a4a68df-12fa-4e4b-a3d5-8ba43f819e1d"/>
<subreportParameter name="orderid">
<subreportParameterExpression><![CDATA[$F{orderClient.id}]]></subreportParameterExpression>
</subreportParameter>
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
<subreportExpression><![CDATA["src/main/resources/underreport.jasper"]]></subreportExpression>
</subreport>
</band>
</detail>
<columnFooter>
<band height="45" splitType="Stretch"/>
</columnFooter>
<pageFooter>
<band height="54" splitType="Stretch"/>
</pageFooter>
<summary>
<band height="42" splitType="Stretch"/>
</summary>
</jasperReport>
this is the subreport
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.5.0.final using JasperReports Library version 6.5.0 -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="underreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="3365f770-336c-4f9c-a25f-0886872566e0">
<property name="com.jaspersoft.studio.data.sql.tables">
<![CDATA[cHJvZHVjdCAsMTM5LDI4LDc0MGI5ZWIxLTY4OGYtNGI3MS1hOGVjLWY3NDA0ZWE2ZmIzOTtvcmRl
cl9saW5lX3Byb2R1Y3RzICwyMzUsNDEsZWY1N2VmY2EtZDNmYS00MTNhLWE0MTgtNzA5ODU2ZWEz
YTQ0O29yZGVyX2xpbmVfY2xpZW50ICwxNSwxNSxmOTdiYTY2OC03MTNiLTQzNzAtYWI0MS1kODFi
YmM4MGFiZTE7]]>
</property>
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="JDBC Data Adapter"/>
<parameter name="orderid" class="java.lang.Long"/>
<queryString language="SQL">
<![CDATA[SELECT product.id,
product.name,
product.price,
order_line_client.id,
order_line_client.price,
order_line_client.quantities,
order_line_client.tooths
FROM product,
order_line_products,
order_line_client
WHERE
product.id = order_line_products.product_id
AND order_line_products.order_line_id = order_line_client.id]]>
</queryString>
<field name="id" class="java.lang.Long">
<property name="com.jaspersoft.studio.field.label" value="id"/>
<property name="com.jaspersoft.studio.field.tree.path" value="product"/>
</field>
<field name="name" class="java.lang.String">
<property name="com.jaspersoft.studio.field.label" value="name"/>
<property name="com.jaspersoft.studio.field.tree.path" value="product"/>
</field>
<field name="price" class="java.lang.Double">
<property name="com.jaspersoft.studio.field.label" value="price"/>
<property name="com.jaspersoft.studio.field.tree.path" value="product"/>
</field>
<field name="COLUMN_4" class="java.lang.Long">
<property name="com.jaspersoft.studio.field.label" value="id"/>
<property name="com.jaspersoft.studio.field.tree.path" value="order_line_client"/>
</field>
<field name="COLUMN_5" class="java.lang.Double">
<property name="com.jaspersoft.studio.field.label" value="price"/>
<property name="com.jaspersoft.studio.field.tree.path" value="order_line_client"/>
</field>
<field name="quantities" class="java.lang.String">
<property name="com.jaspersoft.studio.field.label" value="quantities"/>
<property name="com.jaspersoft.studio.field.tree.path" value="order_line_client"/>
</field>
<field name="tooths" class="java.lang.String">
<property name="com.jaspersoft.studio.field.label" value="tooths"/>
<property name="com.jaspersoft.studio.field.tree.path" value="order_line_client"/>
</field>
<group name="id">
<groupExpression><![CDATA[$F{id}]]></groupExpression>
</group>
<group name="name">
<groupExpression><![CDATA[$F{name}]]></groupExpression>
</group>
<group name="price">
<groupExpression><![CDATA[$F{price}]]></groupExpression>
</group>
<group name="COLUMN_4">
<groupExpression><![CDATA[$F{COLUMN_4}]]></groupExpression>
</group>
<group name="COLUMN_5">
<groupExpression><![CDATA[$F{COLUMN_5}]]></groupExpression>
</group>
<group name="quantities">
<groupExpression><![CDATA[$F{quantities}]]></groupExpression>
</group>
<group name="tooths">
<groupExpression><![CDATA[$F{tooths}]]></groupExpression>
</group>
<background>
<band splitType="Stretch"/>
</background>
<title>
<band height="79" splitType="Stretch"/>
</title>
<pageHeader>
<band height="35" splitType="Stretch"/>
</pageHeader>
<columnHeader>
<band height="61" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="30" uuid="4d24ee13-0586-4ab5-8804-0f984acdd187">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="0e5824f5-b3da-4bba-88b6-b57f5fb9d886"/>
</reportElement>
<text><![CDATA[name]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="125" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="100" height="30" uuid="616ff217-cfb2-496c-bbb8-0f4ee2a644b8">
<property name="com.jaspersoft.studio.spreadsheet.connectionID" value="0e5824f5-b3da-4bba-88b6-b57f5fb9d886"/>
</reportElement>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
</band>
</detail>
<columnFooter>
<band height="45" splitType="Stretch"/>
</columnFooter>
<pageFooter>
<band height="54" splitType="Stretch"/>
</pageFooter>
<summary>
<band height="42" splitType="Stretch"/>
</summary>
</jasperReport>

Flex 4. Output my component repeatedly

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.

Resources