How to change the cursor type when a TableView class was added to a Swing application? - cursor

We can resize column width by dragging the column divider in the table header. This is a built-in feature of the TableView class.
Normally, the cursor will become to east-resize (or west-resize) type with positioning the cursor just to the right of a column header.
However, I found that the cursor is remaining the default type at the same position if I integrate JavaFX into Swing Application. That is adding the TableView to a Scene, and then adding this Scene to a JFXPanel, finally, adding this JFXPanel to the JFrame.
The sample codes are listing below:
public class Run extends JFrame {
Run() {
setSize(600, 450);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initComponents();
}
private void initComponents() {
final JFXPanel fxPanel = new JFXPanel();
this.getContentPane().add(fxPanel);
Platform.runLater(new Runnable() {
#Override
public void run() {
initFX(fxPanel);
}
});
}
private void initFX(JFXPanel fxPanel) {
Scene scene = null;
try {
scene = FXMLLoader.load(
new File("res/fxml_example.fxml").toURI().toURL()
);
} catch (Exception ex) {
ex.printStackTrace();
}
fxPanel.setScene(scene);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Run().setVisible(true);
}
});
}
}
fxml_example.fxml:
<?import javafx.scene.Scene?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<Scene xmlns:fx="http://javafx.com/fxml">
<TableView fx:id="tableView"
editable="true">
<columns>
<TableColumn text="COL1">
</TableColumn>
<TableColumn text="COL2">
</TableColumn>
<TableColumn text="COL3">
</TableColumn>
<TableColumn text="COL4">
</TableColumn>
<TableColumn text="COL5">
</TableColumn>
</columns>
</TableView>
</Scene>
So, are there anyone can advise how to fix these codes; make the cursor can change to east-resize (or west-resize) type when this TableView class was added to a Swing application?

Related

Working checkboxes in JavaFX table (CheckBoxTableCell)

