either i am looking at it for to long... or i did not really understand it.
In any case i am trying to fill a tableview that has been created using fxml (inc. Columns) with data.
My Code works for the first (Title) column but not for the rest.
(Yes "data" has all the info in it... checked with debug.)
So can any1 tell me what i am doing wrong??
Here (hopefully all relevant) code (copied together):
#FXML private TableColumn<sresult,String> cl_title;
#FXML private TableColumn<sresult, String> cl_url;
#FXML private TableColumn<sresult, String> cl_poster;
#FXML private TableColumn<sresult, String> cl_date;
#FXML private TableColumn<sresult, String> cl_forum;
String[][] search_res=null;
try {
search_res= search(tf_search.getText());
} catch (MalformedURLException | SolrServerException | ParseException ex) {
Logger.getLogger(MainUiController.class.getName()).log(Level.SEVERE, null, ex);
}
final ObservableList<sresult> data= FXCollections.observableArrayList();
for ( String[] s : search_res){
data.add(new sresult(s[0], s[2],s[3],s[4],s[1]));
}
cl_title.setCellValueFactory(
new PropertyValueFactory<sresult,String>("Title"));
cl_poster.setCellValueFactory(
new PropertyValueFactory<sresult,String>("poster"));
cl_date.setCellValueFactory(
new PropertyValueFactory<sresult,String>("date"));
cl_forum.setCellValueFactory(
new PropertyValueFactory<sresult,String>("forum"));
cl_url.setCellValueFactory(
new PropertyValueFactory<sresult,String>("link"));
tb_results.setItems(data);
public class sresult {
private final SimpleStringProperty Title;
private final SimpleStringProperty poster;
private final SimpleStringProperty date;
private final SimpleStringProperty forum;
private final SimpleStringProperty link;
public sresult(String T, String p, String d, String f, String l) {
this.Title = new SimpleStringProperty(T);
this.poster = new SimpleStringProperty(p);
this.date = new SimpleStringProperty(d);
this.forum = new SimpleStringProperty(f);
this.link = new SimpleStringProperty(l);
}
public String getTitle() {
return Title.get();
}
public void setTitle(String T) {
Title.set(T);
}
public String getposter() {
return poster.get();
}
public void setposter(String p) {
poster.set(p);
}
public String getdate() {
return date.get();
}
public void setdate(String d) {
date.set(d);
}
public String getforum() {
return forum.get();
}
public void setforum(String f) {
forum.set(f);
}
public String getlink() {
return link.get();
}
public void setlink(String l) {
link.set(l);
}
}
Thank you!
Ok,
This was simular enough for me to get the answer.
The getter and setters need to have a Capital letter after get/set.
e.g. public String getTitle() vs public String gettitle()
not really sure why java is forcing this...
Anyway thanks to jewelsea for his answer on the other question.
Related
//Database is Sucessfully Connected
I am trying to Create a table in which I want to display the contents of my 'student' table in tableView of Javafx but I could not get the desired output.
ObservableList<Student> list = FXCollections.observableArrayList();
#FXML
//Initializes the controller class.
#Override
public void initialize(URL url, ResourceBundle rb)
{
// TODO
initCol();
loadTable();
}
//A view Table has been made with fx:id-table
//Variable name for 2 columns are 'fx:id-rollnoColand' & 'fx:id-nameCol'
#FXML
private TableView<Student> table;
#FXML
private TableColumn<Student,String> rollnoCol;
#FXML
private TableColumn<Student,String> nameCol;
private void initCol()
{
rollnoCol.setCellValueFactory(new PropertyValueFactory<>("s_rollno"));
nameCol.setCellValueFactory(new PropertyValueFactory<>("s_name"));
}
//Name of the Table is 'student' with Columns 'rollno' and 'name'
private void loadTable()
{
String selectAll = "select * from student";
try
{
Statement stmt = connectdb.createStatement();
ResultSet rs = stmt.executeQuery(selectAll);
while(rs.next())
{
String getrollno = rs.getString("rollno");
String getname = rs.getString("name");
list.add(new Student(getrollno,getname));
}
}
catch(SQLException exp)
{
System.out.println(exp);
}
table.getItems().setAll(list);
}
public static class Student
{
private final String s_rollno;
private final String s_name;
Student(String rollno,String name)
{
this.s_rollno = rollno;
this.s_name = name;
}
}
PropertyValueFactory works with getters or property methods. In your case you need to add getters for your properties in the Student class to enable PropertyValueFactory to retrieve the values:
public static class Student {
private final String s_rollno;
private final String s_name;
Student(String rollno, String name) {
this.s_rollno = rollno;
this.s_name = name;
}
public String getS_rollno() {
return s_rollno;
}
public String getS_name() {
return s_name;
}
}
I had this problem before,and it has many reason.First ,you may remove final keyword from your model,because your variables are changing.Second, TableView shows empty cells because you make your variables private in class Student and you can not access them from init method in parent class.So you need add getter and setter methods for access to these variables.
public static class Student
{
private String s_rollno;
private String s_name;
Student(String rollno,String name)
{
this.s_rollno = rollno;
this.s_name = name;
}
public String getS_rollno() {
return s_rollno;
}
public void setS_rollno(String s_rollno) {
this.s_rollno = s_rollno;
}
public String getS_name() {
return s_name;
}
public void setS_name(String s_name) {
this.s_name = s_name;
}
}
I spent full day to make my model observable by this JavaFx databinding.
At this point I already see, that if I change one property like this, it works like charm
selectedTestcase.setFolder("....");
but how I can observe the following and refresh my form:
if (maybeCase.isPresent()) {
selectedTestcase = maybeCase.get();
}
So I change the complete model. How I can make this?
Model:
#XmlRootElement(name = "Testcase")
#XmlAccessorType(XmlAccessType.PROPERTY)
public class Testcase {
private StringProperty Guid;
#XmlElement(name="GUID")
public String getGuid() {
return guidProperty().get();
}
public StringProperty guidProperty() {
if (Guid == null)
Guid = new SimpleStringProperty(this, "Guid");
return Guid;
}
public void setGuid(String guid) {
this.guidProperty().set(guid);
}
private StringProperty caseName;
#XmlElement(name="CaseName")
public String getCaseName() {
return caseNameProperty().get();
}
public StringProperty caseNameProperty() {
if (caseName == null)
caseName = new SimpleStringProperty();
return caseName;
}
public void setCaseName(String caseName) {
this.caseNameProperty().set(caseName);
}
ViewModel:
public Testcase selectedTestcase = new Testcase();
public void setSelectedTestcase(String folder, String filename) {
Optional<Testcase> maybeCase = this.AvailableTestCases.stream()
.filter((t -> t.TestcaseEqualsFolderAndName(folder, filename))).findFirst();
if (maybeCase.isPresent()) {
selectedTestcase = maybeCase.get();
}
}
Thanks in advance :)
Thanks to James_D and the Easybind Library:
MonadicObservableValue
That seems to be the solution:
private ObjectProperty<Testcase> testcaseObjectProperty = new SimpleObjectProperty<>(new Testcase());
public MonadicObservableValue<Testcase> selectedTestcase = EasyBind.monadic(testcaseObjectProperty);
public void setSelectedTestcase(String folder, String filename) {
Optional<Testcase> maybeCase = this.AvailableTestCases.stream()
.filter((t -> t.TestcaseEqualsFolderAndName(folder, filename))).findFirst();
if (maybeCase.isPresent()) {
testcaseObjectProperty.setValue(maybeCase.get());
}
}
and then the final binding:
txtCaseName.textProperty().bind(viewModel.selectedTestcase.flatMap(Testcase::caseNameProperty).orElse(""));
James; you are able to explain me this "orElse"?
I have this model:
public class AbstractMappingRow {
private StringProperty abstractService = new SimpleStringProperty();
private StringProperty taskId = new SimpleStringProperty();
private StringProperty taskName = new SimpleStringProperty();
public AbstractMappingRow(String taksNameString, String taskIdString, String abstractServiceString) {
super();
this.abstractService = new SimpleStringProperty(abstractServiceString);
this.taskId = new SimpleStringProperty(taskIdString);
this.taskName = new SimpleStringProperty(taksNameString);
}
public StringProperty getAbstractService() {
return abstractService;
}
public void setAbstractService(StringProperty abstractService) {
this.abstractService = abstractService;
}
public StringProperty getTaskId() {
return taskId;
}
public void setTaskId(StringProperty taskId) {
this.taskId = taskId;
}
public StringProperty getTaskName() {
return taskName;
}
public void setTaskName(StringProperty taskName) {
this.taskName = taskName;
}
}
I am trying to have a table row [ String - String - ComboBox with Strings ]. So I set up the table like this:
TableColumn<AbstractMappingRow,String> taskIdCol = new TableColumn<>("Task ID");
taskIdCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<AbstractMappingRow, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<AbstractMappingRow, String> p) {
return p.getValue().getTaskId();
}
});
mappingTable.getColumns().add(taskIdCol);
TableColumn<AbstractMappingRow,String> taskNameCol = new TableColumn<>("Task Name");
taskNameCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<AbstractMappingRow, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<AbstractMappingRow, String> p) {
return p.getValue().getTaskName();
}
});
mappingTable.getColumns().add(taskNameCol);
TableColumn<AbstractMappingRow, String> abstractServiceCol = new TableColumn<>("Abstrakter Dienst");
abstractServiceCol.setMinWidth( 200 );
abstractServiceCol.setCellValueFactory(cellData -> cellData.getValue().getAbstractService());
abstractServiceCol.setCellFactory(ComboBoxTableCell.<AbstractMappingRow, String>forTableColumn(FXCollections.observableArrayList("1", "3")));
mappingTable.getColumns().add(abstractServiceCol);
mappingTable.getItems().add(new AbstractMappingRow("test", "test", "3"));
But as a result, I do not see any ComboBox in the third column which is supposed to contain the values "1" and "3". Instead, I see this:
What am I missing to make the ComboBox show up? Thanks!
I found the mistake: I forgot to set
mappingTable.setEditable(true);
Thanks!
I have an object Contract and it contains Summary and Observable List of another object ContractDetails inside it.
Now, I am using ContractDetails to populate in tableview from Contract object.
I have a save button, which on clicking needs to save Contract along with ContractDetails. I am able to access ContractDetails since they are in tableview.
How do I access Contract properties in eventlistener of save button.
The related code is given below
public class Contract {
private String tradeDate;
private String contractNote;
.....
.....
private String brokerId;
private ObservableList<ContractDetails> contractdetails = FXCollections.observableArrayList();
public Contract() {
}
public Contract(String tradeDate, String contractNote, ....., String brokerId,ObservableList<ContractDetails> contractdetails) {
this.tradeDate = tradeDate;
this.contractNote = contractNote;
....
....
this.contractdetails=contractdetails;
}
public String getTradeDate() {
return tradeDate;
}
public void setTradeDate(String tradeDate) {
this.tradeDate = tradeDate;
}
public String getContractNote() {
return contractNote;
}
public void setContractNote(String contractNote) {
this.contractNote = contractNote;
}
....
....
public ObservableList<ContractDetails> getContractdetails() {
return contractdetails;
}
public void setContractdetails(ObservableList<ContractDetails> contractdetails) {
this.contractdetails = contractdetails;
}
}
public class ContractDetails {
private String orderNo;
private String contractType;
private String symbol;
private String buysell;
private Integer quantity;
private Double buysellprice;
private Double netcontractValue;
public ContractDetails() {
}
public ContractDetails(String orderNo, String contractType, String symbol, String buysell, Integer quantity, Double buysellprice, Double netcontractValue) {
this.orderNo = orderNo;
this.symbol = symbol;
this.buysell = buysell;
this.quantity = quantity;
this.buysellprice = buysellprice;
this.netcontractValue = netcontractValue;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
....
....
public Double getNetcontractValue() {
return netcontractValue;
}
public void setNetcontractValue(Double netcontractValue) {
this.netcontractValue = netcontractValue;
}
}
In the controller
==================
public class ContractViewController implements Initializable {
#FXML
private TableView<ContractDetails> tblcontractfx;
#FXML
private TableColumn<ContractDetails, String> contractTypefx;
#FXML
private TableColumn<ContractDetails, String> symbolfx;
....
....
#FXML
private Button savefx;
#FXML
private TextField txtclientcodefx;
#FXML
private TextField txttradedtfx;
private void fetchContracts(TableView tableView, Contract contract)
{ txttradedtfx.setText(contract.getTradeDate());
txtclientcodefx.setText(contract.getClientCode());
symbolfx.setCellValueFactory(new PropertyValueFactory<ContractDetails, String>("symbol"));
contractTypefx.setCellValueFactory(new PropertyValueFactory<ContractDetails, String>("contractType"));
tableView.setItems((ObservableList) contract.getContractdetails());
#FXML
private void saveClicked(ActionEvent event) { DBConnection DBcon = new DBConnection();
//Now I am getting the contract details from tableview tblcontractfx
ObservableList<ContractDetails> contractdetails = tblcontractfx.getItems();
//How do I get the summary values from contract. I am able to get those which are in text fields like txttradedtfx and txtclientcodefx.However contractNote which I am not using, I still need to retrieve it to populate into database.
String clientCode=txtclientcodefx.getText();
Thanks
Just store the contract in a local variable.
Contract contract;
private void fetchContracts(TableView tableView, Contract contract)
{
this.contract = contract;
...
}
private void saveClicked(ActionEvent event) {
// here you have full access to the contract variable
String contractNote = contract.getContractNote();
}
As an alternative, if you insist on combining it all in a single table, you could put the Contract into the table via setUserData and retrieve it via getUserData.
By the way, I still don't get your code. Why is there a tableView parameter when you have full access to TableView<ContractDetails> tblcontractfx
I have tables with editable fields item,Description,Quantity,Unit price and Sub Total.
I am creating a cellFactory and Column Update like this:
TableColumn DescriptionCol = new TableColumn("Description");
EditableTableSupport.createEditingColumn(DescriptionCol,"description");
TableColumn QuantityCol = new TableColumn("Quantity");
EditableTableSupport.createEditingColumn(QuantityCol,"quantity");
TableColumn UnitPriceColumn = new TableColumn<>("Unit Price");
EditableTableSupport.createEditingColumn(UnitPriceColumn,"unitPrice");
TableColumn DiscountColumn = new TableColumn<>("Discount");
EditableTableSupport.createEditingColumn(DiscountColumn,"discount");
SubTotalColumn = new TableColumn<>("SubTotal");
EditableTableSupport.createColumn(SubTotalColumn,"subTotal");
TableColumn SubTotalColumn = new TableColumn<>("SubTotal");
EditableTableSupport.createColumn(SubTotalColumn,"subTotal");
DescriptionCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<DUMMY_PurchaseOrderLine, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<DUMMY_PurchaseOrderLine, String> t) {
((DUMMY_PurchaseOrderLine) t.getTableView().getItems().get(t.getTablePosition().getRow())).setDescription(t.getNewValue());
}
});
QuantityCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<DUMMY_PurchaseOrderLine, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<DUMMY_PurchaseOrderLine, String> t) {
((DUMMY_PurchaseOrderLine) t.getTableView().getItems().get(t.getTablePosition().getRow())).setQuantity(t.getNewValue());
}
});
UnitPriceColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<DUMMY_PurchaseOrderLine, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<DUMMY_PurchaseOrderLine, String> t) {
((DUMMY_PurchaseOrderLine) t.getTableView().getItems().get(t.getTablePosition().getRow())).setUnitPrice(t.getNewValue());
}
});
DiscountColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<DUMMY_PurchaseOrderLine, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<DUMMY_PurchaseOrderLine, String> t) {
((DUMMY_PurchaseOrderLine) t.getTableView().getItems().get(t.getTablePosition().getRow())).setDiscount(t.getNewValue());
}
});
public class EditableTableSupport {
public static void createEditingColumn(TableColumn Column ,String name){
Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() {
#Override
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
Column.setSortable(false);
Column.setCellValueFactory(new PropertyValueFactory<DUMMY_PurchaseOrderLine, String>(name));
Column.setCellFactory(cellFactory);
}
public static void createColumn(TableColumn Column, String name) {
Column.setSortable(false);
Column.setCellValueFactory(new PropertyValueFactory<DUMMY_PurchaseOrderLine, String>(name));
}}
Question:How to Update Subtotal Column When i updating Quantity Column or UnitPrice Column
Thank you..
public class DUMMY_PurchaseOrderLine {
private String name;
private String description;
private BigDecimal quantity;
private BigDecimal unitPrice;
private BigDecimal discount;
private BigDecimal subTotal;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public BigDecimal getQuantity() {
return quantity;
}
public void setQuantity(BigDecimal quantity) {
this.quantity = quantity;
}
public BigDecimal getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(BigDecimal unitPrice) {
this.unitPrice = unitPrice;
}
public BigDecimal getDiscount() {
return discount;
}
public void setDiscount(BigDecimal discount) {
this.discount = discount;
}
public BigDecimal getSubTotal() {
return subTotal;
}
public void setSubTotal(BigDecimal subTotal) {
this.subTotal = subTotal;
}
public DUMMY_PurchaseOrderLine(String name, BigDecimal description, BigDecimal quantity,BigDecimal unitPrice,BigDecimal discount,BigDecimal subTotal) {
this.name = name;
this.description = description;
this.quantity = quantity;
this.unitPrice = unitPrice;
this.discount = discount;
this.subTotal = quantity.multiply(unitPrice).subtract(discount);
}
}
In your DUMMY_PurchaseOrderLine class create a read only property named subTotal and initialize it in the constructor via binding. The combination of the binding and the PropertyValueFactory you use to set the value for the SubTotalColumn will ensure that the correct subtotal is always reflected.
class DUMMY_PurchaseOrderLine {
private IntegerProperty quantity = new SimpleIntegerProperty(0);
private DoubleProperty unitPrice = new SimpleDoubleProperty(0);
private DoubleProperty discount = new SimpleDoubleProperty(0);
private ReadOnlyDoubleWrapper subTotal = new ReadOnlyDoubleWrapper(0);
DUMMY_PurchaseOrderLine() {
subTotal.bind(quantity.multiply(unitPrice).subtract(discount));
}
IntegerProperty quantityProperty() { return quantity; }
IntegerProperty unitPriceProperty() { return unitPrice; }
IntegerProperty discountProperty() { return discount; }
ReadOnlyDoubleProperty subTotalProperty() { return subTotal.getReadOnlyProperty(); }
}
Note the naming conventions used. Using the correct naming convention is key.
I'm assuming here that the subtotal is just the calculated value for a single row (specifically by quantity * unitPrice - discount), not a total of values calculated across multiple rows (which would be quite a difficult problem to solve with a TableView).
Update based on question edit
I see from your update that you are using BigDecimal and JavaFX doesn't have a corresponding BigDecimalProperty, so either you will need to create one (not trivial if you want it to be fully featured) or use one of the existing property types.
Your alternate to using properties is to use the low level binding api to calculate subtotals, but I'd advise using properties if you can.