I am new to JavaFX. I develop an JavaFX application. I want to show data from MySQL database in TableView.
When I add data from JavaFX, data is perfectly stored in database, but it shows 'No content in table' in tableview. There is no error in my code, I could not find where I made the mistake. I am using Eclipse IDE.
This is Customer class:
package application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Customer {
private final StringProperty pname;
private final IntegerProperty pphno;
private final StringProperty paddress;
public Customer(String pname,int pphno,String paddress){
this.pname = new SimpleStringProperty(pname);
this.pphno = new SimpleIntegerProperty(pphno);
this.paddress = new SimpleStringProperty(paddress);
}
public StringProperty getpname() {
return pname;
}
public IntegerProperty getpphno() {
return pphno;
}
public StringProperty getpaddress() {
return paddress;
}
}
This is Cust.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="575.0" prefWidth="760.0" xmlns:fx="http://javafx.com/fxml/1"
xmlns="http://javafx.com/javafx/11.0.1" fx:controller="application.CustController">
<children>
<TableView fx:id="tbl_cust" layoutX="16.0" layoutY="249.0" prefHeight="315.0"
prefWidth="730.0">
<columns>
<TableColumn fx:id="tcol_name" prefWidth="235.0" text="Name" />
<TableColumn fx:id="tcol_phno" prefWidth="223.0" text="Phone Number" />
<TableColumn fx:id="tcol_add" prefWidth="271.0" text="Address" />
</columns>
</TableView>
<VBox layoutX="37.0" layoutY="72.0" prefHeight="150.0" prefWidth="169.0" spacing="30.0">
<children>
<Label text="Name" textFill="#a86905">
<font>
<Font name="Georgia Bold" size="20.0" />
</font>
</Label>
<Label layoutX="10.0" layoutY="10.0" text="Phone Number" textFill="#9e5f02">
<font>
<Font name="Georgia Bold" size="20.0" />
</font>
</Label>
<Label layoutX="10.0" layoutY="27.0" text="Address" textFill="#a4450a">
<font>
<Font name="Georgia Bold" size="20.0" />
</font>
</Label>
</children>
</VBox>
<VBox layoutX="220.0" layoutY="79.0" prefHeight="150.0" prefWidth="223.0" spacing="25.0">
<children>
<TextField fx:id="txt_name" />
<TextField fx:id="txt_phno" layoutX="10.0" layoutY="10.0" />
<TextField fx:id="txt_add" layoutX="10.0" layoutY="35.0" />
</children>
</VBox>
<VBox layoutX="559.0" layoutY="56.0" prefHeight="160.0" prefWidth="156.0" spacing="25.0">
<children>
<Button fx:id="btn_save" mnemonicParsing="false" prefHeight="44.0" prefWidth="105.0"
text="Save" textFill="#2d8d07">
<font>
<Font name="Impact" size="22.0" />
</font>
</Button>
<Button fx:id="btn_update" layoutX="10.0" layoutY="10.0" mnemonicParsing="false"
prefHeight="44.0" prefWidth="105.0" text="Update" textFill="#0a85d7">
<font>
<Font name="Impact" size="24.0" />
</font>
</Button>
<Button fx:id="btn_del" layoutX="10.0" layoutY="35.0" mnemonicParsing="false"
prefHeight="44.0" prefWidth="105.0" text="Delete" textFill="#c91c1c">
<font>
<Font name="Impact" size="23.0" />
</font>
</Button>
</children>
</VBox>
<Label layoutX="212.0" layoutY="6.0" prefHeight="34.0" prefWidth="307.0" text="
Customer Details" textFill="#2e66ae">
<font>
<Font name="Impact" size="30.0" />
</font>
</Label>
</children>
</AnchorPane>
This is CustController class:
package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
public class CustController implements Initializable {
#FXML
private TableView<Customer> tbl_cust;
#FXML
private TableColumn<Customer, String> tcol_name;
#FXML
private TableColumn<Customer, Integer> tcol_phno;
#FXML
private TableColumn<Customer, String> tcol_add;
#FXML
private TextField txt_name;
#FXML
private TextField txt_phno;
#FXML
private TextField txt_add;
#FXML
private Button btn_save;
#FXML
private Button btn_update;
#FXML
private Button btn_del;
private String query, cname, cphno, cadd;
DataAccessObj dao;
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
dao = new DataAccessObj();
btn_save.setOnAction(e->{
insertNewCustomer();
});
refreshTable();
}
private void initTable() {
tcol_name.setCellValueFactory(cell->cell.getValue().getpname());
tcol_phno.setCellValueFactory(cell->cell.getValue().getpphno().asObject());
tcol_add.setCellValueFactory(cell->cell.getValue().getpaddress());
}
private void refreshTable() {
initTable();
query = "select a.Name, a.Phno, a.Address from customer ordered by a.Name";
tbl_cust.setItems(dao.getCustomerData(query));
}
private void insertNewCustomer() {
cname = txt_name.getText();
cphno = txt_phno.getText();
cadd = txt_add.getText();
query = "insert into customer values('"+cname+"', '"+cphno+"', '"+cadd+"');";
dao.savedata(query);
txt_name.setText("");
txt_phno.setText("");
txt_add.setText("");
refreshTable();
}
}
This is DataAccessObject class:
package application;
import java.sql.Connection;
import java.sql.PreparedStatement;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.sql.ResultSet;
public class DataAccessObj {
private DBConnection database = new DBConnection();
private ResultSet rs;
private PreparedStatement ps;
private Connection connect;
public DataAccessObj() {
}
public void savedata(String query) {
try {
connect = database.getConnection();
ps = connect.prepareStatement(query);
ps.executeUpdate();
}catch(Exception e) {
e.printStackTrace();
}finally {
database.close(connect, ps, null);
}
}
public ObservableList<Customer> getCustomerData(String query){
ObservableList list = FXCollections.observableArrayList();
try {
connect = database.getConnection();
ps = connect.prepareStatement(query);
rs = ps.executeQuery();
while(rs.next()) {
list.add(new Customer(rs.getString(1), rs.getInt(2), rs.getString(3)));
}
}catch(Exception e) {
e.printStackTrace();
}
return list;
}
}
I am trying to get customer details from database. Database is connected to the javafx and it stores data from javafx but doesn't show data in javafx tableview.
Related
This is the error.
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml#19-ea/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1857)
at javafx.fxml#19-ea/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1724)
at javafx.base#19-ea/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base#19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at javafx.base#19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base#19-ea/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base#19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base#19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base#19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base#19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base#19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base#19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base#19-ea/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base#19-ea/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base#19-ea/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics#19-ea/javafx.scene.Node.fireEvent(Node.java:8797)
at javafx.controls#19-ea/javafx.scene.control.Button.fire(Button.java:203)
at javafx.controls#19-ea/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208)
at javafx.controls#19-ea/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at javafx.base#19-ea/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at javafx.base#19-ea/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base#19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
at javafx.base#19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base#19-ea/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base#19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base#19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base#19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base#19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base#19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base#19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base#19-ea/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base#19-ea/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base#19-ea/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics#19-ea/javafx.scene.Scene$MouseHandler.process(Scene.java:3881)
at javafx.graphics#19-ea/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
at javafx.graphics#19-ea/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2607)
at javafx.graphics#19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
at javafx.graphics#19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics#19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
at javafx.graphics#19-ea/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
at javafx.graphics#19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
at javafx.graphics#19-ea/com.sun.glass.ui.View.handleMouseEvent(View.java:551)
at javafx.graphics#19-ea/com.sun.glass.ui.View.notifyMouse(View.java:937)
at javafx.graphics#19-ea/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics#19-ea/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:77)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at javafx.base#19-ea/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml#19-ea/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:84)
at javafx.fxml#19-ea/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1852)
... 46 more
Caused by: java.lang.NumberFormatException: For input string: ""
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:675)
at java.base/java.lang.Integer.valueOf(Integer.java:992)
at com.example.studentdatabase/com.example.studentdatabase.Register.register(Register.java:99)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
... 53 more
These are my classes and FXMLs
Main class -
package com.example.studentdatabase;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class Main extends Application {
InputStream stream = new FileInputStream("C:\\Users\\dinira francisco\\Desktop\\DDSlogo.jpg");
Image image = new Image(stream);
public Main() throws FileNotFoundException {
}
#Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("Register.fxml"));
Scene scene = new Scene(fxmlLoader.load());
stage.setTitle("Student Database 2023");
stage.getIcons().add(image);
stage.setResizable(false);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
// type here
Register class -
package com.example.studentdatabase;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Statement;
public class Register {
private int studentID=0;
private boolean hasFirstName = false;
private boolean hasLastName = false;
private boolean hasAge = false;
private boolean hasGrade = false;
#FXML
private TextField GradeTF;
#FXML
private Button ageSubmit;
#FXML
private TextField ageTF;
#FXML
private TextField firstNameTF;
#FXML
private Button firstSubmit;
#FXML
private Button gradeSubmit;
#FXML
private TextField lastNameTF;
#FXML
private Button lastsubmit;
#FXML
private Button registerButton;
#FXML
private Label warning;
public void getFirstName(ActionEvent event){
if(firstNameTF.getText().length()>=1){
hasFirstName=true;
firstNameTF.setDisable(true);
}
}
public void getLastName(ActionEvent event){
if(lastNameTF.getText().length()>=1){
hasLastName=true;
lastNameTF.setDisable(true);
}
}
public void getAge(ActionEvent event){
if(ageTF.getText().length()>=1){
hasAge=true;
ageTF.setDisable(true);
}
}
public void getGrade(ActionEvent event){
if(GradeTF.getText().length()>=1){
hasGrade=true;
GradeTF.setDisable(true);
}
}
public void register(ActionEvent event){
if(hasFirstName && hasLastName && hasAge && hasGrade){
studentID++;
warning.setText("Registration Completed!");
warning.setVisible(true);
firstNameTF.setText("");
lastNameTF.setText("");
ageTF.setText("");
GradeTF.setText("");
firstNameTF.setDisable(false);
lastNameTF.setDisable(false);
ageTF.setDisable(false);
GradeTF.setDisable(false);
hasFirstName=false;
hasLastName = false;
hasAge = false;
hasGrade = false;
DatabaseConnection databaseConnection = new DatabaseConnection();
Connection connection = databaseConnection.getConnection();
String registerString = "INSERT INTO student_data(student_id,first_name,last_name,age,grade) VALUES('"+studentID+"','"+firstNameTF.getText()+"','"+lastNameTF.getText()+"','"+Integer.valueOf(ageTF.getText())+"','"+Integer.valueOf(GradeTF.getText())+"')";
try{
Statement statement = connection.createStatement();
statement.executeUpdate(registerString);
}catch(Exception e){
e.printStackTrace();
e.getCause();
}
}else{
warning.setText("Fields are Empty!");
warning.setVisible(true);
}
}
}
Database Connection class -
package com.example.studentdatabase;
import java.sql.Connection;
import java.sql.DriverManager;
public class DatabaseConnection {
public Connection databaseLink;
public Connection getConnection(){
String databaseName = "student_db";
String databaseUser = "root";
String databasePassword = "***";
String url = "jdbc:mysql://localhost/"+databaseName;
try{
Class.forName("com.mysql.cj.jdbc.Driver");
databaseLink = DriverManager.getConnection(url,databaseUser,databasePassword);
}catch (Exception e){
e.printStackTrace();
e.getCause();
}
return databaseLink;
}
}
and FXML -
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="443.0" prefWidth="458.0" style="-fx-background-color: #f0db24;" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.studentdatabase.Register">
<children>
<Label layoutX="161.0" layoutY="25.0" text="Student Database">
<font>
<Font size="17.0" />
</font>
</Label>
<Label layoutX="95.0" layoutY="52.0" text="Sinhala Oratory & Debating Society">
<font>
<Font size="17.0" />
</font>
</Label>
<Label layoutX="106.0" layoutY="78.0" text="D.S.Senanayake College - Col. 08">
<font>
<Font size="17.0" />
</font>
</Label>
<Label layoutX="161.0" layoutY="125.0" text="Registration Form">
<font>
<Font size="17.0" />
</font>
</Label>
<Label layoutX="66.0" layoutY="177.0" text="First Name ">
<font>
<Font size="15.0" />
</font>
</Label>
<Label layoutX="67.0" layoutY="226.0" text="Last Name ">
<font>
<Font size="15.0" />
</font>
</Label>
<Label layoutX="66.0" layoutY="269.0" text="Age">
<font>
<Font size="15.0" />
</font>
</Label>
<Label layoutX="66.0" layoutY="315.0" text="Grade">
<font>
<Font size="15.0" />
</font>
</Label>
<TextField fx:id="firstNameTF" layoutX="154.0" layoutY="175.0" />
<TextField fx:id="lastNameTF" layoutX="154.0" layoutY="224.0" />
<TextField fx:id="ageTF" layoutX="154.0" layoutY="267.0" />
<TextField fx:id="GradeTF" layoutX="154.0" layoutY="313.0" />
<Button fx:id="firstSubmit" layoutX="318.0" layoutY="175.0" mnemonicParsing="false" onAction="#getFirstName" text="Submit" />
<Button fx:id="gradeSubmit" layoutX="318.0" layoutY="313.0" mnemonicParsing="false" onAction="#getGrade" text="Submit" />
<Button fx:id="ageSubmit" layoutX="318.0" layoutY="267.0" mnemonicParsing="false" onAction="#getAge" text="Submit" />
<Button fx:id="lastsubmit" layoutX="318.0" layoutY="224.0" mnemonicParsing="false" onAction="#getLastName" text="Submit" />
<Button fx:id="registerButton" layoutX="192.0" layoutY="358.0" mnemonicParsing="false" onAction="#register" text="Register" />
<Label fx:id="warning" layoutX="175.0" layoutY="399.0" text="Fields are Empty!" textFill="#f70909" visible="false" />
</children>
</AnchorPane>
I searched some solutions in stackoverflow but couldn't solve the issue.
First some notes about your code.
Class DatabaseConnection
Class.forName("com.mysql.cj.jdbc.Driver");
This is no longer needed.
Because of the catch block in method getConnection, the method may return null which means that other methods, that call method getConnection, need to check if null was returned. In my opinion, better to declare that method getConnection throws SQLException. Also, class DatabaseConnection should probably be a singleton which means that method getConnection should be a static method.
Class Register
I think that you should use PreparedStatement rather than Statement.
You should also use try-with-resources
I don't see the need for this line:
e.getCause();
Method printStackTrace will also print the cause – if there is one.
Rather than using variables hasFirstName, hasLastName, hasAge and hasGrade, use bindings which you can set up in method initialize since class Register is your FXML controller. Then you don't need a Submit button for every TextField in your registration form. Data entry forms usually don't require submitting each field individually.
Rather than explicitly setting sizes and locations for each Node, better to use layouts.
Regarding the top Label, you can use a single Label rather than a separate Label for each line of text. You can insert line breaks and you can center align the text.
Now to your problem. You need to "clear" the registration form after you have updated the database (and not before, as you are currently doing in your code).
Here is my version of your application.
Class DatabaseConnection
package com.example.studentdatabase;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DatabaseConnection {
private static Connection databaseLink;
public static Connection getConnection() throws SQLException {
if (databaseLink == null) {
String databaseName = "student_db";
String databaseUser = "root";
String databasePassword = "***";
String url = "jdbc:mysql://localhost/" + databaseName;
databaseLink = DriverManager.getConnection(url, databaseUser, databasePassword);
}
return databaseLink;
}
}
Class Register
Note that it uses text blocks. It also uses [JavaFX] alerts.
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class Register {
private int studentID = 0;
#FXML
private TextField gradeTF;
#FXML
private TextField ageTF;
#FXML
private TextField firstNameTF;
#FXML
private TextField lastNameTF;
#FXML
private Button registerButton;
public void register(ActionEvent event) {
String registerString = """
INSERT INTO student_data (student_id, first_name, last_name, age, grade)
VALUES (?, ?, ?, ?, ?)
""";
try (Connection connection = DatabaseConnection.getConnection();
PreparedStatement statement = connection.prepareStatement(registerString)) {
statement.setInt(1, ++studentID);
statement.setString(2, firstNameTF.getText());
statement.setString(3, lastNameTF.getText());
statement.setInt(4, Integer.valueOf(ageTF.getText()));
statement.setInt(5, Integer.valueOf(gradeTF.getText()));
statement.executeUpdate();
Alert alert = new Alert(AlertType.INFORMATION);
alert.setContentText("Registration Completed!");
alert.setHeaderText(null);
alert.showAndWait();
firstNameTF.setText("");
lastNameTF.setText("");
ageTF.setText("");
gradeTF.setText("");
firstNameTF.setDisable(false);
lastNameTF.setDisable(false);
ageTF.setDisable(false);
gradeTF.setDisable(false);
}
catch (Exception e) {
e.printStackTrace();
}
}
#FXML
private void initialize() {
registerButton.disableProperty().bind(firstNameTF.textProperty().isEmpty()
.or(lastNameTF.textProperty().isEmpty())
.or(ageTF.textProperty().isEmpty())
.or(gradeTF.textProperty().isEmpty()));
}
}
FXML file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.text.Font?>
<BorderPane style="-fx-background-color: #f0db24;" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.studentdatabase.Register">
<top>
<Label text="Student Database
Sinhala Oratory & Debating Society
D.S.Senanayake College - Col. 08
Registration Form">
<font>
<Font size="17.0" />
</font>
<textAlignment>CENTER</textAlignment>
</Label>
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</BorderPane.margin>
</top>
<center>
<GridPane hgap="10.0" vgap="10.0">
<alignment>CENTER</alignment>
<children>
<Label text="First Name">
<font>
<Font size="15.0" />
</font>
<GridPane.rowIndex>0</GridPane.rowIndex>
<GridPane.columnIndex>0</GridPane.columnIndex>
</Label>
<TextField fx:id="firstNameTF">
<GridPane.rowIndex>0</GridPane.rowIndex>
<GridPane.columnIndex>1</GridPane.columnIndex>
</TextField>
<Label text="Last Name">
<font>
<Font size="15.0" />
</font>
<GridPane.rowIndex>1</GridPane.rowIndex>
<GridPane.columnIndex>0</GridPane.columnIndex>
</Label>
<TextField fx:id="lastNameTF">
<GridPane.rowIndex>1</GridPane.rowIndex>
<GridPane.columnIndex>1</GridPane.columnIndex>
</TextField>
<Label text="Age">
<font>
<Font size="15.0" />
</font>
<GridPane.rowIndex>2</GridPane.rowIndex>
<GridPane.columnIndex>0</GridPane.columnIndex>
</Label>
<TextField fx:id="ageTF">
<GridPane.rowIndex>2</GridPane.rowIndex>
<GridPane.columnIndex>1</GridPane.columnIndex>
</TextField>
<Label text="Grade">
<font>
<Font size="15.0" />
</font>
<GridPane.rowIndex>3</GridPane.rowIndex>
<GridPane.columnIndex>0</GridPane.columnIndex>
</Label>
<TextField fx:id="gradeTF">
<GridPane.rowIndex>3</GridPane.rowIndex>
<GridPane.columnIndex>1</GridPane.columnIndex>
</TextField>
</children>
</GridPane>
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</BorderPane.margin>
</center>
<bottom>
<Button fx:id="registerButton" mnemonicParsing="false" onAction="#register" text="Register" />
<BorderPane.alignment>CENTER</BorderPane.alignment>
<BorderPane.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</BorderPane.margin>
</bottom>
</BorderPane>
Class Main was not changed and so is omitted.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.chart.BarChart?>
<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="800.0" styleClass="mainFxmlClass" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Views.MonthlyHoursController">
<children>
<VBox alignment="CENTER" layoutX="121.0" layoutY="121.0" prefHeight="600.0" prefWidth="800.0" spacing="20.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Label styleClass="header" text="Monthly Hours" />
<HBox prefHeight="292.0" prefWidth="760.0">
<children>
<BarChart fx:id="barChart" prefHeight="292.0" prefWidth="755.0">
<xAxis>
<CategoryAxis fx:id="months" side="BOTTOM" />
</xAxis>
<yAxis>
<NumberAxis fx:id="hoursWorked" side="LEFT" />
</yAxis>
</BarChart>
</children>
</HBox>
<HBox alignment="BOTTOM_RIGHT" prefHeight="100.0" prefWidth="200.0" spacing="20.0">
<children>
<Button mnemonicParsing="false" text=" Back" />
</children>
</HBox>
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
</children>
</AnchorPane>
Above is my fxml file for the bar chart
package Views;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDate;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
public class MonthlyHoursController implements Initializable {
#FXML private BarChart<?, ?> barChart;
#FXML private CategoryAxis months;
#FXML private NumberAxis hoursWorked;
private XYChart.Series currentYearSeries, previousYearSeries;
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
currentYearSeries = new XYChart.Series<>();
previousYearSeries = new XYChart.Series<>();
// barChart.setTitle("Hours Worked");
months.setLabel("Months");
hoursWorked.setLabel("Hours Worked");
currentYearSeries.setName(Integer.toString(LocalDate.now().getYear()));
previousYearSeries.setName(Integer.toString(LocalDate.now().getYear()-1));
try {
populateSeriesFromDB();
} catch (SQLException e) {
e.printStackTrace();
}
barChart.getData().addAll(previousYearSeries);
barChart.getData().addAll(currentYearSeries);
}
private void populateSeriesFromDB() throws SQLException {
Connection conn = null;
Statement statement = null;
ResultSet resultSet = null;
try{
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bakery?useSSL=false", "root",
"a3756421");
statement = conn.createStatement();
String sql = " Select Year(dateworked), monthname(dateworked), sum(hoursworked)" +
"From hoursworked" +
"Group by year(dateworked), month(dateworked)" +
"Order by Year(dateworked), month(dateworked);";
resultSet = statement.executeQuery(sql);
while (resultSet.next()){
if(resultSet.getInt(1)==LocalDate.now().getYear())
currentYearSeries.getData().add(new XYChart.Data(resultSet.getString(2), resultSet.getString(3)));
else if(resultSet.getInt(1)==LocalDate.now().getYear()-1)
previousYearSeries.getData().add(new XYChart.Data(resultSet.getString(2), resultSet.getString(3)));
}
}
catch (SQLException e){
System.err.println(e.getMessage());
}
finally{
if(conn !=null)
conn.close();
if (statement != null)
statement.close();
if(resultSet != null)
resultSet.close();
}
}
}
this is the controller for the fxml.
If I perform
From hoursworked
Group by Year(dateworked), month(dateworked)
Order by Year(dateworked), month(dateworked);
in workbench, it gives below:
However, when I open the fxml file, it doesnt show anything in the bar chart.
Is there something wrong with my javafx or mysql syntax?
The program itself does not give any error when it's run.
I have no idea where to even start fixing this.
I have a report in JasperReports, it works fine. However, i'm passing just one parameter of type cliente to the report, and what i do want now is to pass more than one. The page is like in the picture bellow, a basic idea was to have a button (maybe) that would send the content of <p:selectOneMenu that is of the type cliente each time its clicked to the map of parameters, than it would be sent to the report. I wasn't able to do that yet, so i'm asking for a help.
Bean:
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import org.hibernate.Session;
import com.rodrigo.controleacidentes.model.Cliente;
import com.rodrigo.controleacidentes.model.StatusEntrada;
import com.rodrigo.controleacidentes.util.jsf.FacesUtil;
import com.rodrigo.controleacidentes.util.report.ExecutorRelatorioPdf;
import com.rodrigo.controleacidentes.util.report.ExecutorRelatorioXls;
#Named
#RequestScoped
public class RelatorioEntradasBean implements Serializable {
private static final long serialVersionUID = 1L;
private Date dataInicio;
private Date dataFim;
private Cliente cliente;
private StatusEntrada statusEntrada;
public StatusEntrada getStatusEntrada() {
return statusEntrada;
}
public void setStatusEntrada(StatusEntrada statusEntrada) {
this.statusEntrada = statusEntrada;
}
public void teste(StatusEntrada st) {
// StatusEntrada entrada = StatusEntrada.valueOf(st);
System.out.println("TESTE: " + st);
}
#Inject
private FacesContext facesContext;
#Inject
private HttpServletResponse response;
#Inject
private EntityManager manager;
public void emitirXls() {
Map<String, Object> parametros = new HashMap<>();
parametros.put("data_inicio", this.dataInicio);
parametros.put("data_fim", this.dataFim);
if (cliente != null) {
System.out.println("TESTE: " + cliente.getNome());
parametros.put("nome_cliente", cliente.getNome());
}
if (statusEntrada != null) {
System.out.println("TESTE :" + statusEntrada.getDescricao());
parametros.put("status_entrada", statusEntrada.getDescricao());
}
ExecutorRelatorioXls executor = new ExecutorRelatorioXls("/relatorios/RelatorioEntradasNome.jasper",
this.response, parametros, "Relatório Entradas.xls");
Session session = manager.unwrap(Session.class);
session.doWork(executor);
if (executor.isRelatorioGerado()) {
facesContext.responseComplete();
} else {
FacesUtil.addErrorMessage("A execução do relatório não retornou dados.");
}
}
public void emitirPdf() {
Map<String, Object> parametros = new HashMap<>();
parametros.put("data_inicio", this.dataInicio);
parametros.put("data_fim", this.dataFim);
parametros.put("nome_cliente", this.cliente);
ExecutorRelatorioPdf executor = new ExecutorRelatorioPdf("/relatorios/RelatorioEntradasNome.jasper",
this.response, parametros, "Relatório Entradas.pdf");
Session session = manager.unwrap(Session.class);
session.doWork(executor);
if (executor.isRelatorioGerado()) {
facesContext.responseComplete();
} else {
FacesUtil.addErrorMessage("A execução do relatório não retornou dados.");
}
}
#NotNull
public Date getDataInicio() {
return dataInicio;
}
public void setDataInicio(Date dataInicio) {
this.dataInicio = dataInicio;
}
#NotNull
public Date getDataFim() {
return dataFim;
}
public void setDataFim(Date dataFim) {
this.dataFim = dataFim;
}
#NotNull
public Cliente getCliente() {
return cliente;
}
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
}
Executor:
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.jdbc.Work;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
public class ExecutorRelatorioXls implements Work {
private String caminhoRelatorio;
private HttpServletResponse response;
private Map<String, Object> parametros;
private String nomeArquivoSaida;
private boolean relatorioGerado;
public ExecutorRelatorioXls(String caminhoRelatorio, HttpServletResponse response, Map<String, Object> parametros,
String nomeArquivoSaida) {
this.caminhoRelatorio = caminhoRelatorio;
this.response = response;
this.parametros = parametros;
this.nomeArquivoSaida = nomeArquivoSaida;
this.parametros.put(JRParameter.REPORT_LOCALE, new Locale("pt", "BR"));
}
#Override
public void execute(Connection connection) throws SQLException {
try {
InputStream relatorioStream = this.getClass().getResourceAsStream(this.caminhoRelatorio);
JasperPrint print = JasperFillManager.fillReport(relatorioStream, this.parametros, connection);
this.relatorioGerado = print.getPages().size() > 0;
if (this.relatorioGerado) {
JRXlsExporter exportador = new JRXlsExporter();
exportador.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, response.getOutputStream());
exportador.setParameter(JRXlsExporterParameter.JASPER_PRINT, print);
exportador.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
exportador.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
exportador.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
response.setHeader("Content-Transfer-Encoding", "Cp1256");
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=\"" + this.nomeArquivoSaida + "\"");
exportador.exportReport();
}
} catch (Exception e) {
throw new SQLException("Erro ao executar relatório " + this.caminhoRelatorio, e);
}
}
public boolean isRelatorioGerado() {
return relatorioGerado;
}
}
Query in the report:
SELECT DISTINCT
ocorrencia.`id` AS ocorrencia_id,
ocorrencia.`descricao` AS ocorrencia_descricao,
ocorrencia.`condicao_tempo` AS ocorrencia_condicao_tempo,
ocorrencia.`data_ocorrencia` AS ocorrencia_data_ocorrencia,
ocorrencia.`periodo_ocorrencia` AS ocorrencia_periodo_ocorrencia,
ocorrencia.`condutor_id` AS ocorrencia_condutor_id,
condutor.`id` AS condutor_id,
condutor.`codigo` AS condutor_codigo,
condutor.`nome` AS condutor_nome,
entrada_acidente.`id` AS entrada_acidente_id,
entrada_acidente.`data_criacao` AS entrada_acidente_data_criacao,
entrada_acidente.`ocorrencia_id` AS entrada_acidente_ocorrencia_id,
entrada_acidente.`valor_unitario` AS entrada_acidente_valor_unitario,
cliente.`id` AS cliente_id,
cliente.`nome` AS cliente_nome,
entrada_acidente.`status` AS entrada_acidente_status
FROM
`condutor` condutor INNER JOIN `ocorrencia` ocorrencia ON condutor.`id` = ocorrencia.`condutor_id`
INNER JOIN `entrada_acidente` entrada_acidente ON ocorrencia.`id` = entrada_acidente.`ocorrencia_id`
INNER JOIN `cliente` cliente ON entrada_acidente.`cliente_id` = cliente.`id`
WHERE
entrada_acidente.`data_criacao` BETWEEN $P{data_inicio} AND $P{data_fim}
AND cliente.`nome` = $P{nome_cliente}
AND entrada_acidente.`status` = $P{status_entrada}
xhtml:
<ui:composition template="/WEB-INF/template/LayoutPadrao.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:define name="titulo">Relatório de entradas emitidas</ui:define>
<ui:define name="corpo">
<h:form id="frm">
<h1>Relatório de entradas emitidas</h1>
<p:messages autoUpdate="true" closable="true" />
<p:toolbar style="margin-top: 20px">
<p:toolbarGroup>
<p:commandButton value="EmitirPdf"
action="#{relatorioEntradasBean.emitirPdf}" ajax="false" />
<p:commandButton value="EmitirXls"
action="#{relatorioEntradasBean.emitirXls}" ajax="false" />
</p:toolbarGroup>
</p:toolbar>
<p:panelGrid columns="7" id="painel"
style="width: 100%; margin-top: 20px" columnClasses="rotulo, campo">
<p:outputLabel value="Data de criação" />
<h:panelGroup>
<p:calendar value="#{relatorioEntradasBean.dataInicio}"
label="Data inicial" pattern="dd/MM/yyyy" size="8" />
<p:spacer width="8" />
<h:outputText value="a" />
<p:spacer width="8" />
<p:calendar value="#{relatorioEntradasBean.dataFim}"
label="Data final" pattern="dd/MM/yyyy" size="8" />
</h:panelGroup>
<h:panelGroup>
<p:outputLabel value="Cliente" for="cliente" />
<p:autoComplete id="cliente" size="40" dropdown="true"
value="#{relatorioEntradasBean.cliente}"
completeMethod="#{cadastroEntradaBean.completarCliente}"
var="cliente" itemLabel="#{cliente.nome}" itemValue="#{cliente}"
forceSelection="true" />
</h:panelGroup>
<p:outputLabel value="Status" />
<h:panelGroup>
<p:selectOneMenu id="statusEntrada"
value="#{relatorioEntradasBean.statusEntrada}">
<f:selectItem itemLabel="Selecione" />
<f:selectItems value="#{enumProviderStatus.statusEntradas}"
var="statusEntrada" itemValue="#{statusEntrada}"
itemLabel="#{statusEntrada.descricao}" />
</p:selectOneMenu>
</h:panelGroup>
</p:panelGrid>
</h:form>
</ui:define>
</ui:composition>
I need to have TableView CELL should display text in multi line in single cell with multi color.
In CELL I am displaying Multiline text using "\n" currently. But I am not able to set color for each line in the same cell,
for example text in the CELL is : Charlotte , 403 St. Tryon Street then I want In Single cell, Charlotte as first line and 403 St. Tryon Street as sencond line with Charlotte as RED color and remaining text on 2nd line as Green color.
You can use a cellFactory to customize the way the content is displayed. Assuming the values for the column are Strings like "Charlotte\n403 St. Tryon Street" and "Tony Stark\n10880 Malibu Point\n90265"
It could be done like this:
column.setCellFactory(tv -> new TableCell<MyItemType, String>() {
private final VBox lines;
{
lines = new VBox();
lines.getStyleClass().add("address");
setGraphic(lines);
}
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
lines.getChildren().clear();
if (!empty && item != null) {
int lineNo = 1;
for (String line : item.split("\n")) {
Text text = new Text(line);
text.getStyleClass().add("line-" + (lineNo++));
lines.getChildren().add(text);
}
}
}
});
CSS stylesheet
.address > * {
-fx-fill: green;
}
.address > .line-1 {
-fx-fill: red;
}
Note that this uses CSS to style the lines, but you could also assign the color in the updateItem method directly...
You can use a custom cell factory in this case, here is an example:
I've created an FXML document that contains a TableView holding two TableColumns, one for the fullname and the second for the address of a Person instance.
I've then set the cellFactory as follows:
addressCol.setCellFactory(column->{
return new TableCell<Person, String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(item==null || empty) {
setGraphic(null);
} else {
VBox vbox = new VBox();
List<String> textList = Arrays.asList(item.split("\n"));
String[] colors = {"#3E50B4", "#FF3F80", "#727272"};
int colorCount = colors.length;
for(int i=0;i<textList.size();i++) {
Label lbl = new Label(textList.get(i));
lbl.setStyle("-fx-text-fill: "+colors[i%colorCount]);
vbox.getChildren().add(lbl);
}
setGraphic(vbox);
}
}
};
});
Now this is just an example where I've used a VBox containing a bunch of Label instances (one for each line), and I've hard coded the colors, you can use whatever you like, for example, you can try a TextFlow with Text nodes and you can also use CSS Style classes.
Here is the full example code:
TableViewExample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<VBox alignment="CENTER" spacing="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<children>
<Label text="Colored Lines of Text in a Table Cell Example">
<font>
<Font size="16.0" />
</font>
</Label>
<TableView fx:id="personTable" prefHeight="200.0" prefWidth="200.0">
<columns>
<TableColumn fx:id="fullnameCol" prefWidth="75.0" text="Full Name" />
<TableColumn fx:id="addressCol" prefWidth="75.0" text="Address" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</children>
</VBox>
Person.java
public class Person {
private String fullname, address;
public Person() {}
public Person(String fullname, String address) {
this.fullname = fullname;
this.address = address;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
MainApp.java
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MainApp extends Application implements Initializable {
#FXML private TableView<Person> personTable;
#FXML private TableColumn<Person, String> fullnameCol, addressCol;
ObservableList<Person> persons = FXCollections.observableArrayList();
public static void main(String [] args) {
launch(args);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
Person p1 = new Person("John Doe", "Charlotte ,\n403 St. Tryon Street");
Person p2 = new Person("Riyad Mahrez", "xxxxx, \n007 St.YYYY");
persons.addAll(p1, p2);
fullnameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("fullname"));
addressCol.setCellValueFactory(new PropertyValueFactory<Person, String>("address"));
addressCol.setCellFactory(column->{
return new TableCell<Person, String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(item==null || empty) {
setGraphic(null);
} else {
VBox vbox = new VBox();
List<String> textList = Arrays.asList(item.split("\n"));
String[] colors = {"#3E50B4", "#FF3F80", "#727272"};
int colorCount = colors.length;
for(int i=0;i<textList.size();i++) {
Label lbl = new Label(textList.get(i));
lbl.setStyle("-fx-text-fill: "+colors[i%colorCount]);
vbox.getChildren().add(lbl);
}
setGraphic(vbox);
}
}
};
});
personTable.setItems(persons);
}
#Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("TableViewExample.fxml"));
loader.setController(this);
Parent parent = loader.load();
Scene scene = new Scene(parent);
primaryStage.setScene(scene);
primaryStage.show();
}
}
I hope this helps...
How can i create a secondary y axis on primefaces 3.4?
i already read the primefaces manual e googled out there
Google tells that y2axis (from jqplot) is the way
but primefaces manual doesn't mention y2axis at all
my class
package br.com.inmetrics.managedbean;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.LineChartSeries;
import javax.faces.event.ComponentSystemEvent;
import br.com.inmetrics.entity.Grafico;
import javax.faces.event.AbortProcessingException;
import br.com.inmetrics.dao.SistemaDAO;
#ManagedBean(name = "chartMB")
#SessionScoped
public class ChartManagedBean implements Serializable {
private static final long serialVersionUID = 1L;
private SistemaDAO apoioDao = new SistemaDAO();
private List<Grafico> graficos = new ArrayList<Grafico>();
private CartesianChartModel categoryModel;
private CartesianChartModel linearModel;
private String sistema;
private String hostname;
private String metrica;
private String alinhamento;
private String funcao;
private int maximo;
public ChartManagedBean() {
}
public CartesianChartModel getCategoryModel() {
return categoryModel;
}
public CartesianChartModel getLinearModel() {
return linearModel;
}
private void createLinearModel() {
try {
graficos = apoioDao.getGrafico(hostname, metrica);
} catch (Exception ex) {
ex.printStackTrace();
}
linearModel = new CartesianChartModel();
LineChartSeries series1 = new LineChartSeries();
this.alinhamento = metrica.equalsIgnoreCase("GBL_LOADAVG") ? "ne" : "e";
this.funcao = metrica.equalsIgnoreCase("GBL_LOADAVG") ? "ext2" : "ext1";
this.maximo = metrica.equalsIgnoreCase("GBL_LOADAVG") ? 1 : 100;
series1.setLabel(metrica);
for (Grafico s : graficos) {
series1.set(s.getData(), s.getValor());
}
LineChartSeries series2 = new LineChartSeries();
series2.setLabel("Threshold");
series2.setMarkerStyle("filledSquare");
for (Grafico t : graficos) {
series2.set(t.getData(), metrica.equalsIgnoreCase("GBL_LOADAVG") ? 0.48 : 80);
}
//teste
LineChartSeries series3 = new LineChartSeries();
series3.setLabel("Threshold");
series3.setMarkerStyle("filledSquare");
for (Grafico t : graficos) {
series3.set(t.getData(), metrica.equalsIgnoreCase("GBL_LOADAVG") ? 0.48 : 90);
}
linearModel.addSeries(series1);
linearModel.addSeries(series2);
//teste
linearModel.addSeries(series3);
}
public String getSistema() {
return sistema;
}
public void setSistema(String sistema) {
this.sistema = sistema;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public String getMetrica() {
return metrica;
}
public void setMetrica(String metrica) {
this.metrica = metrica;
}
public void push(ComponentSystemEvent evt) throws AbortProcessingException {
createLinearModel();
}
public String getAlinhamento() {
return alinhamento;
}
public void setAlinhamento(String alinhamento) {
this.alinhamento = alinhamento;
}
public int getMaximo() {
return maximo;
}
public void setMaximo(int maximo) {
this.maximo = maximo;
}
public String getFuncao() {
return funcao;
}
public void setFuncao(String funcao) {
this.funcao = funcao;
}
}
my xhtml:
<h:head>
<link rel="shortcut icon" href="images/ico.ico" />
<title>Capacity - Dashboard</title>
<link rel="stylesheet" type="text/css" href="styles.css" />
</h:head>
<h:body>
<h:form>
<script type="text/javascript">
function ext1() {
this.cfg.axes.yaxis.tickOptions = {
formatString : '%d\%'
};
}
function ext2() {
this.cfg.axes.yaxis.tickOptions = {
formatString : '%.2f'
};
}
</script>
<div id="externa_corpo">
<div id="corpo">
<div id="logo">
<img src="images/pt/logo.png" width="200" height="74" />
</div>
<!--logo-->
<div id="titulo-book">
Dashboard <br />
</div>
<div id="logo-cliente">
<img src="images/logoTIM.jpg" width="122" height="53" />
</div>
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
<p:lineChart id="linear" value="#{chartMB.linearModel}"
legendPosition="#{chartMB.alinhamento}"
title="#{chartMB.hostname} - P90" minY="0" maxY="#{chartMB.maximo}"
style="height:450px" animate="true" xaxisAngle="270"
seriesColors="FFFF00, FF0000" extender="#{chartMB.funcao}" showMarkers="true"
zoom="false" />
<f:metadata>
<f:viewParam name="sistema" value="#{chartMB.sistema}" />
<f:viewParam name="hostname" value="#{chartMB.hostname}" />
<f:viewParam name="metrica" value="#{chartMB.metrica}" />
<f:event type="preRenderView" listener="#{chartMB.push}" />
</f:metadata>
</div>
</div>
</h:form>
</h:body>
</html>
Kind Regards and Best Wishes,
Geraldo Netto