(This is similar to a homework question.)
I recently made an example UI in Scenebuilder for something I later had to program with Java Swing. That more or less worked. Now it is my task, not for the actual development of the program, but for learning something in my job training, to make a similar UI with Scenebuilder, but this time an actually working one. The specifications are:
It's a window with a table in it.
At least two of the columns have radio boxes in them that look like checkboxes or checkboxes that act like radio boxes (because the company has weird standards).
It uses FXML files made with Scenebuilder for the layout.
Making the check boxes act as radio boxes should be easy, if I could just enable the editing. I found a lot of examples that do almost what I want, but are still all not really applicable to my situation. Here are some of them:
I started with this video and almost exactly copied the code to first have a working example. Then I adjusted it to my needs until I only had the check boxes to do (first working prototype had Booleans instead).
Then I took part of the full code of this answer to add the check boxes. That worked, but they don't react to clicks.
This, this and this seems to only apply to text fields, not checkboxes.
I then used the two lambda expressions from the second code block in this answer (actually I used the variant in the first answer and manually resolved some errors until suddenly Eclipse automatically converted it to lambda expressions). I also added the public ObservableValue<Boolean> getCompleted() method, Eclipse suggested some magic and then I had what you can see in the corresponding code below (without the console print).
I also added a listener to the boolean property, like this site (archive) apparently does (I think), but that doesn't seem like it helped much.
Here is a picture of how the dialog looks now, I still can't use the check boxes:
My question: How can I make it so that the check boxes react to clicks? React can mean outputting something on the console, I don't need a given code that makes it automatically disable the other checkbox, I want to figure that part out myself.
My code:
src.controller.MainController.java
package controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import view.Table;
public class MainController implements Initializable{
#FXML TableView<Table> tableID;
#FXML TableColumn<Table,String> iFirstName;
#FXML TableColumn<Table,String> iLastName;
#FXML TableColumn<Table,Boolean> iMalebox;
#FXML TableColumn<Table,Boolean> iFemalebox;
#Override public void initialize(URL location,ResourceBundle resources){
iFirstName.setCellValueFactory(new PropertyValueFactory<Table,String>("rFirstName"));
iLastName.setCellValueFactory(new PropertyValueFactory<Table,String>("rLastName"));
iMalebox.setCellValueFactory(p->p.getValue().getCompleted());
iMalebox.setCellFactory(p->new CheckBoxTableCell<>());
iMalebox.setEditable(true);
// iMalebox.setCellValueFactory(p->p.getValue().getCompleted());
// iMalebox.setCellFactory(p->new CheckBoxTableCell<>());
iFemalebox.setCellValueFactory(p->p.getValue().getCompleted());
iFemalebox.setCellFactory(p->new CheckBoxTableCell<>());
// iMalebox.setCellValueFactory(new PropertyValueFactory<Table,Boolean>("rMalebox"));
// iFemalebox.setCellValueFactory(new PropertyValueFactory<Table,Boolean>("rFemalebox"));
tableID.setItems(FXCollections.observableArrayList(new Table("Horst","Meier",true,false),new Table("Anna","Becker",false,true),new Table("Karl","Schmidt",true,false)));
tableID.setEditable(true);
}
}
src.controller.MainView.java
package controller;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class MainView extends Application{
#Override public void start(Stage primaryStage){
try{
// FXMLLoader.load(MainView.class.getResource("MainController.fxml"));
AnchorPane page=(AnchorPane)FXMLLoader.load(MainView.class.getResource("MainController.fxml"));
Scene scene=new Scene(page);
primaryStage.setScene(scene);
primaryStage.setTitle("Window Title");
primaryStage.show();
}catch(Exception e){
Logger.getLogger(MainView.class.getName()).log(Level.SEVERE,null,e);
}
}
public static void main(String[] args){
Application.launch(MainView.class,(java.lang.String[])null);
}
}
src.controller.MainController.fxml
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
<children>
<TableView fx:id="tableID" prefHeight="494.0" prefWidth="798.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="iFirstName" prefWidth="75.0" text="First name" />
<TableColumn fx:id="iLastName" prefWidth="75.0" text="Last name" />
<TableColumn fx:id="iMalebox" prefWidth="75.0" text="Male" />
<TableColumn fx:id="iFemalebox" prefWidth="75.0" text="Female" />
</columns>
</TableView>
</children>
</AnchorPane>
src.view.Table.java
package view;
import javafx.beans.InvalidationListener;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
public class Table{
private SimpleStringProperty rFirstName;
private SimpleStringProperty rLastName;
private SimpleBooleanProperty rMalebox;
private SimpleBooleanProperty rFemalebox;
public Table(String sFirstName,String sLastName,Boolean sMalebox,Boolean sFemalebox){
rFirstName=new SimpleStringProperty(sFirstName);
rLastName=new SimpleStringProperty(sLastName);
rMalebox=new SimpleBooleanProperty(sMalebox);
rMalebox.addListener((ChangeListener)(observable,oldValue,newValue)->{
System.out.println("test");
System.out.println("abc");
});
rFemalebox=new SimpleBooleanProperty(sFemalebox);
}
public String getRFirstName(){
return rFirstName.get();
}
public void setRFirstName(String v){
rFirstName.set(v);
}
public String getRLastName(){
return rLastName.get();
}
public void setRLastName(String v){
rLastName.set(v);
}
public Boolean getRMalebox(){
return rMalebox.get();
}
public void setRMalebox(Boolean v){
rMalebox.set(v);
}
public Boolean getRFemalebox(){
return rFemalebox.get();
}
public void setRFemalebox(Boolean v){
rFemalebox.set(v);
}
public ObservableValue<Boolean> getCompleted(){
return new ObservableValue<Boolean>(){
#Override public void removeListener(InvalidationListener arg0){}
#Override public void addListener(InvalidationListener arg0){}
#Override public void removeListener(ChangeListener<? super Boolean> listener){}
#Override public Boolean getValue(){
return null;
}
#Override public void addListener(ChangeListener<? super Boolean> listener){
System.out.println("Test");
}
};
}
}
I found a solution. Since I changed so much (I worked on getting this stupid thing to work for almost 20 hours after asking that question), it's not really useful to enumerate all the changes I did. But here is at least a working example.
There are very few lines responsible for making the "male" and "female" boxes trigger each other's opposites (which is specific to my task), everything else is just for getting actually properly working CheckBoxTableCells. One would think that that is a really common case and there should be standard methods for that, like for "print text into the console" or "read file", but apparently not, apparently everything has to be complicated in programming with UIs.
Anyway, rant aside, here is the working code:
src.controller.MainView.java
package controller;
import java.io.*;
import javafx.application.*;
import javafx.fxml.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.stage.*;
public class MainView extends Application{
#Override public void start(Stage primaryStage) throws IOException{
primaryStage.setScene(new Scene((AnchorPane)FXMLLoader.load(MainView.class.getResource("MainController.fxml"))));
primaryStage.show();
}
public static void main(String[] args){
Application.launch(MainView.class);
}
}
src.controller.MainController.java
package controller;
import java.net.*;
import java.util.*;
import javafx.beans.value.*;
import javafx.collections.*;
import javafx.fxml.*;
import javafx.scene.control.*;
import javafx.scene.control.TableColumn.*;
import javafx.scene.control.cell.*;
import javafx.util.*;
import view.*;
public class MainController implements Initializable{
#FXML TableView<Table> tableID;
#FXML TableColumn<Table,String> iFirstName;
#FXML TableColumn<Table,String> iLastName;
#FXML TableColumn<Table,Boolean> iMalebox;
#FXML TableColumn<Table,Boolean> iFemalebox;
#Override public void initialize(URL location,ResourceBundle resources){
iFirstName.setCellValueFactory(new PropertyValueFactory<Table,String>("rFirstName"));
iLastName.setCellValueFactory(new PropertyValueFactory<Table,String>("rLastName"));
iMalebox.setCellValueFactory(new Callback<CellDataFeatures<Table,Boolean>,ObservableValue<Boolean>>(){
#Override public ObservableValue<Boolean> call(CellDataFeatures<Table,Boolean> cellData){
return cellData.getValue().maleCheckedProperty(true);
}
});
iMalebox.setCellFactory(new Callback<TableColumn<Table,Boolean>,TableCell<Table,Boolean>>(){
#Override public TableCell<Table,Boolean> call(TableColumn<Table,Boolean> param){
return new CheckBoxTableCell<>();
}
});
iFemalebox.setCellValueFactory(new Callback<CellDataFeatures<Table,Boolean>,ObservableValue<Boolean>>(){
#Override public ObservableValue<Boolean> call(CellDataFeatures<Table,Boolean> cellData){
return cellData.getValue().femaleCheckedProperty(true);
}
});
iFemalebox.setCellFactory(new Callback<TableColumn<Table,Boolean>,TableCell<Table,Boolean>>(){
#Override public TableCell<Table,Boolean> call(TableColumn<Table,Boolean> param){
return new CheckBoxTableCell<>();
}
});
tableID.setItems(FXCollections.observableArrayList(new Table("Horst","Meier",true),new Table("Anna","Becker",false),new Table("Karl","Schmidt",true)));
}
}
src.view.Table.java
package view;
import javafx.beans.property.*;
public class Table{
private String rFirstName;
private String rLastName;
public Table(String sFirstName,String sLastName,Boolean sMale){
rFirstName=sFirstName;
rLastName=sLastName;
maleCheckedProperty(false).set(sMale);
}
private SimpleBooleanProperty maleChecked=new SimpleBooleanProperty(false);
private SimpleBooleanProperty femaleChecked=new SimpleBooleanProperty(false);
public SimpleBooleanProperty maleCheckedProperty(boolean recursion){
if(recursion) femaleCheckedProperty(false).set(!maleChecked.get());
return maleChecked;
}
public SimpleBooleanProperty femaleCheckedProperty(boolean recursion){
if(recursion) maleCheckedProperty(false).set(!femaleChecked.get());
return femaleChecked;
}
public String getRFirstName(){
return rFirstName;
}
public String getRLastName(){
return rLastName;
}
}
src.controller.MainController.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="98.0" prefWidth="218.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.MainController">
<children>
<TableView fx:id="tableID" editable="true" prefHeight="494.0" prefWidth="798.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="iFirstName" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="63.0" text="First name" />
<TableColumn fx:id="iLastName" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="63.0" text="Last name" />
<TableColumn fx:id="iMalebox" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="45.0" text="Male"/>
<TableColumn fx:id="iFemalebox" maxWidth="1.7976931348623157E308" minWidth="-1.0" prefWidth="45.0" text="Female"/>
</columns>
</TableView>
</children>
</AnchorPane>

