Service is terminated when click on TableView - javafx

I have the following problem. When I press the Button, I execute a Service that parses an html page and puts the results in a table. When I click on the table, while the Service is running, the Service will be terminated.
Can someone help me with this problem?
Here is my controller class:
public class ProxySearchController implements Initializable {
private Scene scene;
#FXML
private Button btn_refresh;
#FXML
private TableView<ProxyResult> tbl_results;
#FXML
private ProgressBar pb_search;
#FXML
private TableColumn<ProxyResult, String> column_ip;
#FXML
private TableColumn<ProxyResult, Integer> column_port;
#FXML
private TableColumn<ProxyResult, Locale> column_locale;
#FXML
private TableColumn<ProxyResult, String> column_anonymity;
#FXML
private TableColumn<ProxyResult, Boolean> column_google;
#FXML
private TableColumn<ProxyResult, Boolean> column_https;
#FXML
private TableColumn<ProxyResult, String> column_lastchecked;
#FXML
private TableColumn<ProxyResult, Long> column_response;
private ObservableList<ProxyResult> data = FXCollections.observableArrayList();
/*
* (non-Javadoc)
*
* #see javafx.fxml.Initializable#initialize(java.net.URL, java.util.ResourceBundle)
*/
#Override
public void initialize(URL location, ResourceBundle resources) {
tbl_results.setItems(data);
tbl_results.getSelectionModel().setCellSelectionEnabled(true);
Clipboard clipboard = Clipboard.getSystemClipboard();
// add listner to your tableview selecteditemproperty
tbl_results.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<ProxyResult>() {
#Override
public void changed(ObservableValue observable, ProxyResult oldValue, ProxyResult newValue) {
ObservableList<TablePosition> posList = tbl_results.getSelectionModel().getSelectedCells();
int old_r = -1;
StringBuilder clipboardString = new StringBuilder();
for (TablePosition p : posList) {
int r = p.getRow();
int c = p.getColumn();
Object cell = tbl_results.getColumns().get(c).getCellData(r);
if (cell == null)
cell = "";
if (old_r == r)
clipboardString.append('\t');
else if (old_r != -1)
clipboardString.append('\n');
clipboardString.append(cell);
old_r = r;
}
final ClipboardContent content = new ClipboardContent();
content.putString(clipboardString.toString());
Clipboard.getSystemClipboard().setContent(content);
}
});
column_ip.setCellValueFactory(new PropertyValueFactory<ProxyResult, String>("ip"));
column_port.setCellValueFactory(new PropertyValueFactory<ProxyResult, Integer>("port"));
column_locale.setCellValueFactory(new PropertyValueFactory<ProxyResult, Locale>("locale"));
column_anonymity.setCellValueFactory(new PropertyValueFactory<ProxyResult, String>("anonymity"));
column_google.setCellValueFactory(new PropertyValueFactory<ProxyResult, Boolean>("google"));
column_https.setCellValueFactory(new PropertyValueFactory<ProxyResult, Boolean>("https"));
column_lastchecked.setCellValueFactory(new PropertyValueFactory<ProxyResult, String>("lastChecked"));
column_response.setCellValueFactory(new PropertyValueFactory<ProxyResult, Long>("responseTime"));
}
public void handleSearchButton(ActionEvent event) {
Service<Void> searchWorker = new SearchProxyWorker(pb_search, data);
searchWorker.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override
public void handle(WorkerStateEvent event) {
System.out.println("Tadaaa");
}
});
searchWorker.start();
}
/**
* Set the current scene.
*
* #param scene A scene
*/
public void setScene(Scene scene) {
this.scene = scene;
}
}

Related

Javafx tableview checkbox to hide unwanted rows?

