JavaFx: How to hide the value of a CheckBoxTreeItem? - javafx

How to hide the value of a CheckBoxTreeItem?
mfbs.add(new CheckBoxTreeItem<String>(mfb.userId, new Label(mfb.userId + "-" + mfb.name), true));
The Label should be the caption of the CheckBoxTreeItem and the first argument mfb.userId should not show up at all.
Thanks in advance

You can add a custom cell factory to your TreeView that disables the text:
TreeView<String> treeView;
CheckBoxTreeItem<String> root = new CheckBoxTreeItem<>("Not Visible", new Label("Visible"));
treeView.setRoot(root);
treeView.setCellFactory(e -> new CustomCheckBoxTreeCell());
public class CustomCheckBoxTreeCell extends CheckBoxTreeCell<String>{
public CustomCheckBoxTreeCell() {}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(!empty){
setText(null);
}
}
}

I am not Java FX expert but I have worked with Swing API. What my research after your question showed is if you want to make your TreeItem visible/invisible, you should add or remove it.
parentTreeItem.getChildren().add(treeItem); // makes visible
parentTreeItem.getChildren().remove(treeItem); //makes invisible
Edit
If you want to hide only the value of the item, not the whole item, there are things you can make;
Save the value in a variable (or database or file if you want that it is persistent) and use it when you need it. (After that, you can apply my solution above)
Make the colour of the text same as the colour of the background.

Apply this css style to your treeView:
.tree-view, .tree-cell {
-fx-text-fill: transparent;
}

Related

JavaFX SetText CSS options

I'm using the Jfoenix libary, and I have gotten it to show both the day of the year, and day of the month (after asking here for the first hint). They are both inside the setText line. I'm trying to figure out if I can add CSS to them individually so I can make the Day of the Year appear smaller, in the right corner and maybe a different color. I've googled quite a bit but not getting the answers I'm looking for. Thank you.
endDate.setDayCellFactory(p -> new DateCell() {
#Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (item == null) {
setText("");
} else {
setText(Integer.toString(item.getDayOfYear()) + "\r\n" + Integer.toString(item.getDayOfMonth()));
}
}
});
You cannot style the text in the same Labeled differently, but you can use the graphic property instead to display the date:
DatePicker datePicker = new DatePicker();
datePicker.setDayCellFactory(p -> new DateCell() {
private final Text doy = new Text();
private final Text dom = new Text();
private final VBox graphic = new VBox(doy, dom);
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
doy.setFont(Font.font(8));
dom.setFont(Font.font(15));
VBox.setMargin(dom, new Insets(0, 0, 0, 10));
}
#Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (item == null) {
setGraphic(null);
} else {
setGraphic(graphic);
doy.setText(Integer.toString(item.getDayOfYear()));
dom.setText(Integer.toString(item.getDayOfMonth()));
}
}
});
BTW: For java internal string handling usually \r is not required. This is only necessary, if you write the string to a file or use a class that depends on the line separator of the OS; only \n works just fine for the purpose you're using it for here. If you need to use different line separation on different OS, hardcoding \r\n is not a good idea; use System.lineSeparator() instead.

TableView modify style per cell only [duplicate]