Multiple, but limited, CheckBoxes in FXML/JavaFX

I'm trying to find a way to use check boxes to allow the user to pick two things from a list of three, and then have the remaining check box become disabled until one of the others is un-selected. I have a ChangeListener attached to all three check boxes, so I can register when two have been selected, but I don't know how to target the "other" box/boxes to disable/enable them.
ChangeListener checkboxlistener = new ChangeListener() {
int i = 0;
#Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
if((boolean) observable.getValue() == true) {
i++;
System.out.println(i);
} else {
i--;
System.out.println(i);
}
if(i == 2) {
//What should I put here, if anything?//
}
}
};
checkbox1.selectedProperty().addListener(checkboxlistener);
checkbox2.selectedProperty().addListener(checkboxlistener);
checkbox3.selectedProperty().addListener(checkboxlistener);
}
Keep a collection of selected check boxes and unselected check boxes. Add a listener to each check box's selectedProperty and make sure it is in the correct collections when the selection changes.
Then you can just observe the size of the collection of selected check boxes, and update the disable state of all the unselected check boxes accordingly.
Here's an example:
MultipleCheckBoxExampleController.java:
package multiplecheckbox;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.IntegerBinding;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
public class MultipleCheckBoxExampleController {
#FXML
private CheckBox checkBox1 ;
#FXML
private CheckBox checkBox2 ;
#FXML
private CheckBox checkBox3 ;
#FXML
private Button submitButton ;
private ObservableSet<CheckBox> selectedCheckBoxes = FXCollections.observableSet();
private ObservableSet<CheckBox> unselectedCheckBoxes = FXCollections.observableSet();
private IntegerBinding numCheckBoxesSelected = Bindings.size(selectedCheckBoxes);
private final int maxNumSelected = 2;
public void initialize() {
configureCheckBox(checkBox1);
configureCheckBox(checkBox2);
configureCheckBox(checkBox3);
submitButton.setDisable(true);
numCheckBoxesSelected.addListener((obs, oldSelectedCount, newSelectedCount) -> {
if (newSelectedCount.intValue() >= maxNumSelected) {
unselectedCheckBoxes.forEach(cb -> cb.setDisable(true));
submitButton.setDisable(false);
} else {
unselectedCheckBoxes.forEach(cb -> cb.setDisable(false));
submitButton.setDisable(true);
}
});
}
private void configureCheckBox(CheckBox checkBox) {
if (checkBox.isSelected()) {
selectedCheckBoxes.add(checkBox);
} else {
unselectedCheckBoxes.add(checkBox);
}
checkBox.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
unselectedCheckBoxes.remove(checkBox);
selectedCheckBoxes.add(checkBox);
} else {
selectedCheckBoxes.remove(checkBox);
unselectedCheckBoxes.add(checkBox);
}
});
}
}
MultipleCheckBoxExample.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="multiplecheckbox.MultipleCheckBoxExampleController"
alignment="center" spacing="5">
<padding>
<Insets top="10" bottom="10" left="10" right="10" />
</padding>
<CheckBox fx:id="checkBox1" text="Choice 1" />
<CheckBox fx:id="checkBox2" text="Choice 2" />
<CheckBox fx:id="checkBox3" text="Choice 3" />
<Button fx:id="submitButton" text="Submit" />
</VBox>
Main.java:
package multiplecheckbox;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.fxml.FXMLLoader;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
VBox root = FXMLLoader.load(getClass().getResource("MultipleCheckBoxExample.fxml"));
Scene scene = new Scene(root,400,400);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}

