I have a TableView Column set up as follows, with some text in a Text node. I wanted to style up the text, but the only css property being picked up is the italics. How can I associate the text with other properties such as color.
I've tried text.getStyleClass().add("table-text-allign-top-left"); but only italics gets picked up.
I'd also like to add some kind of spacing, like padding, but I don't know how to add such to an item in a TableCell.
The other problem is how to align items: to the left' right in a TableCell.
Would appreciate it a lot if anyone could help. Thank you all in advance.
This is an extract of the TableView:
clientNames.setCellFactory(new Callback<TableColumn<NewClientPOJO, String>, TableCell<NewClientPOJO, String>>() {
#Override
public TableCell<NewClientPOJO, String> call(TableColumn<NewClientPOJO, String> param) {
final TableCell<NewClientPOJO, String> cell = new TableCell<NewClientPOJO, String>() {
private Text text;
private Text emails;
private Text emails2;
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!isEmpty()) {
text = new Text(item.toString());
// Setting the wrapping width to the Text
text.setWrappingWidth(410);
text.getStyleClass().add("table-text-allign-top-left");
emails = new Text("Good DW TV");
emails.getStyleClass().add("lower");
emails2 = new Text("Scandinavia - Lines cold weather");
emails2.getStyleClass().add("lower");
VBox vbTable = new VBox();
vbTable.getChildren().add(text);
vbTable.getChildren().add(emails);
vbTable.getChildren().add(emails2);
setGraphic(vbTable);
}
}
};
return cell;
}
});
Thanks brian for the reply. I got it to work by changing the Node from Text to a Label. The Label picks up the style class.
Related
I have tried to research about this, but could not find any examples. The examples I found were regarding normal TableView only. I could only create a JFXTreeTableView with an object and list out String. Any help would be appreciated! Thanks!
I need to put a button or basically any other object than a string into a TreeTableView.
Updated to make it clear on what I wanted it to look like, and the solution is below.
With reference to this post, I was trying to add a Button(Specifically JFXButton) into a TreeTableView(Specifically JFXTreeTableView)
How to add button in JavaFX table view
However, the post only talks about TableView. After analyzing the codes I tried to modify the codes to work with TreeTableView and TreeTableCell instead.
Using the sample codes from JFoenix and modifying it as seen in the codes snippets below, I could load a JFXButton into a JFXTreeTableView. (Also works with normal Button. Just replace the JFXButton to Button)
JFXTreeTableColumn<User, String> settingsColumn = new JFXTreeTableColumn<>("Others");
settingsColumn.setPrefWidth(100);
Callback<TreeTableColumn<User, String>, TreeTableCell<User, String>> cellFactory
= //
new Callback<TreeTableColumn<User, String>, TreeTableCell<User, String>>() {
#Override
public TreeTableCell call(final TreeTableColumn<User, String> param) {
final TreeTableCell<User, String> cell = new TreeTableCell<User, String>() {
final JFXButton btn = new JFXButton("Just Do it");
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
setText(null);
} else {
btn.setButtonType(JFXButton.ButtonType.RAISED);
btn.setOnAction(event -> {
//Button Action here
});
setGraphic(btn);
setText(null);
}
}
};
return cell;
}
};
settingsColumn.setCellFactory(cellFactory);
//Also remember to add the new column in
treeView.getColumns().setAll(deptColumn, ageColumn, empColumn, settingsColumn);
This is the end result:
Is it possible to update every cell in a TableView with JavaFX? Actually, I get a new object in an ObservableList and, automatically, I also get a new row in the TableView.
But I also need to update the other rows. Is it possible? As far as I understand, the code below update just the first row in the table.
#Override
public TableCell<AtisMessage, String> call(TableColumn<AtisMessage, String> param) {
final TableCell<AtisMessage, String> cell = new TableCell<AtisMessage, String>() {
private TextFlow tf;
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!isEmpty()) {
Text text = new Text(item.toString());
tf = new TextFlow(text);
tf.setPrefWidth(Control.USE_COMPUTED_SIZE);
tf.setMaxHeight(Control.USE_COMPUTED_SIZE);
setGraphic(tf);
}
}
};
cell.setPrefHeight(65);
return cell;
}
Let's say i have 2 columns in a TreeTableView and now i want to add a string/Label in the first column and a ProgressBar in the other one. How would i accomplish something like this?
Really appreciate any help!
As correctly pointed out by James_D, you can use ProgressBarTreeTableCell for a column with ProgressBars. There is internal supports for some other UI controls such as TextField, CheckBox etc.
For other UI controls you can create a Custom TreeTableCell
as shown:
private class ProgressCell extends TreeTableCell<Employee, String> {
final ProgressBar progress = new ProgressBar();
ProgressCell() {
}
#Override
protected void updateItem(String t, boolean empty) {
super.updateItem(t, empty);
if (!empty) {
setGraphic(progress);
}
}
}
and then assign a CellFactory to the second column
secondCol.setCellFactory(
new Callback<TreeTableColumn<Employee, String>, TreeTableCell<Employee, String>>() {
#Override
public TreeTableCell<Employee, String> call(
TreeTableColumn<Employee, String> param) {
return new ProgressCell();
}
});
where Employee is the POJO class on which the TreeTableView is built
I am experiencing an issue when resizing a TableView which contains text items that wrap around TableCell items. Upon resizing, hidden values are resized but the visible items do not re-calculate the text wrapping.
The tweets in the red box were hidden during the resize and had their text wrapping adjusted as expected. Tweets above the box were visible during the resize phase and still have the old wrapping.
Below is my code for the resize phase.
fxSearchResultsTableTweet.setCellFactory(new Callback<TableColumn<Status, String>, TableCell<Status, String>>() {
#Override
public TableCell<Status, String> call(TableColumn<Status, String> arg0) {
return new TableCell<Status, String>() {
private Text text;
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!isEmpty()) {
text = new Text(item.toString());
text.setWrappingWidth(fxSearchResultsTableTweet.getWidth());
this.setWrapText(true);
setGraphic(text);
}
}
};
}
});
}
Any help would be greatly appreciated.
This is closer, but not great:
textCol.setCellFactory(new Callback<TableColumn<Status, String>, TableCell<String, String>>() {
#Override
public TableCell<Status, String> call(
TableColumn<Status, String> param) {
TableCell<Status, String> cell = new TableCell<>();
Text text = new Text();
cell.setGraphic(text);
cell.setPrefHeight(Control.USE_COMPUTED_SIZE);
text.wrappingWidthProperty().bind(cell.widthProperty());
text.textProperty().bind(cell.itemProperty());
return cell ;
}
});
In 2.2 this displays the wrong height when you add new items to the table, then on resize the cells are sized correctly. In 8 it's almost perfect, just seems to fail after the first item is added (at least in my mock-up).
As noted in the comments,
textCol.setCellFactory(tc -> {
TableCell<Status, String> cell = new TableCell<>();
Text text = new Text();
cell.setGraphic(text);
cell.setPrefHeight(Control.USE_COMPUTED_SIZE);
text.wrappingWidthProperty().bind(textCol.widthProperty());
text.textProperty().bind(cell.itemProperty());
return cell ;
});
appears to work better.
Just add cell factory on each table of column.
It should add before adding your data to table view.
It is worked fine for me.
yourTableColumn.setCellFactory(param -> {
return new TableCell<YourDataClass, String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
setStyle("");
} else {
Text text = new Text(item);
text.setStyle("-fx-text-alignment:justify;");
text.wrappingWidthProperty().bind(getTableColumn().widthProperty().subtract(35));
setGraphic(text);
}
}
};
});
How can I make an auto wrap ListView (multiline when the text is too long) in JavaFX 2? I know that if I put a \n to the string, it will be multiline, but the content is too dynamic.
Or is there a good way to put \n to the String after every xyz pixel length?
You can put a TextArea in the ListCell.graphicProperty(). This is usually used to set an icon in a list cell but can just as easy to set to any Node subclass.
Here is the exact code how I did it finally.
ListView<String> messages = new ListView<>();
messages.relocate(10, 210);
messages.setPrefSize(this.getPrefWidth() - 20, this.getPrefHeight() - 250);
messages.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
#Override
public ListCell<String> call(ListView<String> list) {
final ListCell cell = new ListCell() {
private Text text;
#Override
public void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (!isEmpty()) {
text = new Text(item.toString());
text.setWrappingWidth(messages.getPrefWidth());
setGraphic(text);
}
}
};
return cell;
}
});
There is no need to create additional controls such as TextArea or Text. It is enough to just setWrapText(true) of the ListCell and setPrefWidth(50.0) or so. It will be automatically rewrapped on resize.
Here is my working code in Kotlin:
datasets.setCellFactory()
{
object : ListCell<Dataset>()
{
init
{
isWrapText = true
prefWidth = 50.0
}
override fun updateItem(item: Dataset?, empty: Boolean)
{
super.updateItem(item, empty)
text = item?.toString()
}
}
}
By the way, this is how I made it to correctly wrap CamelCase words:
replace(Regex("(?<=\\p{javaLowerCase})(?=\\p{javaUpperCase})|(?<=[_.])"), "\u2028")
Here \u2028 is the Unicode soft line break character, which javaFX respects.