This question already has an answer here:
How to get row value inside updateItem() of CellFactory
(1 answer)
Closed 4 years ago.
Assume a:
TableView<ResultType, String> table = new TableView<> ();
table.setItems(myItems);
In TableColumn we have the setCellValueFactory method which very nicely gives you access to the ResultType object of the respective cell value. So you can use it to extract the values like that:
aColumnFromTableView.setCellValueFactory(data -> new SimpleStringProperty(data.getValue));
Now each cell from aColumnFromTableView will be populated with a value from all ResultType objects which are set as items for the table.
The question is: can we also change the cell's style in a similar way? I had a look at the setCellFactory method, but it does not seem as friendly as setCellValueFactory though (= it does not provide me the respective ResultType).
Here's what you can do with setCellFactory:
aColumnFromTableView.setCellValueFactory(data -> ???? ); // data is actually aColumnFromTableView itself??
So I am wondering of a way to set the cell style individually similar to what I described with "setCellValueFactory". I hope it exists.
Note: I also tried
aColumnFromTableView.setCellValueFactory(data -> {
aColumnFromTableView.setStyle("my style");
return new SimpleStringProperty(data.getValue);
})
But that sets it for the entire column and not individually.
Thanks!!!!
If you want to customize the style of the TableCell based on the value of the cell you'll need to use a cellFactory and return your own TableCell.
For instance, if you wanted a TableCell<?, Double> that displayed the number in red if it was negative you could do:
column.setCellFactory(col -> new TableCell<>() {
#Override
protected void updateItem(Double item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
} else {
setText(item.toString());
if (item < 0.0) {
setTextFill(Color.RED); // or use setStyle(String)
} else {
setTextFill(Color.BLACK); // or use setStyle(String)
}
}
}
});
When creating a custom TableCell you'll more than likely want to override the updateItem(Object,boolean) method. It's important you override it correctly, however, if you want it to work right. Read the javadoc for information:
The updateItem method should not be called by developers, but it is the best method for developers to override to allow for them to customise the visuals of the cell. To clarify, developers should never call this method in their code (they should leave it up to the UI control, such as the ListView control) to call this method. However, the purpose of having the updateItem method is so that developers, when specifying custom cell factories (again, like the ListView cell factory), the updateItem method can be overridden to allow for complete customisation of the cell.
It is very important that subclasses of Cell override the updateItem method properly, as failure to do so will lead to issues such as blank cells or cells with unexpected content appearing within them. Here is an example of how to properly override the updateItem method:
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
} else {
setText(item.toString());
}
}
Note in this code sample two important points:
We call the super.updateItem(T, boolean) method. If this is not done, the item and empty properties are not correctly set, and you are likely to end up with graphical issues.
We test for the empty condition, and if true, we set the text and graphic properties to null. If we do not do this, it is almost guaranteed that end users will see graphical artifacts in cells unexpectedly.
Instead of setting properties or calling setStyle you could use things like PseudoClass states to make it easier to style from an external CSS stylesheet.
import javafx.css.PseudoClass;
import javafx.scene.control.TableCell;
public class CustomCell<S> extends TableCell<S, Double> {
private static final PseudoClass POSITIVE = PseudoClass.getPseudoClass("positive");
private static final PseudoClass NEGATIVE = PseudoClass.getPseudoClass("negative");
public CustomCell() {
getStyleClass().add("custom-cell");
}
#Override
protected void updateItem(Double item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
pseudoClassStateChanged(POSITIVE, false);
pseudoClassStateChanged(NEGATIVE, false);
} else {
setText(item.toString()); // you might want to format the number for display
pseudoClassStateChanged(POSITIVE, item >= 0.0);
pseudoClassStateChanged(NEGATIVE, item < 0.0);
}
}
}
Then use:
column.setCellFactory(col -> new CustomCell<>());
And in a stylesheet:
.custom-cell:positive {
-fx-text-fill: black;
}
.custom-cell:negative {
-fx-text-fill: red;
}

JavaFX JFXDatePicker set color for specific dates