Populating a TableView with data from Database JavaFX

I'm trying to populate my TableView in JavaFX with data from my database.
I've been trying a lot of different methods to try and get something working. I've been changing a lot of things but ultimately I haven't gotten anywhere. I think it has something to do with the way I'm loading my FXML file.
My database has 3 columns, so I'm not sure if I have to define everything from the database in my Artist class and that's why it's giving me errors.
I built my GUI with SceneBuilder so I'll attach my FXML file.
My main class
package application;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
public class Main extends Application {
#Override
public void start(Stage stage) throws IOException {
FXMLLoader loader = new FXMLLoader(Main.class
.getResource("artistSelection.fxml"));
Group rootGroup = loader.load();
final artistSelectionController controller = loader.getController();
controller.setStage(stage);
Scene scene = new Scene(rootGroup,600,400);
stage.setScene(scene);
StageStyle stageStyle = StageStyle.TRANSPARENT;
scene.setFill(Color.TRANSPARENT);
stage.initStyle(stageStyle);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
My Controller Class
public class artistSelectionController{
#FXML
private Rectangle rect;
#FXML
private ImageView logo;
#FXML
private HBox buttons;
#FXML
private Button newArtist;
#FXML
private Button closeScreen;
private Stage stage;
private double dragAnchorX;
private double dragAnchorY;
private PreparedStatement preparedStatement;
public void setStage(Stage stage){
this.stage = stage;
}
#FXML
public void closeScreenHandler(ActionEvent e){
stage.close();
}
#FXML
public void mousePressedHandler(MouseEvent me) {
dragAnchorX = me.getScreenX() - stage.getX();
dragAnchorY = me.getScreenY() - stage.getY();
}
#FXML
public void mouseDraggedHandler(MouseEvent me) {
stage.setX(me.getScreenX() - dragAnchorX);
stage.setY(me.getScreenY() - dragAnchorY);
}
#FXML
private static TableView<Artist> artistTable;
#FXML
private TableColumn<Artist, String> artistName;
private DBConnect objDbClass;
private Connection con;
private Logger logger;
#FXML
void initialize(){
// assert artistTable != null : "fx:id=\"tableview\" was not injected: check your FXML file 'UserMaster.fxml'.";
artistName.setCellValueFactory(
new PropertyValueFactory<Artist,String>("Artist"));
objDbClass = new DBConnect();
try{
con = objDbClass.getConnection();
buildData();
}
catch(ClassNotFoundException ce){
logger.newInput(ce.toString());
}
catch(SQLException ce){
logger.newInput(ce.toString());
}
}
private ObservableList<Artist> data;
public void buildData(){
data = FXCollections.observableArrayList();
try{
String SQL = "Select Name from ARTIST";
ResultSet rs = con.createStatement().executeQuery(SQL);
while(rs.next()){
Artist cm = new Artist();
cm.name.set(rs.getString("name"));
data.add(cm);
}
artistTable.setItems(data);
}
catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
}
My POJO
package application;
import javafx.beans.property.SimpleStringProperty;
public class Artist {
public SimpleStringProperty name = new SimpleStringProperty();
public SimpleStringProperty genre = new SimpleStringProperty();
public String getName() {
return name.get();
}
public String getGenre() {
return genre.get();
}
}
My Database Connector
import java.sql.*;
public class DBConnect{
public Connection getConnection() throws ClassNotFoundException, SQLException{
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection("jdbc:mysql://localhost/myStudio","root","root");
}
}
And finally my FXML file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<Group fx:id="rootGroup" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application/artistSelectionController">
<children>
<Rectangle fx:id="rect" arcHeight="50.0" arcWidth="50.0" height="376.0" layoutX="13.0" layoutY="13.0" stroke="BLACK" strokeType="INSIDE" width="577.0">
<fill>
<LinearGradient cycleMethod="REPEAT" endX="1.0" endY="1.0" startY="1.0">
<stops>
<Stop color="#1b2f36" />
<Stop color="#1b2f36" offset="0.007662835249042145" />
<Stop color="#15596e" offset="1.0" />
</stops>
</LinearGradient>
</fill>
</Rectangle>
<ImageView fx:id="logo" fitHeight="411.0" fitWidth="606.0" layoutX="13.0" layoutY="13.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../../Downloads/myStudio.png" />
</image>
</ImageView>
<TableView fx:id="artistTable" layoutX="316.0" layoutY="143.0" prefHeight="223.0" prefWidth="241.0">
<columns>
<TableColumn fx:id="artistName" editable="false" prefWidth="240.0" resizable="false" text="Artists" />
</columns>
</TableView>
<HBox fx:id="buttons" layoutX="65.0" layoutY="339.0" prefHeight="100.0" prefWidth="200.0" spacing="20.0">
<children>
<Button fx:id="newArtist" mnemonicParsing="false" prefWidth="75.0" text="New Artist" />
<Button fx:id="closeScreen" mnemonicParsing="false" prefWidth="75.0" text="Close" />
</children>
</HBox>
</children>
</Group>
Thanks
There seem to be many errors in your code.
First, you have made artistTable static. Don't do this - it makes no sense at all, and static fields won't be injected by the FXMLLoader. This is why you are getting the null pointer exception.
Second, the value you pass to the PropertyValueFactory ("Artist") does not match the name of any property in your model class Artist. (I.e. there is no ArtistProperty() method and no getArtist() method).
You probably want
artistName.setCellValueFactory(
new PropertyValueFactory<Artist,String>("name"));
which will tie the value for the column to the getName() method. See the PropertyValueFactory documentation for a description of how it works.
(You should probably define your POJO according to the JavaFX Property pattern described here. However just having a get...() method will work.)

How to reload data in ZK PivotTable with new values when combobox onchange event trigger

I need to reload data in ZK pivot table when ombobox onchange event trigger.
If user change the value from the comobox { as shown in below code } data should change based on user selection.
index.zul
<window apply="org.zkoss.pivot.demo.PivotDemoBaseController" >
<hlayout>
<panel id="main" hflex="1" border="normal">
<caption label="2012 Data">
<toolbarbutton id="exportCsvBtn" label="Export CSV" />
<toolbarbutton id="exportXlsBtn" label="Export XLS" />
<toolbarbutton id="exportXlsxBtn" label="Export XLSX" />
</caption>
<panelchildren>
<vlayout spacing="0">
<pivottable id="pivot" hflex="1" pageSize="15" >
<combobox model="${lm}" id="selectGeo"/>
<div>All People</div>
</pivottable>
<div id="descDiv" />
</vlayout>
</panelchildren>
</panel>
<panel id="field" title="Control" width="300px" border="normal" >
<panelchildren>
<vlayout style="padding: 10px">
<!-- Predefined scenario: -->
<hlayout id="preDef" spacing="0" />
<div class="footnote" style="padding: 5px 0">(Drag fields among the areas below)</div>
<pivot-field-control id="pfc" height="300px" />
<hlayout hflex="1">
<checkbox id="autoUpdate" label="Auto Update" checked="true" />
<div hflex="1" />
<!-- <button id="updateBtn" label="Update" disabled="true" autodisable="+self" /> -->
</hlayout>
<separator />
<checkbox id="colGrandTotal" label="Enable grand total for columns" />
<checkbox id="rowGrandTotal" label="Enable grand total for rows" />
<div>
<radiogroup id="dataOrient">
Data field orientation:
<radio id="colOrient" label="column" />
<radio id="rowOrient" label="row" />
</radiogroup>
</div>
</vlayout>
</panelchildren>
</panel>
</hlayout>
</window>
Below is the code of my Controller
public class PivotDemoBaseController extends SelectorComposer {
private static final long serialVersionUID = -7531153593366258488L;
private static final String[] TITLES = new String[] { "(Data Title)", "(Column Title)", "(Row Title)" };
#Wire
private Pivottable pivot;
#Wire
private PivotFieldControl pfc;
#Wire
private Button updateBtn;
#Wire
private Checkbox colGrandTotal, rowGrandTotal;
#Wire
private Radio colOrient, rowOrient;
#Wire
private Hlayout preDef;
#Wire
private Div descDiv;
private TabularPivotModel _model;
#Wire
private Combobox selectGeo;
private CellStyleConfigurator styleConfigurator;
public void onCheck$autoUpdate(CheckEvent event) {
boolean deferred = !event.isChecked();
pfc.setDeferredUpdate(deferred);
if (!deferred)
updateBtn.setDisabled(true);
}
#Listen("onChange = #selectGeo")
public void onChangeSelectGeo(Event event) {
String geography = selectGeo.getValue();
System.out.println("Value---"+geography);
}
public void onClick$updateBtn() {
pfc.update();
}
public void onPivotFieldControlChange$pfc() {
if (!pfc.isUpdated())
updateBtn.setDisabled(false);
}
public void onCheck$colGrandTotal(CheckEvent event) {
System.out.println("PivotDemoBaseController.onCheck$colGrandTotal()");
pivot.setGrandTotalForColumns(event.isChecked());
}
public void onCheck$rowGrandTotal(CheckEvent event) {
pivot.setGrandTotalForRows(event.isChecked());
}
public void onCheck$dataOrient(CheckEvent event) {
pivot.setDataFieldOrient(((Radio)event.getTarget()).getLabel());
}
public void onClick$exportCsvBtn() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PivotExportContext context = Exports.getExportContext(pivot, true, TITLES);
Exports.exportCSV(out, context);
Filedownload.save(out.toByteArray(), "text/csv", "pivot.csv");
try {
out.close();
} catch (IOException e) {}
}
public void onClick$exportXlsBtn() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PivotExportContext context = Exports.getExportContext(pivot, true, TITLES);
Exports.exportExcel(out, "xls", context, styleConfigurator);
Filedownload.save(out.toByteArray(), "application/vnd.ms-excel", "pivot.xls");
try {
out.close();
} catch (IOException e) {}
}
public void onClick$exportXlsxBtn() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PivotExportContext context = Exports.getExportContext(pivot, true, TITLES);
Exports.exportExcel(out, "xlsx", context, styleConfigurator);
Filedownload.save(out.toByteArray(), "application/vnd.ms-excel", "pivot.xlsx");
try {
out.close();
} catch (IOException e) {}
}
#NotifyChange("*")
#Override
public void doAfterCompose(Component comp) throws Exception {
System.out.println("PivotDemoBaseController.doAfterCompose()");
super.doAfterCompose(comp);
StaticPivotModelFactory pmf = StaticPivotModelFactory.INSTANCE;
//PivotModelFactory pmf= (PivotModelFactory) arg.get("factory");
_model = pmf.build();
pivot.setModel(_model);
pfc.setModel(_model);
Executions.createComponents(pmf.getDescriptionURI(), descDiv, null);
loadConfiguration(pmf.getDefaultConfigurator());
// load predefined scenario
for(PivotConfigurator conf : pmf.getConfigurators())
preDef.appendChild(getPreDefDiv(conf));
}
private void initControls() {
System.out.println("PivotDemoBaseController.initControls()");
// grand totals
colGrandTotal.setChecked(pivot.isGrandTotalForColumns());
rowGrandTotal.setChecked(pivot.isGrandTotalForRows());
// data orientation
("column".equals(pivot.getDataFieldOrient()) ?
colOrient : rowOrient).setChecked(true);
pfc.syncModel(); // field control
}
private Component getPreDefDiv(final PivotConfigurator conf) {
Div div = new Div();
div.setHflex("1");
div.setSclass("predef");
div.appendChild(new Label(conf.getTitle()));
div.addEventListener("onClick", new EventListener(){
public void onEvent(Event event) throws Exception {
loadConfiguration(conf);
}
});
return div;
}
private void loadConfiguration(PivotConfigurator conf) {
System.out.println("PivotDemoBaseController.loadConfiguration()");
_model.clearAllFields(true);
conf.configure(_model);
conf.configure(pivot);
pivot.setPivotRenderer(conf.getRenderer());
styleConfigurator = conf.getCellStyleConfigurator();
initControls();
}
}
Any Help would be much appreciated.
I think you mean the #NotifyChange annotation, but it is for MVVM data-binding, which you did not use.
You can switch to the MVVM data binding or you schould update it like this:
#Listen("onChange = #selectGeo")
public void onChangeSelectGeo(CheckEvent event) {
// Manipulate pivot element here.
}
For more info, see CheckEvent and MVVM vs MVC.

