I'm trying to insert data into a Javafx TableView, actually I did it, but it fills the row with the following String:
IntegerProperty [value: 72] and etc...
How can I show only the value fill in my rows??
My TableView code:
#FXML TableView tableView = new TableView<MetaDadosInfo>();
#FXML javafx.scene.control.TableColumn instituicaoCol;
#FXML javafx.scene.control.TableColumn anoCol;
#FXML javafx.scene.control.TableColumn tamanhoCol;
#FXML javafx.scene.control.TableColumn tipoCol;
#FXML javafx.scene.control.TableColumn nomeCol;
final ObservableList<MetaDadosInfo> data = FXCollections.observableArrayList(
new MetaDadosInfo(codigoInstituicao, ano, size, type, name));
instituicaoCol.setCellValueFactory(
new PropertyValueFactory<MetaDadosInfo, String>("codigoInstituicao"));
anoCol.setCellValueFactory(
new PropertyValueFactory<MetaDadosInfo, String>("ano"));
tamanhoCol.setCellValueFactory(
new PropertyValueFactory<MetaDadosInfo, String>("size"));
tipoCol.setCellValueFactory(
new PropertyValueFactory<MetaDadosInfo, String>("type"));
nomeCol.setCellValueFactory(
new PropertyValueFactory<MetaDadosInfo, String>("name"));
tableView.setItems(data);
MetaDadosInfo class:
public class MetaDadosInfo {
private SimpleIntegerProperty codigoInstituicao;
private SimpleIntegerProperty ano;
private SimpleLongProperty size;
private SimpleStringProperty type;
private SimpleStringProperty name;
public MetaDadosInfo(int codigoInstituicao, int ano, long size, String type, String name) {
this.codigoInstituicao = new SimpleIntegerProperty (codigoInstituicao);
this.ano = new SimpleIntegerProperty (ano);
this.size = new SimpleLongProperty (size);
this.type = new SimpleStringProperty (type);
this.name = new SimpleStringProperty (name);
}
public SimpleIntegerProperty getCodigoInstituicao() {
return codigoInstituicao;
}
public void setCodigoInstituicao(SimpleIntegerProperty codigoInstituicao) {
this.codigoInstituicao = codigoInstituicao;
}
public SimpleIntegerProperty getAno() {
return ano;
}
public void setAno(SimpleIntegerProperty ano) {
this.ano = ano;
}
public SimpleLongProperty getSize() {
return size;
}
public void setSize(SimpleLongProperty size) {
this.size = size;
}
public SimpleStringProperty getType() {
return type;
}
public void setType(SimpleStringProperty type) {
this.type = type;
}
public SimpleStringProperty getName() {
return name;
}
public void setName(SimpleStringProperty name) {
this.name = name;
}
}
The error was in getters and setters from my MetaDadosInfo class, the right way is:
public class MetaDadosInfo {
private SimpleIntegerProperty codigoInstituicao;
private SimpleIntegerProperty ano;
private SimpleLongProperty size;
private SimpleStringProperty type;
private SimpleStringProperty name;
public MetaDadosInfo(int codigoInstituicao, int ano, long size, String type, String name) {
this.codigoInstituicao = new SimpleIntegerProperty (codigoInstituicao);
this.ano = new SimpleIntegerProperty (ano);
this.size = new SimpleLongProperty (size);
this.type = new SimpleStringProperty (type);
this.name = new SimpleStringProperty (name);
}
public int getCodigoInstituicao() {
return codigoInstituicao.get();
}
public void setCodigoInstituicao(int codigoInstituicao) {
this.codigoInstituicao.set(codigoInstituicao);
}
public int getAno() {
return ano.get();
}
public void setAno(int ano) {
this.ano.set(ano);
}
public Long getSize() {
return size.get();
}
public void setSize(long size) {
this.size.set(size);
}
public String getType() {
return type.get();
}
public void setType(String type) {
this.type.set(type);
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
}
After wasting my day i finally able to find the solution in very easy way
package test;
import java.util.HashMap;
import java.util.Map;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.MapValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;
public class Test extends Application {
public static final String Column1MapKey = "A";
public static final String Column2MapKey = "B";
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(300);
stage.setHeight(500);
final Label label = new Label("Student IDs");
label.setFont(new Font("Arial", 20));
TableColumn<Map, String> firstDataColumn = new TableColumn<>("Class A");
TableColumn<Map, String> secondDataColumn = new TableColumn<>("Class B");
firstDataColumn.setCellValueFactory(new MapValueFactory(Column1MapKey));
firstDataColumn.setMinWidth(130);
secondDataColumn.setCellValueFactory(new MapValueFactory(Column2MapKey));
secondDataColumn.setMinWidth(130);
TableView table_view = new TableView<>();
table_view.setItems(generateDataInMap());
table_view.setEditable(true);
table_view.getSelectionModel().setCellSelectionEnabled(true);
table_view.getColumns().setAll(firstDataColumn, secondDataColumn);
// Callback<TableColumn<Map, String>, TableCell<Map, String>> cellFactoryForMap = new Callback<TableColumn<Map, String>, TableCell<Map, String>>() {
// #Override
// public TableCell call(TableColumn p) {
// return new TextFieldTableCell(new StringConverter() {
// #Override
// public String toString(Object t) {
// return t.toString();
// }
//
// #Override
// public Object fromString(String string) {
// return string;
// }
// });
// }
// };
// firstDataColumn.setCellFactory(cellFactoryForMap);
// secondDataColumn.setCellFactory(cellFactoryForMap);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table_view);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
private ObservableList<Map> generateDataInMap() {
int max = 10;
ObservableList<Map> allData = FXCollections.observableArrayList();
for (int i = 1; i < max; i++) {
Map<String, String> dataRow = new HashMap<>();
String value1 = "A" + i;
String value2 = "B" + i;
dataRow.put(Column1MapKey, value1);
dataRow.put(Column2MapKey, value2);
allData.add(dataRow);
}
return allData;
}
}
just try to change and use it in your way it can also be used directly in resultset
Happy Coding, Happy Innovation
This doesn't work with PropertyValueFactory because you have not declared your JavaFX beans with the expected naming conventions for the properties you have defined in your data model.
Refer to this post for how to use PropertyValueFactory correctly: How to use the PropertyValueFactory correctly?
Related
I want to reproduce that combobox in JavaFX
With swing there is a way by using a renderer where HTML code can be passed.
I haven't found a way yet to do it in JAVAFX. I saw the cellFactory but it seems to handle only one line of text.
I tried to use an observableList of WebView. I was able to display the information as desired, but then the onAction was never called. I tried by setting an event and a listener, but nothing worked. I tried the next examples separately.
cbOrderLine.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<WebView>() {
#Override
public void changed(ObservableValue<? extends WebView> arg0, WebView arg1, WebView arg2) {
int uasbdviadn = 0;
if (arg2 != null) {
System.out.println("Selected employee: " + arg2.getId() + " " + uasbdviadn);
}
}
});
cbOrderLine.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent ev) {
int index = cbOrderLine.getSelectionModel().getSelectedIndex();
initComboBox(index);
}
});
this is the code to create my dummy values
private List<WebView> createListFakeOrderLineItem() {
List<WebView> list = new ArrayList<>();
list.add(createFakeOrderLineItem(1));
list.add(createFakeOrderLineItem(2));
list.add(createFakeOrderLineItem(3));
list.add(createFakeOrderLineItem(4));
return list;
}
private WebView createFakeOrderLineItem(int id) {
WebView wv = new WebView();
wv.setPrefSize(684, 90);
ProductionOrderHeader header = new ProductionOrderHeader();
header.setPoNumber("PONumber1234");
ProductionOrderLine line = new ProductionOrderLine();
line.setId(3333);
ManufactureProduct product = new ManufactureProduct();
product.setId(1111);
product.setPartNumber("Product.PartNumber1111");
ManufacturePart part = new ManufacturePart();
part.setId(9999);
part.setPartNumber("Part.Partnumber9999");
part.setHardwareId(666666);
part.setHardwareName("Hardware Name");
OrderLineItem item = new OrderLineItem(id, header, line, part, product);
// return item;
wv.getEngine().loadContent(item.toString());
return wv;
}
This is my OrderLineItem
public class OrderLineItem {
Integer index;
ProductionOrderHeader header;
ProductionOrderLine line;
ManufacturePart part;
ManufactureProduct product;
public OrderLineItem(Integer index, ProductionOrderHeader header, ProductionOrderLine line, ManufacturePart part,
ManufactureProduct product) {
this.index = index;
this.header = header;
this.line = line;
this.part = part;
this.product = product;
}
public Integer getIndex() {
return index;
}
public void setIndex(Integer index) {
this.index = index;
}
public ProductionOrderHeader getHeader() {
return header;
}
public void setHeader(ProductionOrderHeader order) {
this.header = order;
}
public ProductionOrderLine getLine() {
return line;
}
public void setLine(ProductionOrderLine orderLine) {
this.line = orderLine;
}
public ManufacturePart getPart() {
return part;
}
public void setPart(ManufacturePart part) {
this.part = part;
}
public ManufactureProduct getProduct() {
return product;
}
public void setProduct(ManufactureProduct product) {
this.product = product;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("<html>");
sb.append("<table>");
sb.append("<tr>");
sb.append("<td valign=\"middle\" style=\"font-size: 32px; padding-right:5px;\">");
sb.append((index + 1));
sb.append("</td>");
sb.append("<td style=\"border: 1px solid #919191; width:616px; font-size:12px; padding:10px;\">");
sb.append("<b>");
sb.append(header.getPoNumber());
sb.append(" [");
sb.append(line.getId());
sb.append("] </b> -");
sb.append("<b>P/N: </b> #");
sb.append(product.getId());
sb.append("<b> ");
sb.append(product.getPartNumber());
sb.append("</b><br/>");
sb.append("Part: # ");
sb.append(part.getId());
sb.append("<b> ");
sb.append(part.getPartNumber());
sb.append("</b> H/W: # ");
sb.append(part.getHardwareId());
sb.append("<b> ");
sb.append(part.getHardwareName());
sb.append("</b>");
sb.append("</td>");
sb.append("</tr>");
sb.append("</table>");
sb.append("</html>");
return sb.toString();
}
}
I'm using JAVAFX 8.
Thanks
I saw the cellFactory but it seems to handle only one line of text.
Firstly your understanding of cellFactory is wrong. And also setting a WebView as your comboBox item is really a horrible idea :). Instead you can build a simple layout and set it as graphic in your cell factory.
And by the way, never set Nodes as items to your controls (ComboBox, ListView..etc), you can just pass your model and build the appropriate layout in cellFactories.
Below is a quick demo to give you an idea of how to build your desired comboBox. Hope this can help you to have a better understanding.
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MultiLineComboBoxDemo extends Application {
#Override
public void start(Stage stage) throws Exception {
VBox root = new VBox();
root.setSpacing(15);
root.setPadding(new Insets(25));
root.setAlignment(Pos.TOP_LEFT);
Scene sc = new Scene(root, 600, 600);
stage.setScene(sc);
stage.show();
final ObservableList<Person> items = FXCollections.observableArrayList();
for (int i = 1; i < 4; i++) {
items.add(new Person(i,"Name " + i, i + 30, "email" + i + "#test.com"));
}
final ComboBox<Person> comboBox = new ComboBox<>();
comboBox.setItems(items);
comboBox.setCellFactory(param -> new ListCell<Person>() {
#Override
protected void updateItem(Person item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setGraphic(buildLayout(item));
} else {
setGraphic(null);
}
}
});
comboBox.setButtonCell(new ListCell<Person>(){
#Override
protected void updateItem(Person item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setGraphic(buildLayout(item));
} else {
setGraphic(null);
}
}
});
comboBox.getSelectionModel().selectedItemProperty().addListener((obs,oldVal,selectedPerson)->{
System.out.println("Name : "+selectedPerson.getName());
// Do what you want..
});
root.getChildren().add(comboBox);
}
private HBox buildLayout(Person person) {
VBox layout = new VBox();
HBox.setHgrow(layout,Priority.ALWAYS);
layout.setStyle("-fx-border-width:1px;-fx-border-color:#444444;");
layout.setSpacing(5);
layout.setPadding(new Insets(2));
HBox topRow = new HBox();
topRow.setSpacing(5);
topRow.getChildren().addAll(getLabel("Name :","bold"),getLabel(person.getName(),"normal"), getLabel("Age :","bold"),getLabel(person.getAge()+"","normal"));
HBox bottomRow = new HBox();
bottomRow.setSpacing(5);
bottomRow.getChildren().addAll(getLabel("Email :","bold"),getLabel(person.getEmail(),"normal"));
layout.getChildren().addAll(topRow, bottomRow);
HBox pane = new HBox();
pane.setAlignment(Pos.CENTER_LEFT);
pane.setSpacing(5);
pane.setPadding(new Insets(2));
Label num = new Label(person.getId()+"");
num.setStyle("-fx-font-size:20px;-fx-font-weight:bold;-fx-text-fill:black;");
pane.getChildren().addAll(num,layout);
return pane;
}
private Label getLabel(String txt, String style){
Label lblName = new Label(txt);
lblName.setStyle("-fx-font-weight:"+style+";-fx-text-fill:black;");
return lblName;
}
public static void main(String[] args) {
Application.launch(args);
}
class Person {
IntegerProperty id = new SimpleIntegerProperty();
StringProperty name = new SimpleStringProperty();
IntegerProperty age = new SimpleIntegerProperty();
StringProperty email = new SimpleStringProperty();
public Person(int id,String name, int age, String email) {
setId(id);
setName(name);
setAge(age);
setEmail(email);
}
public int getId() {
return id.get();
}
public IntegerProperty idProperty() {
return id;
}
public void setId(int id) {
this.id.set(id);
}
public String getName() {
return name.get();
}
public StringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
public int getAge() {
return age.get();
}
public IntegerProperty ageProperty() {
return age;
}
public void setAge(int age) {
this.age.set(age);
}
public String getEmail() {
return email.get();
}
public StringProperty emailProperty() {
return email;
}
public void setEmail(String email) {
this.email.set(email);
}
}
}
I've a JFXTreeTableView and i want to center the text of the data for each column.
there is one of my creating columns code :
JFXTreeTableColumn<TableData, String> DrinkColumn = new JFXTreeTableColumn<>("Drink");
DrinkColumn.setPrefWidth(100);
DrinkColumn.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<TableData, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(TreeTableColumn.CellDataFeatures<TableData, String> param) {
return param.getValue().getValue().Drink;
}
}
);
I don't use JFoenix, but using a standard TreeTableView, the following external CSS will center the text in tree table cells:
.tree-table-cell {
-fx-alignment: center ;
}
Here's a SSCCE (the code above goes in style.css):
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.stage.Stage;
public class TreeTableViewTest extends Application {
#Override
public void start(Stage primaryStage) {
TreeTableView<Item> table = new TreeTableView<>();
TreeTableColumn<Item, String> col = new TreeTableColumn<>("Item");
col.setCellValueFactory(cellData -> cellData.getValue().getValue().nameProperty());
col.setPrefWidth(250);
table.getColumns().add(col);
TreeTableColumn<Item, Number> valueCol = new TreeTableColumn<>("Value");
valueCol.setCellValueFactory(cellData -> cellData.getValue().getValue().valueProperty());
valueCol.setPrefWidth(150);
table.getColumns().add(valueCol);
table.setRoot(createRandomTree(50));
Scene scene = new Scene(table);
scene.getStylesheets().add("style.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private TreeItem<Item> createRandomTree(int nItems) {
Random rng = new Random();
TreeItem<Item> root = new TreeItem<>(new Item("Item 1", rng.nextInt(1000)));
root.setExpanded(true);
List<TreeItem<Item>> items = new ArrayList<>();
items.add(root);
for (int i = 2 ; i <= nItems ; i++) {
TreeItem<Item> item = new TreeItem<>(new Item("Item "+i, rng.nextInt(1000)));
item.setExpanded(true);
items.get(rng.nextInt(items.size())).getChildren().add(item);
items.add(item);
}
return root ;
}
public static class Item {
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty value = new SimpleIntegerProperty();
public Item(String name, int value) {
setName(name);
setValue(value);
}
public final StringProperty nameProperty() {
return this.name;
}
public final String getName() {
return this.nameProperty().get();
}
public final void setName(final String name) {
this.nameProperty().set(name);
}
public final IntegerProperty valueProperty() {
return this.value;
}
public final int getValue() {
return this.valueProperty().get();
}
public final void setValue(final int value) {
this.valueProperty().set(value);
}
}
public static void main(String[] args) {
launch(args);
}
}
If you want to center only specific columns, then use a cell factory on the column and set a CSS class or PseudoClass on the cell:
valueCol.setCellFactory(column -> {
TreeTableCell<Item, Number> cell = new TreeTableCell<Item, Number>() {
#Override
protected void updateItem(Number value, boolean empty) {
super.updateItem(value, empty);
if (empty) {
setText(null);
} else {
setText(value.toString());
}
}
};
cell.pseudoClassStateChanged(PseudoClass.getPseudoClass("centered"), true);
return cell ;
});
and modify the CSS accordingly:
.tree-table-cell:centered {
-fx-alignment: center ;
}
The latter version gives
I'm making a simple database application with JavaFX, but I can't figure out a way of making the Data class less verbose whilst still retaining the functionality of the Add Button.
Does anyone know a good way of streamlining the Data class, and keeping the Add Button, so that the user can input their own data?
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class DB extends Application {
private final TableView<Data> table = new TableView<>();
private final ObservableList<Data> data =
FXCollections.observableArrayList(
new Data("one", "one", "one", "one", "one", "one", "one", "one"));
private TableColumn<Data, String> [] tableCol;
private TextField [] textField;
private Button btn;
private HBox hbox;
private VBox vbox;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Custom DB");
stage.setMaximized(true);
table.setEditable(true);
setTableCol();
setCellValue();
addToTable();
setTextField();
setBtn();
addToHBox();
addToVBox();
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
private void setTableCol()
{
tableCol = new TableColumn[8];
for(int i = 0; i<8; i++) {
tableCol[i] = new TableColumn();
tableCol[i].setMinWidth(100);
tableCol[i].setGraphic(new TextField("x"));
}
}
private void setCellValue()
{
tableCol[0].setCellValueFactory( new PropertyValueFactory<Data, String>("one"));
tableCol[1].setCellValueFactory( new PropertyValueFactory<Data, String>("two"));
tableCol[2].setCellValueFactory( new PropertyValueFactory<Data, String>("three"));
tableCol[3].setCellValueFactory( new PropertyValueFactory<Data, String>("four"));
tableCol[4].setCellValueFactory( new PropertyValueFactory<Data, String>("five"));
tableCol[5].setCellValueFactory( new PropertyValueFactory<Data, String>("six"));
tableCol[6].setCellValueFactory( new PropertyValueFactory<Data, String>("seven"));
tableCol[7].setCellValueFactory( new PropertyValueFactory<Data, String>("eight"));
}
private void addToTable()
{
table.setItems(data);
for(int i = 0; i<8; i++)
table.getColumns().addAll(tableCol[i]);
}
private void setTextField()
{
textField = new TextField[8];
for(int i = 0; i<8; i++) {
textField[i] = new TextField();
textField[i].setPromptText("Enter");
textField[i].setMaxWidth(tableCol[i].getPrefWidth());
}
}
private void setBtn()
{
btn = new Button("Add Data");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
data.add(new Data(
textField[0].getText(),
textField[1].getText(),
textField[2].getText(),
textField[3].getText(),
textField[4].getText(),
textField[5].getText(),
textField[6].getText(),
textField[7].getText()));
}
});
}
private void addToHBox()
{
hbox = new HBox();
hbox.setSpacing(20);
for(int i = 0; i<8; i++)
hbox.getChildren().addAll(textField[i]);
hbox.getChildren().addAll(btn);
}
private void addToVBox()
{
vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(table, hbox);
}
public static class Data {
private final SimpleStringProperty one;
private final SimpleStringProperty two;
private final SimpleStringProperty three;
private final SimpleStringProperty four;
private final SimpleStringProperty five;
private final SimpleStringProperty six;
private final SimpleStringProperty seven;
private final SimpleStringProperty eight;
private Data(String a, String b, String c, String d, String e, String f, String g, String h)
{
this.one = new SimpleStringProperty(a);
this.two = new SimpleStringProperty(b);
this.three = new SimpleStringProperty(c);
this.four = new SimpleStringProperty(d);
this.five = new SimpleStringProperty(e);
this.six = new SimpleStringProperty(f);
this.seven = new SimpleStringProperty(g);
this.eight = new SimpleStringProperty(h);
}
public String getOne()
{
return one.get();
}
public void setOne(String fName)
{
one.set(fName);
}
public String getTwo()
{
return two.get();
}
public void setTwo(String fName) {
two.set(fName);
}
public String getThree()
{
return three.get();
}
public void setThree(String fName)
{
three.set(fName);
}
public String getFour()
{
return four.get();
}
public void setFour(String fName)
{
four.set(fName);
}
public String getFive()
{
return five.get();
}
public void setFive(String fName)
{
five.set(fName);
}
public String getSix()
{
return six.get();
}
public void setSix(String fName)
{
six.set(fName);
}
public String getSeven()
{
return seven.get();
}
public void setSeven(String fName)
{
seven.set(fName);
}
public String getEight()
{
return eight.get();
}
public void setEight(String fName)
{
eight.set(fName);
}
}
}
I'm stuck with trying to format Long values in a TableView with JavaFX.
I have following class to store the rows that I want to display on the table:
import java.text.DecimalFormat;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleStringProperty;
public class DataByCurrencyPairRow {
private DecimalFormat integerFormat = new DecimalFormat("#,###");
private SimpleStringProperty currencyPair = new SimpleStringProperty("");
private SimpleDoubleProperty shareOfTotalVolume = new SimpleDoubleProperty(0);
private SimpleLongProperty totalVolume = new SimpleLongProperty(0);
private SimpleLongProperty currencyBought = new SimpleLongProperty(0);
private SimpleLongProperty currencySold = new SimpleLongProperty(0);
private SimpleLongProperty monthlyAverage = new SimpleLongProperty(0);
public DataByCurrencyPairRow() {
currencyPair.set("");
shareOfTotalVolume.set(0);
totalVolume.set(0);
currencyBought.set(0);
currencySold.set(0);
monthlyAverage.set(0);
}
public String getCurrencyPair() {
return currencyPair.getValue();
}
public void setCurrencyPair(String currencyPair) {
this.currencyPair.setValue(currencyPair);
}
public Long getMonthlyAverage() {
return monthlyAverage.getValue();
}
public void setMonthlyAverage(Long monthlyAverage) {
this.monthlyAverage.setValue(monthlyAverage);
}
public Long getCurrencySold() {
return currencySold.getValue();
}
public void setCurrencySold(Long currencySold) {
this.currencySold.setValue(currencySold);
}
public Long getCurrencyBought() {
return currencyBought.getValue();
}
public void setCurrencyBought(Long currencyBought) {
this.currencyBought.setValue(currencyBought);
}
public Long getTotalVolume() {
return totalVolume.getValue();
}
public void setTotalVolume(Long totalVolume) {
this.totalVolume.setValue(totalVolume);
}
public Double getShareOfTotalVolume() {
return shareOfTotalVolume.getValue();
}
public void setShareOfTotalVolume(Double shareOfTotalVolume) {
this.shareOfTotalVolume.setValue(shareOfTotalVolume);
}
}
Then I have the controller with initialize method where I have been trying to override the updateItem method to get the table to show comma as a thousand separator:
public class MainController {
private static final String DEFAULT_TIME_HORIZON = new String("0");
private final NumberFormat integerFormat = new DecimalFormat("#,###");
#FXML
TableView<DataByCurrencyPairRow> tableTransactionsByCurrencyPair;
#FXML
TableColumn<DataByCurrencyPairRow, Long> columnTotal;
#FXML
void initialize() {
columnTotal.setCellFactory(
new Callback<TableColumn<DataByCurrencyPairRow, SimpleLongProperty>, TableCell<DataByCurrencyPairRow, SimpleLongProperty>>() {
#Override
public TableCell<DataByCurrencyPairRow, SimpleLongProperty> call(TableColumn<DataByCurrencyPairRow, SimpleLongProperty> param
) {
return new TableCell<DataByCurrencyPairRow, SimpleLongProperty>() {
#Override
protected void updateItem(SimpleLongProperty item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText("0");
setStyle("");
} else {
setText(integerFormat.format(item.longValue()));
}
}
};
}
}
);
And this is the method that populates the TableView:
public void updateByCurrencyPairTable() {
System.out.println("#MainController: Updating data in table view Markets volumes by currency pair");
ObservableList<DataByCurrencyPairRow> data = tableTransactionsByCurrencyPair.getItems();
data.clear();
// Add row items to the table view Markets volume by currency
for (DataByCurrencyPairRow row : customer.getDataByCurrencyPairR12m().getDataByCurrencyPair()) {
data.add(row);
}
}
Please help me by showing how to do this!! I also tried to override the updateItem method as Long instead of SimpleLongProperty and my IDE accepted the code but still the number is not formatted in the table.
Thank you guys in advance!!!
LongProperty implements ObservableValue<Number>, not ObservableValue<Long> (or ObservableValue<SimpleLongProperty>). So your table columns need to be of type TableColumn<DataByCurrencyPair, Number> and your cell factory needs to match those types accordingly.
Here's a simple example of a formatted column with Longs:
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Random;
import javafx.application.Application;
import javafx.beans.property.LongProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
public class TableWithFormattedLong extends Application {
private final NumberFormat integerFormat = new DecimalFormat("#,###");
#Override
public void start(Stage primaryStage) {
TableView<Item> table = new TableView<>();
TableColumn<Item, String> itemColumn = new TableColumn<>("Item");
itemColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
TableColumn<Item, Number> valueColumn = new TableColumn<>("Value");
valueColumn.setCellValueFactory(cellData -> cellData.getValue().valueProperty());
valueColumn.setCellFactory(tc -> new TableCell<Item, Number>() {
#Override
protected void updateItem(Number value, boolean empty) {
super.updateItem(value, empty);
if (value == null || empty) {
setText("");
} else {
setText(integerFormat.format(value));
}
}
});
table.getColumns().add(itemColumn);
table.getColumns().add(valueColumn);
Random rng = new Random();
for (int i = 1 ; i <= 20 ; i++) {
table.getItems().add(new Item("Item "+i, rng.nextLong()));
}
primaryStage.setScene(new Scene(table, 600, 600));
primaryStage.show();
}
public static class Item {
private final StringProperty name = new SimpleStringProperty();
private final LongProperty value = new SimpleLongProperty();
public Item(String name, long value) {
setName(name);
setValue(value);
}
public final StringProperty nameProperty() {
return this.name;
}
public final String getName() {
return this.nameProperty().get();
}
public final void setName(final String name) {
this.nameProperty().set(name);
}
public final LongProperty valueProperty() {
return this.value;
}
public final long getValue() {
return this.valueProperty().get();
}
public final void setValue(final long value) {
this.valueProperty().set(value);
}
}
public static void main(String[] args) {
launch(args);
}
}
There is no need to set the Cellfactory, just set the CellValueFactory.
TableColumn<DataByCurrencyPairRow, String> columnTotal;
columnTotal.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<DataByCurrencyPairRow,String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<DataByCurrencyPairRow, String> param) {
DataByCurrencyPairRow value = param.getValue();
return new ReadOnlyStringWrapper(NumberFormat.getNumberInstance(Locale.US).format(123123)); //replace the number with the calculated total
}
});
I have this combo box which inserts list of objects into combo box:
private List<ListGroupsObj> lisGroups;
public static class ListGroupsObj
{
private int groupId;
private String groupName;
public static ListGroupsObj newInstance()
{
return new ListGroupsObj();
}
public ListGroupsObj()
{
}
public ListGroupsObj groupId(int groupId)
{
this.groupId = groupId;
return this;
}
public ListGroupsObj groupName(String groupName)
{
this.groupName = groupName;
return this;
}
public int getGroupId()
{
return groupId;
}
public String getGroupName()
{
return groupName;
}
// #Override
// public String toString()
// {
// return serverName;
// }
}
ListGroupsObj ob = ListGroupsObj.newInstance().groupId(12).groupName("Group12");
ListGroupsObj osb = ListGroupsObj.newInstance().groupId(13).groupName("Group13");
ListGroupsObj oa = ListGroupsObj.newInstance().groupId(14).groupName("Group14");
ListGroupsObj oz = ListGroupsObj.newInstance().groupId(15).groupName("Group15");
final ComboBox<ListGroupsObj> listGroups = new ComboBox();
listGroups.getItems().addAll(ob, osb, oa, oz);
I would like to do something like this:
listGroups.getItems().addAll(listGroups);
How I can insert the list of the object into the combo box?
Updated
My Bad, missed the javaFX tag and jumped to conclusions...
What you "should" be able to do is something like...
final ComboBox<ListGroupsObj> listGroups = new ComboBox();
listGroups.getItems().addAll(ob, osb, oa, oz);
final ComboBox<ListGroupsObj> otherGroups = new ComboBox(listGroups.getItems());
This will pass the items of one combobox to other.
But you should also be able to do something like...
List<ListGroupsObj> listOfObjects = new ArrayList<>(5);
listOfObjects.add(ListGroupsObj.newInstance().groupId(12).groupName("Group12"));
listOfObjects.add(ListGroupsObj.newInstance().groupId(12).groupName("Group13"));
listOfObjects.add(ListGroupsObj.newInstance().groupId(12).groupName("Group14"));
listOfObjects.add(ListGroupsObj.newInstance().groupId(12).groupName("Group15"));
ObservableList<ListGroupsObj> observableListOfObjects = FXCollections.observableList(listOfObjects);
final ComboBox<ListGroupsObj> listGroups = new ComboBox(observableListOfObjects);
final ComboBox<ListGroupsObj> otherGroups = new ComboBox(observableListOfObjects);
Or
final ComboBox<ListGroupsObj> listGroups = new ComboBox();
listGroups.setItems(observableListOfObjects);
Or
final ComboBox<ListGroupsObj> listGroups = new ComboBox();
listGroups.getItems().addAll(observableListOfObjects);
This of course, will need to be tested ;)
Take a look at ComboBox JavaDocs for more details
Updated with runnable example
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TestComboBox extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
ListGroupsObj ob = ListGroupsObj.newInstance().groupId(12).groupName("Group12");
ListGroupsObj osb = ListGroupsObj.newInstance().groupId(13).groupName("Group13");
ListGroupsObj oa = ListGroupsObj.newInstance().groupId(14).groupName("Group14");
ListGroupsObj oz = ListGroupsObj.newInstance().groupId(15).groupName("Group15");
final ComboBox<ListGroupsObj> listGroups = new ComboBox();
listGroups.getItems().addAll(ob, osb, oa, oz);
final ComboBox<ListGroupsObj> otherGroups = new ComboBox(listGroups.getItems());
List<ListGroupsObj> listOfObjects = new ArrayList<>(5);
listOfObjects.add(ListGroupsObj.newInstance().groupId(12).groupName("Group12"));
listOfObjects.add(ListGroupsObj.newInstance().groupId(12).groupName("Group13"));
listOfObjects.add(ListGroupsObj.newInstance().groupId(12).groupName("Group14"));
listOfObjects.add(ListGroupsObj.newInstance().groupId(12).groupName("Group15"));
ObservableList<ListGroupsObj> observableListOfObjects = FXCollections.observableList(listOfObjects);
listGroups.setItems(observableListOfObjects);
otherGroups.getItems().addAll(observableListOfObjects);
VBox root = new VBox();
root.getChildren().add(btn);
root.getChildren().add(listGroups);
root.getChildren().add(otherGroups);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be launched
* through deployment artifacts, e.g., in IDEs with limited FX support.
* NetBeans ignores main().
*
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public static class ListGroupsObj {
private int groupId;
private String groupName;
public static ListGroupsObj newInstance() {
return new ListGroupsObj();
}
public ListGroupsObj() {
}
public ListGroupsObj groupId(int groupId) {
this.groupId = groupId;
return this;
}
public ListGroupsObj groupName(String groupName) {
this.groupName = groupName;
return this;
}
public int getGroupId() {
return groupId;
}
public String getGroupName() {
return groupName;
}
// #Override
// public String toString()
// {
// return serverName;
// }
}
}