I am able to change the color of a JFXDatePicker from the JFoenix library for certain dates via the code below.
final Callback<DatePicker, DateCell> dayCellFactory = new Callback<DatePicker, DateCell>() {
#Override
public DateCell call(final DatePicker datePicker) {
return new DateCell() {
#Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if(!empty) {
if(listRegisteredTOTDays.contains(item)) {
setStyle("-fx-background-color: #99e699;");
}
}
}
};
}
};
The problem occurs when I have hovered over the item with a changed background. It changes the background colour to the default one after hovering and not the set one via de code above.
I do not want to disable the cell as the user still must be able to click on it!
The exercise is to inform the user which dates already has data. So nothing can be disabled.
How to overcome this? I just want after hovering it gets back the color set as above.
Before hovering:
and after hovering
While JFXDatePicker looks beautiful, it takes some liberties that make DateCells hard to customize. Instead of using CSS to style the cells it sets the background from code which has a higher precedence than any CSS, even inline CSS styles.
You can see this in the createDayCells() method of com.jfoenix.skins.JFXDatePickerContent.
This means without modifying the skins your only chance of fixing this is to add your own event handler and use Platform.runLater to ensure it runs after the event handler added in createDayCells():
final Background markedBackground = new Background(new BackgroundFill(Color.rgb(0x99, 0xE6, 0x99),
CornerRadii.EMPTY,
Insets.EMPTY));
picker.setDayCellFactory(dp -> new DateCell() {
{
addEventHandler(MouseEvent.MOUSE_EXITED, evt -> {
if (listRegisteredTOTDays.contains(getItem())) {
// override background property of marked cells after
// JFXDatePicker modifies it
Platform.runLater(() -> {
setBackground(markedBackground);
});
}
});
}
#Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (!empty && listRegisteredTOTDays.contains(item)) {
setBackground(markedBackground);
}
}
});

Javafx listview dynamically changing the color of listview cells

Hello I'm currently building project that uses javaFx and was wondering if it's possible to dynamically change the color of a listview objects cells at run-time. Each cell of the listview represents an object which has a color associated with it. The issue I'm having is that each object has a color that's generated at run time and the number of objects won't necessarily remain constant.
The underlying GUI that the javaFX code base is working with is fxml. I've tried looking into using CSS but since the amount of objects and color associated with those objects is generated at run-time I can't hard code it into a style-sheet. I've also been looking to using cell factories to create the desired cell for each cell, but I need to color to be passed into the cell factory and it has to be in the RGB format. Does anyone have any experience with a problem such as this one?
for(int i =0; i< mice.mice.size();i++){
selectedMiceListView.setCellFactory(new Callback<ListView<Object>,
ListCell<Object>>() {
// #Override
public ListCell<Object> call(final ListView<Object> param) {
final ListCell<Object> cell = new ListCell<Object>() {
#Override
protected void updateItem(final Object item, final boolean empty) {
super.updateItem(item, empty);
setStyle("-fx-background-color: rgb(" + mice.mice.get(i).red + "," + mice.mice.get(i).green + ", " + mice.mice.get(i).blue + ");");
}
};
return cell;
}
});
}
Below is what I've tried so far, it says that inner classes must effectively have final variables. Is there a way to modify it so that it accepts the rgb value i'm trying to set it too?
Try this, the below code paints every cell in the listview with black
this.listView
.setCellFactory(new Callback<ListView<Object>, ListCell<Object>>() {
#Override
public ListCell<Object> call(final ListView<Object> param) {
final ListCell<Object> cell = new ListCell<Object>() {
#Override
protected void updateItem(final Object item, final boolean empty) {
super.updateItem(item, empty);
setBackground(
new Background(new BackgroundFill(Color.rgb(100, 150, 200), CornerRadii.EMPTY, Insets.EMPTY)));
}
};
return cell;
}
});

How to add a custom css style for specific item in a combo/choice box in JavaFx?

I am using javaFx, and I want to mimic this control. Specificly the link in the bottom of the menu !!
is it possible to do it with css only or without creating a custom control?
There is no need to implement a custom control, but you do need a cell factory to do this. The basic idea is to add a style class to the cell if it requires it, and remove it if not. So you can do, for example:
final String cellStyleClass = "my-combo-box-cell" ;
ComboBox<String> combo = new ComboBox<>();
combo.setCellFactory(listView -> new ListCell<String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty) ;
getStyleClass().remove(cellStyleClass);
if (empty) {
setText(null);
} else {
setText(item);
if (/* needs style class */) {
getStyleClass().add(cellStyleClass);
}
}
}
});
The test to see if you need to add the style class can obviously reference the item, etc.
Now in your CSS file you can style the cell as you need it:
.my-combo-box-cell {
/* specific styles here... */
}

Resources