JavaFX How can I make a line chart out of an observable list? - database

I have been playing around with the line chart tutorial here: http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/line-chart.htm#CIHGBCFI
I want to extend the tutorial and attempt to build a line chart out of data from a database, instead of setting data like this:
series.getData().add(new XYChart.Data(1, 23));
series.getData().add(new XYChart.Data(2, 14));
What I have to import data from database:
public ObservableList<Items> loadChart() {
try {
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("SELECT cost, date FROM Items ORDER BY date ASC");
ObservableList<Items> data = FXCollections.observableArrayList();
while(rs.next()){
Items items = new Items();
items.setCost(rs.getInt(1));
items.setDate(rs.getString(2));
data.add(items);
}
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
I want to plot cost and date against in a line chart... Yet don't know how to do so (based on observable list and the tutorial).

If you are using that sample, your code should look something like this.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
public class LineChartSample extends Application {
#Override public void start(Stage stage) {
stage.setTitle("Line Chart Sample");
//defining the axes
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Number of Month");
//creating the chart
final LineChart<Number,Number> lineChart =
new LineChart<Number,Number>(xAxis,yAxis);
lineChart.setTitle("Stock Monitoring, 2010");
//defining a series
XYChart.Series series = new XYChart.Series();
series.setName("My portfolio");
//populating the series with data
try
{
Connection connection = DriverManager.getConnection("...");//You can use try with resources. Establish a Connection
Statement stmt = connection.createStatement();//Create Statement
ResultSet rs = stmt.executeQuery("SELECT cost, date FROM Items ORDER BY date ASC");//Query DB and get results.
//Iterate through results.
while(rs.next())
{
series.getData().add(new XYChart.Data(rs.getInt(1), Integer.parseInt(rs.getString(2))));//Add data to Chart. Changed the second input to Integer due to LineChart<Number,Number>. This should work, though I haven't tested it.
}
}
catch (SQLException ex) {
Logger.getLogger(LineChartSample.class.getName()).log(Level.SEVERE, null, ex);
}
Scene scene = new Scene(lineChart,800,600);
lineChart.getData().add(series);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
UPDATE BELOW
You can try something like this if you want to have a database handler class.
DBHandler Class
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.scene.chart.XYChart;
/**
*
* #author blj0011
*/
public class DBHandler
{
List<List<Integer>> dataHolder;
//There is probably a better way to structure this DBHandler Class
public DBHandler()
{
dataHolder = new ArrayList();
try
{
Connection connection = DriverManager.getConnection("...");//You can use try with resources. Establish a Connection
Statement stmt = connection.createStatement();//Create Statement
ResultSet rs = stmt.executeQuery("SELECT cost, date FROM Items ORDER BY date ASC");//Query DB and get results.
//Iterate through results.
while(rs.next())
{
List<Integer> tempDataHolder = new ArrayList();
tempDataHolder.add(rs.getInt(1));
tempDataHolder.add(Integer.parseInt(rs.getString(2)));
dataHolder.add(tempDataHolder);
}
}
catch (SQLException ex) {
Logger.getLogger(DBHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
public List<List<Integer>> getDataHolder()
{
return dataHolder;
}
}
Main Class
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
public class LineChartSample extends Application {
#Override public void start(Stage stage) {
stage.setTitle("Line Chart Sample");
//defining the axes
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Number of Month");
//creating the chart
final LineChart<Number,Number> lineChart =
new LineChart<Number,Number>(xAxis,yAxis);
lineChart.setTitle("Stock Monitoring, 2010");
//defining a series
XYChart.Series series = new XYChart.Series();
series.setName("My portfolio");
//populating the series with data
DBHandler dbHandler = new DBHandler();
List<List<Integer>> dataHolder = dbHandler.getDataHolder();
for(int i = 0; i < dataHolder.size(); i++)
{
series.getData().add(new XYChart.Data(dataHolder.get(i).get(0), dataHolder.get(i).get(1)));
}
Scene scene = new Scene(lineChart,800,600);
lineChart.getData().add(series);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Related

JAVAFX Text Animation From Array

This is very much a work in progress so I apologize for my code needing to be cleaned up, but I thought it best to include everything I have so far.
I'm trying to figure how to animate text by looping through an array of images. My code loops through the array and displays just the last image. I need to display one image at a time and repeat to give the desired animation effect. What am I doing wrong or not doing?
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.stage.Stage;
import javafx.util.Duration;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.event.EventHandler;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
public class ImageAnimatorWithAudio extends Application {
private final static int NUMBER_OF_SLIDES = 10;
#Override // Override the start method in the Application class
public void start(Stage primaryStage) {
Image[] images = new Image[NUMBER_OF_SLIDES];
Timeline animation = new Timeline(new KeyFrame(Duration.millis(5000)));
animation.setCycleCount(Timeline.INDEFINITE);
animation.play();
HBox hBox = new HBox();
hBox.setSpacing(10);
hBox.setAlignment(Pos.TOP_RIGHT);
Button btStartPause = new Button("Start Animation");
hBox.getChildren().add(btStartPause);
//Create border pane
BorderPane borderPane = new BorderPane();
borderPane.setTop(hBox); //Add hBox to borderPane
BorderPane.setAlignment(hBox, Pos.TOP_RIGHT); //Align hBox
btStartPause.setOnAction(e -> {
if (btStartPause.getText().equals("Start Animation")) {
btStartPause.setText("Pause Animation");
animation.play();
} else {
btStartPause.setText("Start Animation");
animation.pause();
}
});
GridPane pane = new GridPane();
pane.setPadding(new Insets(5,5,5,5));
for (int i = 0; i < NUMBER_OF_SLIDES; i++) {
images[i] = new Image("image_path" + i + ".png"); //file names are numerically named(i)
pane.getChildren().add(new ImageView(images[i]));
}
pane.getChildren().add(borderPane);
Scene scene = new Scene(pane, 450, 450);
primaryStage.setTitle("TextAnimation"); //Set the stage title
primaryStage.setScene(scene); //Place the scene in the stage
primaryStage.show(); //Display the stage
}
public static void main(String[] args){
Application.launch(args);
}
}
Any help is appreciated.
Here is an app that demonstrates how to add Images to an ArrayList(similar approach for an Array). It also demonstrates how to load those Images into an ImageView and change them using Timeline.
Main
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author Sedrick
*/
public class JavaFXApplication1 extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="371.0" prefWidth="607.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.60" fx:controller="javafxapplication1.FXMLDocumentController">
<children>
<Button fx:id="btnMain" layoutX="263.0" layoutY="326.0" onAction="#handleButtonAction" text="Click Me!" />
<Label fx:id="lblMain" layoutX="269.0" layoutY="28.0" minHeight="16" minWidth="69" />
<ImageView fx:id="ivMain" fitHeight="201.0" fitWidth="278.0" layoutX="165.0" layoutY="85.0" pickOnBounds="true" preserveRatio="true" />
</children>
</AnchorPane>
Controller
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.util.Duration;
/**
*
* #author Sedrick
*/
public class FXMLDocumentController implements Initializable {
#FXML private Label lblMain;
#FXML private ImageView ivMain;
#FXML private Button btnMain;
Timeline timeline;
List<Image> imageContainer;
int currentImageBeingDisplayed;
#FXML
private void handleButtonAction(ActionEvent event) {
lblMain.setText("Animation started!");
currentImageBeingDisplayed = 0;
timeline.play();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
//Load images
imageContainer = new ArrayList();
for(int i = 1; i <= 12; i++)
{
try
{
System.out.println("/images/Slide" + i + ".PNG");
imageContainer.add(new Image(getClass().getResource("/images/Slide" + i + ".PNG").toURI().toString()));
} catch (URISyntaxException ex) {
System.out.println(ex.toString());
}
}
//Change the image every second
timeline = new Timeline(
new KeyFrame(
Duration.seconds(1),
new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent actionEvent) {
Platform.runLater(()->{
ivMain.setImage(imageContainer.get(currentImageBeingDisplayed++));
});
}
}
)
);
timeline.setCycleCount(12);
}
}
Output:(looks similar to below)

Import mp3 files through FileChooser to clickable Labels

I want to import mp3 files as clickable labels, but i have no idea how to handle it. I am doing graphical user interface through JavaFX. Image below will explain more.
You can get all Files from a directory by doing something like this:
File myfolder = new File("path/to/directory");
File[] allFiles = folder.listFiles();
for (int i = 0; i < all.length; i++) {
if (allFiles[i].isFile()) {
System.out.println("File " + allFiles[i].getName());
} else if (listOfFiles[i].isDirectory()) {
System.out.println("Directory " + allFiles[i].getName());
}
}
But instead of printing it to the output you can add Labels with the file.
Maybe something like this is what you want:
File myfolder = new File("your/path");
File[] allFiles = folder.listFiles();
VBox yourBox = new VBox();
for (int i = 0; i < all.length; i++) {
if (allFiles[i].isFile()) {
yourBox.getChildren().add(new Label(allFiles[i].getName());
} else if (listOfFiles[i].isDirectory()) {
//Do whatever you want to do with subfolders.
}
}
Edit: for selecting a folder at runtime you can use:
DirectoryChooser
https://docs.oracle.com/javase/8/javafx/api/javafx/stage/DirectoryChooser.html
Or a FileChooser, which allows selecting multiple Files.
Edit full code (tested):
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
public class test extends Application {
#Override
public void start(final Stage stage) {
stage.setTitle("File Chooser");
final FileChooser fileChooser = new FileChooser();
final Button openMultipleButton = new Button("Open Files...");
VBox yourBox = new VBox();
openMultipleButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent e) {
List<File> list = fileChooser.showOpenMultipleDialog(stage);
if (list != null) {
for (File file : list) {
yourBox.getChildren().add(new Label(file.getName()));
}
}
}
});
HBox all = new HBox();
all.getChildren().addAll(openMultipleButton, yourBox);
final Pane rootGroup = new VBox(12);
rootGroup.getChildren().addAll(all);
rootGroup.setPrefSize(400, 400);
stage.setScene(new Scene(rootGroup));
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
Hope this helped,
Steffi

Null Pointer Exception when using Apache POI

I am trying to input the values to excel from web, having 2 columns and 9 rows, so that I will get the price and the description of 10 products from the web.
but Iam getting the Null pointer exception. Please any one help me out in clearing this error.
package samples;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
//import org.apache.commons.io.FileUtils;
//import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import java.text.ParseException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
//import org.openqa.selenium.OutputType;
//import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
public class A1 {
public static void main(String[] args) throws InterruptedException, ParseException, IOException, EncryptedDocumentException, InvalidFormatException
{
System.out.println("selenium");
WebDriver webdriver = new FirefoxDriver();
webdriver.manage().window().maximize();
webdriver.get("http://www.snapdeal.com");
webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
List<WebElement> alllinks = webdriver.findElements(By.tagName("a"));
int linkcnt = alllinks.size();
System.out.println("total links=" +linkcnt);
Actions action = new Actions(webdriver);
WebElement COG = webdriver.findElement(By.xpath("//span[text()='Computers, Office & Gaming']"));
WebElement EHD = webdriver.findElement(By.xpath("//span[text()='External Hard Drives']"));
action.moveToElement(COG).build().perform();
Thread.sleep(5000);
EHD.click();
webdriver.findElement(By.xpath("//label[#for='Capacity_s-1 TB']")).click();
Thread.sleep(5000);
webdriver.findElement(By.xpath("//a[contains(text(),'500 GB')]/..")).click();
Thread.sleep(5000);
webdriver.findElement(By.xpath("(//span[#class='price-collapse-arrow'])[1]/..")).click();
WebElement totalitems = webdriver.findElement(By.xpath("//span[#class='category-count']"));
String totalitemsvalue=totalitems.getText();
System.out.println(totalitemsvalue);
String value=totalitemsvalue.replaceAll(" Items","");
System.out.println(value);
try{
List<WebElement> productprice = webdriver.findElements(By.xpath("//div[#class='product-tuple-description']/div[2]"));
List<WebElement> productTitle = webdriver.findElements(By.xpath("//div[#class='product-desc-rating title-section-collapse']"));
int count=productprice.size();
int count1=productTitle.size();
System.out.println(count);
System.out.println(count1);
//int i=9;
// int j=9;
Thread.sleep(2000);
for (count=0;count<10;count++)
{
productprice = webdriver.findElements(By.xpath("//div[#class='product-tuple-description']/div[2]"));
// File srcfile=((TakesScreenshot)webdriver).getScreenshotAs(OutputType.FILE);
// FileUtils.copyFile(srcfile, new File("c:\\screenshot.png"));
Thread.sleep(2000);
String RupeesValue= productprice.get(count).getText();
System.out.println(RupeesValue);
Thread.sleep(2000);
productTitle = webdriver.findElements(By.xpath("//div[#class='product-tuple-description']/div[1]"));
Thread.sleep(2000);
String TitleValue= productTitle.get(count1).getText();
System.out.println(TitleValue);
Thread.sleep(2000);
FileInputStream fis = new FileInputStream("C:\\Users\\aa74231\\Desktop\\abc.xlsx");
Workbook wb = WorkbookFactory.create(fis);
Sheet sheet = wb.getSheet("Sheet1");
// Sheet sheet1 = wb.getSheet("Sheet1");
for (int i=0;i<2;i++)
{
Row row=sheet.getRow(count);
// Row row1=sheet.getRow(j);
Cell cell = row.createCell(count);
// Cell cell1 = row1.createCell(count1);
cell.setCellType(cell.CELL_TYPE_STRING);
//cell1.setCellType(cell1.CELL_TYPE_STRING);
if(i==0){
cell.setCellValue(productprice.get(count).getText());
}
else
{
cell.setCellValue(productTitle.get(count).getText());
}
//cell1.setCellValue(productTitle.get(count1).getText());
FileOutputStream fos=new FileOutputStream("C:\\Users\\aa74231\\Desktop\\abc.xlsx");
wb.write(fos);
fos.close();
wb.close();
}
}
} catch(Exception e){
e.printStackTrace();
}
}
}
exception which am getting is :
Exception in thread "main" java.lang.NullPointerException
at samples.learningold.main(learningold.java:97)
First of all your ProductTitle Xpath is not fetching all the product names from the list. I have updated that too.
Following code works well.
package samples;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
public class X
{
#SuppressWarnings("resource")
public static void main(String[] args) throws InterruptedException, ParseException, IOException, EncryptedDocumentException, InvalidFormatException
{
System.out.println("selenium");
WebDriver webdriver = new FirefoxDriver();
webdriver.manage().window().maximize();
webdriver.get("http://www.snapdeal.com");
webdriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
List<WebElement> alllinks = webdriver.findElements(By.tagName("a"));
int linkcnt = alllinks.size();
System.out.println("total links=" +linkcnt);
Actions action = new Actions(webdriver);
WebElement COG = webdriver.findElement(By.xpath("//span[text()='Computers, Office & Gaming']"));
WebElement EHD = webdriver.findElement(By.xpath("//span[text()='External Hard Drives']"));
action.moveToElement(COG).build().perform();
Thread.sleep(5000);
EHD.click();
webdriver.findElement(By.xpath("//label[#for='Capacity_s-1 TB']")).click();
Thread.sleep(5000);
webdriver.findElement(By.xpath("//a[contains(text(),'500 GB')]/..")).click();
Thread.sleep(5000);
webdriver.findElement(By.xpath("(//span[#class='price-collapse-arrow'])[1]/..")).click();
Thread.sleep(5000);
WebElement totalitems = webdriver.findElement(By.xpath("//span[#class='category-count']"));
String totalitemsvalue=totalitems.getText();
System.out.println(totalitemsvalue);
String value=totalitemsvalue.replaceAll(" Items","");
System.out.println(value);
try
{
List<WebElement> productprice = webdriver.findElements(By.xpath("//div[#class='product-tuple-description']/div[2]"));
List<WebElement> productTitle = webdriver.findElements(By.xpath("//div[#class='product-tuple-description']/div[1]"));
int count=productprice.size();
int count1=productTitle.size();
System.out.println(count);
System.out.println(count1);
String[] productPriceList = new String[count];
String[] productTitleList = new String[count];
Thread.sleep(2000);
for(int k =0; k<count; k++)
{
System.out.println(productprice.get(k).getText());
productPriceList[k]=productprice.get(k).getText();
System.out.println(productTitle.get(k).getText());
productTitleList[k]=productTitle.get(k).getText();
}
File file= new File("C:\\Users\\XX\\Downloads\\snapdeal.xlsx"); // give your file path
FileInputStream inputStream = new FileInputStream(file);
Workbook sampleWorkbook=null;
sampleWorkbook=new XSSFWorkbook(inputStream);
Sheet sheet = sampleWorkbook.getSheet("Sheet1");
for(int t=0;t<count;t++)
{
Row row = sheet.createRow(t);
Cell cell = row.createCell(0); // create column 1
cell.setCellValue(productPriceList[t].toString());
Cell cell1 = row.createCell(1); // create column 2
cell1.setCellValue(productTitleList[t].toString());
inputStream.close();
FileOutputStream outputStream = new FileOutputStream(file);
sampleWorkbook.write(outputStream);
System.out.println("Data written to Excel successful");
outputStream.close();
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}

Combobox refresh value and listview when object content change

I would like to update my combobox when the content of the object used to display text in combo changes.
Here is a sample:
package com.javafx.example.combobox;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;
import javafx.util.StringConverter;
public class ComboboxSample extends Application {
class Sequence {
public StringProperty name = new SimpleStringProperty();
public Sequence(String name) {
super();
this.name.set(name);
}
#Override
public String toString() {
return "null";
}
}
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("ComboBoxSample");
ComboBox<Sequence> combo = new ComboBox<>();
combo.setItems(FXCollections.observableArrayList(
new Sequence("Toto"),
new Sequence("Titi")));
combo.getSelectionModel().selectFirst();
combo.setConverter(new StringConverter<ComboboxSample.Sequence>() {
#Override
public String toString(Sequence sequence) {
return sequence.name.get();
}
#Override
public Sequence fromString(String string) {
System.out.println("call fromString");
return null;
}
});
TextField text = new TextField();
Button renameButton = new Button("Rename");
renameButton.setOnAction(evt -> combo.getValue().name.set(text.getText()));
HBox root = new HBox(combo, text, renameButton);
HBox.setHgrow(text, Priority.ALWAYS);
stage.setScene(new Scene(root));
stage.show();
}
public static void main(String... args) {
launch(args);
}
}
The combobox contains objects with a property name. If i rename this property, the display do not change or sometimes it changes but not all the time. It is the standard behavior as the combobox update when the object changes, and not when its content changes.
How can i do to force the combobox to refresh its value and the listview on change?
Thanks
EDIT1:
Using a callback in an observaleList seems to be a solution.
package com.javafx.example.combobox;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
public class ComboboxSample extends Application {
ObservableList<Sequence> sequences;
class Sequence {
public StringProperty name = new SimpleStringProperty();
public Sequence(String name) {
super();
this.name.set(name);
}
#Override
public String toString() {
return "null";
}
}
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("ComboBoxSample");
Callback<Sequence, Observable[]> extractor = new Callback<Sequence, Observable[]>() {
#Override
public Observable[] call(Sequence s) {
return new Observable[] {s.name};
}
};
sequences = FXCollections.observableArrayList(extractor);
sequences.addAll(
new Sequence("Toto"),
new Sequence("Titi"));
ComboBox<Sequence> combo = new ComboBox<>();
combo.setItems(sequences);
combo.getSelectionModel().selectFirst();
combo.setConverter(new StringConverter<ComboboxSample.Sequence>() {
#Override
public String toString(Sequence sequence) {
return sequence.name.get();
}
#Override
public Sequence fromString(String string) {
System.out.println("call fromString");
return null;
}
});
combo.valueProperty().addListener((obs, oldValue, newValue) -> System.out.println("Change from " + oldValue.name.get() + " to " + newValue.name.get()));
TextField text = new TextField();
Button renameButton = new Button("Rename");
renameButton.setOnAction(evt -> {
combo.getValue().name.set(text.getText());
});
HBox root = new HBox(combo, text, renameButton);
HBox.setHgrow(text, Priority.ALWAYS);
stage.setScene(new Scene(root));
stage.show();
}
public static void main(String... args) {
launch(args);
}
}
Everytime a new value is added to the object list, set the combobox value again. Works for me. I did a small example to show this. Hope it is helpful
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ComboTest extends Application {
int i =0;
ObservableList<String> list = FXCollections.observableArrayList("A","B");
ComboBox<String> combo = new ComboBox();
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
combo.setPromptText("Testing combobox");
combo.setPrefWidth(300);
btn.setText("Add items to list");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
list.add(String.valueOf(i));
System.out.println("size of list " + list.size() );
i++;
combo.setItems(list);
}
});
combo.setItems(list);
VBox root = new VBox();
root.getChildren().addAll(btn,combo);
root.setSpacing(20);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}

Selenium Web driver--Failure Screenshot is not captured in TestNG report

With below mentioned code,if the test case is pass-screenshot captured successfully and displayed in report.But when the test is failed--screenshot is not displayed.Even screenshot hyperlink is not displayed in report.Anybody can sort out the mistake in code?
package listeners;
import java.io.File;
import java.io.IOException;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.TestListenerAdapter;
import java.util.logging.Logger;
#Listeners
public class CountryChoserLayer extends TestListenerAdapter {
#Test(priority=1)
public void choseCountry() throws Exception{
driver.findElement(By.id("intselect")).sendKeys("India");
driver.findElement(By.xpath(".//*[#id='countryChooser']/a/img")).click();
//window.onbeforeunload = null;
Date date=new Date();
Format formatter = new SimpleDateFormat("yyyy-MM-dd_hh-mm-ss");
File scrnsht = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
String NewFileNamePath=("C://Documents and Settings//vlakshm//workspace//MyTNG//test-output//Screenshots"+"//SearsINTL_"+ formatter.format(date)+".png");
FileUtils.copyFile(scrnsht, new File(NewFileNamePath));
System.out.println(NewFileNamePath);
Reporter.log("Passed Screenshot");
System.out.println("---------------------------------------");
System.out.println("Country choser layer test case-Success");
System.out.println("---------------------------------------");
}
public String baseurl="http://www.sears.com/shc/s/CountryChooserView?storeId=10153&catalogId=12605";
public WebDriver driver;
public int Count = 0;
#Test(priority=0)
public void openBrowser() {
driver = new FirefoxDriver();
driver.manage().deleteAllCookies();
driver.get(baseurl);
}
#Test(priority=2)
public void closeBrowser() {
driver.quit();
}
#Override
public void onTestFailure(ITestResult result){
Reporter.log("Fail");
System.out.println("BBB");
//Reporter.setCurrentTestResult(result);
Date date=new Date();
Format formatter = new SimpleDateFormat("yyyy-MM-dd_hh-mm-ss");
File scrnsht = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
//File scrFile = ((TakesScreenshot) WebDriver.globalDriverInstance).getScreenshotAs(OutputType.FILE);
String NewFileNamePath=("C://Documents and Settings//vlakshm//workspace//MyTNG//test-output//Screenshots"+"//SearsINTL_"+ formatter.format(date)+".png");
//System.out.println("AAA" + NewFileNamePath);
try {
//System.out.println("CCC");
FileUtils.copyFile(scrnsht,new File(NewFileNamePath));
System.out.println(NewFileNamePath);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("DDD");
e.printStackTrace();
}
Reporter.log("Failed Screenshot");
Reporter.setCurrentTestResult(null);
System.out.println("---------------------------------------");
System.out.println("Country choser layer test case Failed");
System.out.println("---------------------------------------");
}
#Override
public void onTestSkipped(ITestResult result) {
// will be called after test will be skipped
Reporter.log("Skip");
}
#Override
public void onTestSuccess(ITestResult result) {
// will be called after test will pass
Reporter.log("Pass");
}
}
Your onTestFailure method is not being called because you didn't specify listener for your test class. You are missing a value in #Listeners annotation. It should be something like
#Listeners({CountryChoserLayer.class})
You can find more ways of specifying a listener in official TestNg's documentation.
Another problem you are likely to encounter would be NullPointerException while trying to take screenshot in onTestFailure method. The easiest workaround for that would be changing the declaration of driver field to static. I run the code with those fixes and I got the report with screenshot.
I must add that in my opinion putting both test and listener methods into one class is not a good practice.

Resources