How to call another method in the pojo class setter method [session file uploading application] of Hibernate and struts 2

Hi Friends i am developing an web application which uses hibernate and struts2. i am creating photo album i successfully done that with out using hibernate but, with hibernate it is having problem while inserting to the database. the module works like this as soon as the file uploaded it will insert the FileName, Contenttype,id and it suppose to insert the Image File(byte[]) Content also but it is showing Null in table value.. my code goes like this...
#Entity
#Table(name="PHOTOALBUM")
public class User implements Serializable {
#Id
#GeneratedValue
#Column(name="PHOTO_ID")
private Long id;
#Column(name="IMAGE")
private byte[] Image;
#Column(name="CONTENT_TYPE")
private String userImageContentType;
#Column(name="PHOTO_NAME")
private String userImageFileName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserImageFileName() {
return userImageFileName;
}
public void setUserImageFileName(String userImageFileName) {
this.userImageFileName = userImageFileName;
}
public String getUserImageContentType() {
return userImageContentType;
}
public void setUserImageContentType(String userImageContentType) {
this.userImageContentType = userImageContentType;
}
public byte[] getImage() {
return Image;
}
public void setImage(byte[] Image) {
Image=Change(this.getUserImage());
this.Image = Image;
}
#Transient
private File userImage;
public File getUserImage() {
return userImage;
}
public void setUserImage(File userImage) {
this.userImage = userImage;
}
public byte[] Change(File userImage)
{
// userImage=this.getUserImage();
// String name=userImage.getName();
// long len=userImage.length();
byte[] bFile = new byte[(int) userImage.length()];
try {
FileInputStream fileInputStream = new FileInputStream(userImage);
fileInputStream.read(bFile);
fileInputStream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
// System.out.println("The Name Of File In Pojo Class Is:="+ name);
//System.out.println("The Length Of File In Pojo Class Is:="+ len);
//System.out.println("The Content Of File In Pojo Class Is:="+ bFile);
return bFile;
}
}
and i am saving the values like this
public class UserDAOImpl implements UserDAO {
#SessionTarget
Session session;
#TransactionTarget
Transaction transaction;
/**
* Used to save or update a user.
*/
#Override
public void saveOrUpdateUser(User user) {
try {
session.saveOrUpdate(user);
} catch (Exception e) {
transaction.rollback();
e.printStackTrace();
}
}
/**
* Used to delete a user.
*/
#Override
public void deleteUser(Long userId) {
try {
User user = (User) session.get(User.class, userId);
session.delete(user);
} catch (Exception e) {
transaction.rollback();
e.printStackTrace();
}
}
/**
* Used to list all the users.
*/
#SuppressWarnings("unchecked")
#Override
public List<User> listUser() {
List<User> courses = null;
try {
courses = session.createQuery("from User").list();
} catch (Exception e) {
e.printStackTrace();
}
return courses;
}
/**
* Used to list a single user by Id.
*/
#Override
public User listUserById(Long userId) {
User user = null;
try {
user = (User) session.get(User.class, userId);
} catch (Exception e) {
e.printStackTrace();
}
return user;
}
}
the struts action mapping goes like this...
\<package name="default" extends="hibernate-default">
<action name="saveOrUpdateUser"method="saveOrUpdate"class="com.srikanth.web.UserAction">
<result name="success" type="redirect">listUser</result>
</action>
<action name="listUser" method="list" class="com.srikanth.web.UserAction">
<result name="success">/register.jsp</result>
</action>
<action name="editUser" method="edit" class="com.srikanth.web.UserAction">
<result name="success">/register.jsp</result>
</action>
<action name="deleteUser" method="delete" class="com.srikanth.web.UserAction">
<result name="success" type="redirect">listUser</result>
</action>
</package>
and my jsp goes like this
\<s:form action="saveOrUpdateUser">
<s:push value="user">
<s:hidden name="id" />
<s:file name="userImage" label="User Image" />
<s:submit />
</s:push>
</s:form>
<s:iterator value="userList" status="userStatus">
<s:property value="id" />
<s:property value="userImageFileName" />
<s:property value="userImageContentType" />
<img src='<s:property value="userImage" />' alt"" />
<s:url id="deleteURL" action="deleteUser">
<s:param name="id" value="%{id}"></s:param>
</s:url> <s:a href="%{deleteURL}">Delete</s:a>
</s:iterator>
I am trying to call the Change Method so that it convert the file to byte[] and stored it in byte[] Image variable using setter but it is not working....
So please help me with this one .....
thanks in advance
As per my understand of question the problem is only inserting file into table. Copy & paste the Change() method into com.srikanth.web.UserAction class as you are using this action for every DB transaction. use Change() method before going to insert/update in DB.
For example:
public class UserAction extends ActionSupport{
//variable to get file from jsp
private File uploadedImage;
.....
//setters & getters for uploadedImage
#Override
public String gsexecute() throws Exception {
User user = new User();
//set image value as byteArray
user.setImage(Change(uploadedImage));
//insert or update DB here
return SUCCESS;
}
public byte[] Change(File userImage)
{
// userImage=this.getUserImage();
// String name=userImage.getName();
// long len=userImage.length();
byte[] bFile = new byte[(int) userImage.length()];
try {
FileInputStream fileInputStream = new FileInputStream(userImage);
fileInputStream.read(bFile);
fileInputStream.close();
}
catch(Exception e)
{
e.printStackTrace();
}
// System.out.println("The Name Of File In Pojo Class Is:="+ name);
//System.out.println("The Length Of File In Pojo Class Is:="+ len);
//System.out.println("The Content Of File In Pojo Class Is:="+ bFile);
return bFile;
}
}
And make sure that the table column should support the byte array insert. Ex: use BLOB column type for MYSQL.

Resources