I'm trying to do some reports by hiding some rows from a tableview (I made in scenebuilder) by using a checkbox. If the object from tableview doesn't have in the column a specific String, it becomes invisible. example: By clicking the checkbox, hide all rows that dont have the exact value "Barcelona" in table_adress. I tried to do this, but I keep complicating myself. Any ideas?
the function
#FXML
void CakeRequestsFromBarcelona(ActionEvent event) throws IOException {
for(Object cake:table.getItems()) {
for (TableColumn column : table.getColumns()) {
//not sure how to write it
}
}
}
initialize
#FXML
private TableColumn<CakeRequest, Integer> table_ID;
#FXML
private TableColumn<CakeRequest, String> table_adress;
#FXML
private TableColumn<CakeRequest, String> table_design;
#FXML
private TableColumn<CakeRequest, String> table_flavour;
#FXML
private TableColumn<CakeRequest, String> table_model;
#FXML
private TableColumn<CakeRequest, String> table_name;
#FXML
private TableColumn<CakeRequest, String> table_phonenumber;
#FXML
private TableView<CakeRequest> table;
public void initialize(){
//cakeRequest
table_ID.setCellValueFactory(
p-> new SimpleIntegerProperty(p.getValue().getID()).asObject()
);
table_name.setCellValueFactory(
p -> new SimpleStringProperty(p.getValue().getOwnerName())
);
table_adress.setCellValueFactory(
p -> new SimpleStringProperty(p.getValue().getOwnerAddress())
);
table_phonenumber.setCellValueFactory(
p -> new SimpleStringProperty(p.getValue().getPhoneNumber())
);
table_flavour.setCellValueFactory(
p -> new SimpleStringProperty(p.getValue().getFlavour())
);
table_design.setCellValueFactory(
p -> new SimpleStringProperty(p.getValue().getDesign())
);
table_model.setCellValueFactory(
p -> new SimpleStringProperty(p.getValue().getModel())
);
}
CakeRequest
public class CakeRequest implements Identifiable<Integer>, Serializable{
private int ID;
private String OwnerName;
private String OwnerAddress;
private String PhoneNumber;
private String Model;
private String Flavour;
private String Design;
Use a FilteredList and change the predicate when the check box is checked/unchecked:
private ObservableList<CakeRequest> data = FXCollections.observableArrayList();
private FilteredList<CakeRequest> filteredData = new FilteredList<>(data, request -> true);
public void initialize(){
// existing code...
table.setItems(filteredData);
}
#FXML
void cakeRequestsFromBarcelona(ActionEvent event) {
if (checkBox.isChecked()) {
filteredData.setPredicate(request -> request.getOwnerAddress().contains("Barcelona"));
} else {
filteredData.setPredicate(request -> true);
}
}

JavaFX run a method once a specified key is pressed

I am trying to run a method in a controller class specified to a particular task, once a specified key is pressed using KeyListener. But i'm unable to detect the keypress and invoke the java.awt.event keyPressed method. My code is as follows :
public class POSController implements KeyListener {
#Override
public void keyPressed(java.awt.event.KeyEvent e) {
if (e.getKeyCode() == com.sun.glass.events.KeyEvent.VK_F1) {
try {
paymentAction();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
What could have gone wrong? Thanks in advance.
Here is the minimal executable example of the problem.
public class POSController implements KeyListener {
#FXML
private TableView<Product> productTableView;
#FXML
private TableView<Item> listTableView;
#FXML
private MenuItem logoutItem, profile;
#FXML
private javafx.scene.image.ImageView backImage;
#FXML
private MenuButton menuButton;
#FXML
private TableColumn<Item, String> itemColumn;
#FXML
private ComboBox<String> clientId, paymentMethod;
#FXML
private TableColumn<Item, Double> priceColumn, totalColumn, discountPercentageColumn, amountColumn;
#FXML
private TableColumn<Item, Integer> quantityColumn;
#FXML
private TableColumn<Product, String> productColumn;
#FXML
private TextField searchField,discountPercentage,productField,priceField,quantityField,vatPercentage,subTotalField,discountField,totalVatField,vatField,netPayableField,totalDiscountField;
#FXML
private TextField ;
#FXML
private TextField ;
#FXML
private TextField ;
#FXML
private TextField ;
#FXML
private TextArea descriptionArea;
#FXML
private Button addButton, removeButton, paymentButton, resetTableButton, resetButton;
#FXML
private Label quantityLabel, errorLabel, userName, backLabel;
#FXML
private ObservableList<Item> ITEMLIST;
public static Scene paymentScene;
private double xOffset = 0;
private double yOffset = 0;
public static double finalNetPayablePrice = 0.0;
public static double finalSubTotalPrice = 0.0;
public static double finalVat = 0.0;
public static double finalDiscount = 0.0;
public static String clientName = null;
public static String selectedPaymentMethod = null;
public static List<String> itemNames = new ArrayList<>();
public static List<Double> itemDiscounts = new ArrayList<>();
public static List<String> prices = new ArrayList<>();
public static List<String> quantities = new ArrayList<>();
public static List<String> subTotals = new ArrayList<>();
public static ObservableList<Item> itemList;
public static List<String> columnItemData = new ArrayList<>();
public static List<String> columnQuantityData = new ArrayList<>();
#FXML
private void initialize() throws SQLException, ClassNotFoundException, IOException {
ObservableList<Product> productsData = ProductDAO.searchGoodProducts(app.values.getProperty("STATUS_TYPE1"));
populateProducts(productsData);
}
#FXML
private void populateProducts(ObservableList<Product> productData) throws ClassNotFoundException {
productTableView.setItems(productData);
}
#Override
public void keyTyped(java.awt.event.KeyEvent e) {
}
#Override
public void keyPressed(java.awt.event.KeyEvent e) {
if (e.getKeyCode() == java.awt.event.KeyEvent.VK_F1) {
try {
paymentAction();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
#Override
public void keyReleased(java.awt.event.KeyEvent e) {
}
#FXML
public void paymentAction() throws Exception {
if (validateInputsForPayment()) {
Payment payment = new Payment();
FXMLLoader loader = new FXMLLoader((getClass().getResource(app.values.getProperty("INVOICE_VIEW_LOCATION"))));
Parent root = loader.load();
Stage stage = new Stage();
root.setOnMousePressed((MouseEvent e) -> {
xOffset = e.getSceneX();
yOffset = e.getSceneY();
});
root.setOnMouseDragged((MouseEvent e) -> {
stage.setX(e.getScreenX() - xOffset);
stage.setY(e.getScreenY() - yOffset);
});
Scene scene = new Scene(root);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initStyle(StageStyle.UNDECORATED);
stage.setScene(scene);
this.paymentScene = scene;
stage.showAndWait();
}
}
You shouldn't be using java.awt.event.KeyListener for a JavaFX application. JavaFX has its own set of event API.
Assuming that POSController is a controller class for a particular FXML:
public class POSController {
#FXML private BorderPane root; // Or any other Node from FXML file
#FXML private void initialize() {
javafx.event.EventHandler<javafx.scene.input.KeyEvent> handler = event -> {
if (event.getCode() == javafx.scene.input.KeyCode.F1) {
try {
paymentAction();
} catch (Exception e1) {
e1.printStackTrace();
}
}
};
// I'm using root to get scene, but any node would be fine
if (root.getScene() != null) {
root.getScene().addEventHandler(javafx.scene.input.KeyEvent.KEY_PRESSED, handler);
}
else {
root.sceneProperty().addListener((obs, oldScene, newScene) -> {
if (newScene != null) {
root.getScene().addEventHandler(javafx.scene.input.KeyEvent.KEY_PRESSED, handler);
}
});
}
}
}
This will add the key event to the Scene. If you do not need to apply this event scene-wide, then you can add the event handler at other appropriate nodes.
Update
If there are any input controls in the scene, then you may need to use setEventFilter() instead of setEventHandler(). This is because those controls are probably going to consume the key event during the event bubbling phase.

Get two Database Table Values to One JavaFX TreeTable

I have two classes Customer and Product.i stored this class values in database as a two table one for customer other for product. i use inner join for retrieve this data.i want to show this data in JavaFX TreeTable.there is plenty of tutorial but they only works for one class.this my code so far but it not working.im not javaFX pro.
Connection con;
PreparedStatement ps;
ResultSet rs;
#FXML
private JFXButton close;
#FXML
private JFXTreeTableView<Product> detailsTable;
#FXML
private JFXComboBox<String> searchStatus;
#FXML
private JFXComboBox<String> searchLocation;
#FXML
private TreeTableColumn<Customer, String> cname;
#FXML
private TreeTableColumn<Customer, String> cnic;
#FXML
private TreeTableColumn<Customer, String> cphone;
#FXML
private TreeTableColumn<Product, String> pbrand;
#FXML
private TreeTableColumn<Product, String> ptype;
#FXML
private TreeTableColumn<Product, Integer> prcc;
#FXML
private TreeTableColumn<Product, String> plocation;
#FXML
private TreeTableColumn<Product, String> pshoptype;
#FXML
private TreeTableColumn<String, Date> pdate;
#FXML
void OnClickSearch(KeyEvent event) {
}
#FXML
void searchByLocation(ActionEvent event) {
}
#FXML
void searchByStatus(ActionEvent event) {
}
private ObservableList<Customer> cData;
private ObservableList<Product> pData;
#Override
public void initialize(URL url, ResourceBundle rb) {
#Override
public void initialize(URL url, ResourceBundle rb) {
con= DBConnect.connect();
cData=FXCollections.observableArrayList();
pData= FXCollections.observableArrayList();
try {
rs=con.createStatement().executeQuery("SELECT c.customerName,c.customerNic,c.customerPhone,p.productBrand,p.productType,p.productRcc,p.productLocation,p.productShopType,p.productDate From customer as c INNER JOIN product as p ON c.customerId=p.customerId ");
} catch (SQLException e) {
System.out.println("GET DATA TO TABLE ERROR");
e.printStackTrace();
}
try {
while(rs.next()){
//pData.add(rs.getString(1),rs.getString(2),rs.getString(3),rs.getString(4),rs.getString(5),rs.getInt(6),rs.getString(7),rs.getString(8),rs.getDate(9));
cData.add(new Customer(rs.getString(1),rs.getString(2),rs.getString(3)));
pData.add(new Product (rs.getString(4),rs.getString(5),rs.getInt(6),rs.getString(7),rs.getString(8),rs.getDate(9)));
}
} catch (SQLException e) {
System.out.println("RS.Next() Error");
e.printStackTrace();
}
cname.setCellValueFactory(new PropertyValueFactory<Customer,String>("customerNam"));
cnic.setCellValueFactory(new PropertyValueFactory<Customer,String>("nic"));
cphone.setCellValueFactory(new PropertyValueFactory<Customer,String>("phone"));
pbrand.setCellValueFactory(new PropertyValueFactory<Product,String>("brand"));
ptype.setCellValueFactory(new PropertyValueFactory<Product,String>("type"));
prcc.setCellValueFactory(new PropertyValueFactory<Product,Integer>("rccNo"));
plocation.setCellValueFactory(new PropertyValueFactory<Product,String>("location"));
pshoptype.setCellValueFactory(new PropertyValueFactory<Product,String>("shopType"));
pdate.setCellValueFactory(new PropertyValueFactory<Customer,Date>("date"));
System.out.println("For Testing");
}

How to add data from Combo Box to Table Column using a Button in JavaFX?

So I have the following code:
public class ToDoListController implements Initializable {
String text = "";
LocalDate isoDate;
#FXML
private Button bttnAddEvent;
#FXML
private DatePicker pickerDate;
#FXML
private ComboBox<String> eventsSelector;
#FXML
private Button bttnDone;
#FXML
private Button bttnRemove;
#FXML
private TableView<EventsBean> eventsTable;
#FXML
private TableColumn<EventsBean, String> eventCol;
#FXML
private TableColumn<EventsBean, LocalDate> dateCol;
#FXML
private TableColumn<?, ?> doneCol;
#FXML
private TableColumn<?, ?> observationCol;
#FXML
private TableColumn<?, ?> removeCol;
#FXML
void bttnDoneAction(ActionEvent event) {
}
#FXML
void bttnRemoveAction(ActionEvent event) {
}
#FXML
void pickerDateAction(ActionEvent event) {
isoDate = pickerDate.getValue();
}
ObservableList<EventsBean> dataList =
FXCollections.observableArrayList();
#Override
public void initialize(URL location, ResourceBundle resources) {
System.out.println("The pane loaded");
List<String> myList;
try {
myList = Files.lines(Paths.get("src/com/todolist/EventsList.txt")).collect(Collectors.toList());
eventsSelector.setItems(FXCollections.observableArrayList(myList));
} catch (IOException e) {
System.out.println("Don t find file");
}
eventCol.setCellValueFactory(new PropertyValueFactory<EventsBean, String>("event"));
dateCol.setCellValueFactory(new PropertyValueFactory<EventsBean, LocalDate>("date"));
observationCol.setCellValueFactory(new PropertyValueFactory<EventsBean, String>("observation"));
observationCol.setCellFactory(TextFieldTableCell.<EventsBean>forTableColumn());
observationCol.setOnEditCommit(
(CellEditEvent<EventsBean, String> t) -> {
((EventsBean) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setObservation(t.getNewValue());
});
observationCol.setSortable(false);
eventsTable.setItems(dataList);
eventsTable.setEditable(true);
bttnAddEvent.setOnAction((ActionEvent e) -> {
text = eventsSelector.getValue().toString();
dataList.add(new EventsBean(text, isoDate, ""));
});
}
}
and my EventsBean class:
public class EventsBean {
private SimpleStringProperty observation;
private SimpleStringProperty event;
private SimpleObjectProperty<LocalDate> date;
public EventsBean(String event, LocalDate date, String observation) {
this.event = new SimpleStringProperty(event);
this.date = new SimpleObjectProperty<LocalDate>(date);
this.observation = new SimpleStringProperty(observation);
}
public String getEvent() {
return event.get();
}
public LocalDate getDate() {
return date.get();
}
public String getObservation() {
return observation.get();
}
public void setObservation(String observation) {
this.observation.set(observation);
}
}
As you can see, I populate the ComboBox with data from a text file.
So I want to use Button bttnAddEvent to add a selected data from ComboBox in TableColumn <?,?> eventCol. Beside this, another challenge it is to use the same Button bttnAddEvent in the same time with data from ComboBox to add the selected date from DatePicker pickerDate in TableColumn <?,?> dateCol.
Update: Until now I put the value of ComboBox into a String named text, but how to transfer into TableColumn eventCol this value from text?
Thank you very much!
I've found the solution and updated the code for someone who will meet this need.

JavaFX : tableview won't populate from database (ucanaccess)

My application contains a tabpane, each tab is a nested fxml with controller included.
Each fxml file have a tableview that retrieve data from a microsoft access database.
Some of the tables that only have string columns work and get populated but another one(Demandes) that have a integer column and a localdate column wont populate.and i don't know what's causing the problem.
here the nested controller of "Demandes" tab:
public class DemandesController{
#FXML
private TableView<Demande> demandesTable;
#FXML
private TableColumn<Demande, Integer> numColumn;
#FXML
private TableColumn<Demande, String> societeColumn;
#FXML
private TableColumn<Demande, LocalDate> dateDemandeColumn;
#FXML
private TableColumn<Demande, LocalDate> dateSignatureColumn;
#FXML
private TableColumn<Demande, String> villeColumn;
private ObservableList<Demande> demandes = FXCollections.observableArrayList();
private MainApp mainApp;
String BD_URL = mainApp.getBdUrl();
public DemandesController(){
}
public ObservableList<Demande> getBulletins(){
return demandes;
}
#FXML
private void initialize() {
getDemandesData();
numColumn.setCellValueFactory(cellData -> cellData.getValue().numDemandeProperty().asObject());
societeColumn.setCellValueFactory(cellData -> cellData.getValue().societeProperty());
dateDemandeColumn.setCellValueFactory(cellData -> cellData.getValue().dateDemandeProperty());
dateSignatureColumn.setCellValueFactory(cellData -> cellData.getValue().dateSignatureProperty());
villeColumn.setCellValueFactory(cellData -> cellData.getValue().villeProperty());
}
public void setMainApp(MainApp mainApp){
this.mainApp = mainApp;
demandesTable.setItems(getBulletins());
}
public void getDemandesData(){
Task task = new Task<Void>() {
#Override
protected Void call() throws Exception {
try (Connection con = DriverManager.getConnection(BD_URL)) {
Statement stmt = con.createStatement();
ResultSet res = stmt.executeQuery("SELECT * FROM [Demandes-tab]");
while (res.next()) {
int numDemande = res.getInt(1);
String societe = res.getString(2);
LocalDate dateDemande = res.getDate(3)
.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate dateSignature = res.getDate(4)
.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
String ville = res.getString(5);
demandes.add(new Demande(numDemande,societe,dateDemande,
dateSignature,ville));
}
}return null;
}
};
new Thread(task).start();
} }
and the parent controller that initialise the nested fxmls and controllers :
public class TabsController{
private MainApp mainApp;
#FXML private AnchorPane Bulletins;
#FXML private BulletinsController BulletinsController;
#FXML private AnchorPane Demandes;
#FXML private DemandesController DemandesController;
#FXML private AnchorPane Personneltest;
#FXML private PersonnelController PersonneltestController;
#FXML private AnchorPane Personnel;
#FXML private PersonnelController PersonnelController;
#FXML private AnchorPane Produit;
#FXML private ProduitController ProduitController;
#FXML private AnchorPane Societes;
#FXML private SocietesController SocietesController;
#FXML
private void initialize() {
}
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
BulletinsController.setMainApp(mainApp);
PersonneltestController.setMainApp(mainApp);
DemandesController.setMainApp(mainApp);
} }
also this was added in the right place :
<Tab text="Demandes">
<content>
<fx:include fx:id="Demandes" source="Demandes.fxml" />
</content>
</Tab>
if someone can tell me why the tableview won't populate that will be a big help. thank you.
ps: oh also i removed the database url just to see if it matters and nothing changed. does that mean that it doesn't connect to the database at all?

Resources