JavaFX8 tree table view custom root row - javafx

In my tree-table-view I have a root item which contains child items(I have mistakenly called them root items) that in turn have child items. I need to customize those mistakenly called root items rows text appearance. Is there such a selector or how else would that be done?
Thanks.

This will set a pseudo-class on the row containing the root:
final PseudoClass firstRowClass = PseudoClass.getPseudoClass("first-row");
treeTableView.setRowFactory(treeTable -> {
TreeTableRow<...> row = new TreeTableRow<>();
row.treeItemProperty().addListener((ov, oldTreeItem, newTreeItem) ->
row.pseudoClassStateChanged(firstRowClass, newTreeItem == treeTable.getRoot()));
return row ;
});
Now you can select that row in css with
.tree-table-row-cell:first-row { ... }
Complete example here
It sounds like you want to style the immediate child nodes of the root node. In this case, just do
row.treeItemProperty().addListener((ov, oldTreeItem, newTreeItem) ->
row.pseudoClassStateChanged(firstRowClass,
newTreeItem != null && newTreeItem.getParent() == treeTable.getRoot()));
instead of the condition in the code above. Obviously, you can use other criteria as you need them (e.g. ! newTreeItem.isLeaf()).
Note that the default style sheet rules for tree-table-row are a little strange: -fx-background-color is set for the row, but -fx-text-fill is set for both the row and the cells inside it. So if you want to change the background color, you just need
-tree-table-row-cell:first-row {
-fx-background-color: antiquewhite ;
}
but if you want to change the text color, you need to change it on the cells:
-tree-table-row-cell:first-row .tree-table-cell {
-fx-text-fill: red ;
}

Related

Is there a different way to style table rows in javafx

I currently am using a custom cell factory in Javafx to style cells/rows of my table view with css. This is working successfully and exactly how I need it to. I was wondering if there was another way to style the rows of a table view.
I want to style the entire row with css dynamically instead of cell by cell. Some of the rows will be different colors, etc. Font fill, background color, font size, etc.. nothing fancy.
You can use a rowFactory on the table which generates rows and manipulates either the style class of the row or a pseudoclass attached to the row. Then use an external style sheet to apply the styles.
e.g.
PseudoClass foo = PseudoClass.getPseudoClass("foo");
table.setRowFactory(tv -> {
TableRow<MyDataType> row = new TableRow<>();
row.itemProperty().addListener((obs, oldItem, newItem) -> {
if (/* some condition on newItem */) {
row.pseudoClassStateChanged(foo, true);
} else {
row.pseudoClassStateChanged(foo, false);
}
});
return row ;
});
and then
.table-row-cell {
/* your regular style settings here */
}
.table-row-cell:foo {
/* your specific style for when foo is set here */
}

Highlighting multiple cells in a JavaFX TableRow

Jewelsea has provided a great example of highlighting table rows and an individual cell at GitHub. However, I am having great difficulty with something that is closely related.
Here is a screen shot:
Using his example, when I perform the updateItem code for an individual cell in the "Will Pay Up" column, I would also like to highlight the corresponding name (which would be found in the same TableRow) with the same color as the cell in the will pay up column. In the code I am actually developing I have ensured that name is always found in the first column.
Here are just a few lines from his code for updateItem (I hope this is okay):
// update the item and set a custom style if necessary
if (item != null) {
setText(item.toString());
this.getStyleClass().add(item ? "willPayCell" : "wontPayCell");
this.getTableRow().getStyleClass().add(item ? "willPayRow" : "wontPayRow");
}
We can highlight the current cell (this.getStyleClass()) or the entire row (this.getTableRow()) but I'm unable to find a way to access another cell within the current row.
Set the style class of the cells to something constant, and the style class of the rows depending on the item's value:
if (item != null) {
setText(item.toString());
if (! this.getStyleClass().contains("willPayCell")) {
this.getStyleClass().add("willPayCell");
}
this.getTableRow().getStyleClass().removeAll("willPayRow", "wontPayRow");
this.getTableRow().getStyleClass().add(item ? "willPayRow" : "wontPayRow");
}
and then you can just use the CSS to determine the colors of different cells:
.table-row-cell.willPayRow .table-cell {
-fx-background: /* color for cells other than willPayCell in willPayRow */;
}
.table-row-cell.wontPayRow .table-cell {
-fx-background: /* color for cells other than willPayCell in wontPayRow */;
}
.table-row-cell.willPayRow .willPayCell {
-fx-background: /* color for willPayCell in willPayRow */;
}
.table-row-cell.wontPayRow .willPayCell {
-fx-background: /* color for willPayCell in wontPayRow */;
}

Vaadin ListSelect - multiple styles in one list

i would like to have one list select that will have more than one style, i put two kinds of object's one is a group of users (bold), rest are users (italic or regular) is it possible to add style that will be added to part of added obj?
My code looks like this:
for(Usr usr: userSearchResult){
listSelect.addItem(usr);
}
listSelect.addStyleName("bold");
for (Gr gr : groupSearchResult) {
searchList.addItem(gr);
}
and also have style set in css correct similar to this
.v-select-bold .v-select-select {
font-weight:bold;}
i would be glad to solve this by myself but that was two days ago now i'm in a dot ;)
Thanks in advance for help!
You can store your row as a label with style. In the container there will be a label instance. There you can simply add the style.
Container container = new IndexedContainer();
container.addContainerProperty(NAME_PROPERTY, Label.class , "");
for (int i = 0; i <= 50 ; i++) {
Item item = container.addItem(i);
Label label = new Label(HashUtils.getRandomSalt());
label.addStyleName(style)
item.getItemProperty(NAME_PROPERTY).setValue();
}
return container;
You can't style rows of a ListSelect. You can use a Table component with one column to achieve a similar result. Table.setCellStyleGenerator method is used for differentiating styles for each cell (each row in your case).

Select element without a child

I have a page that might one of the following:
<span id='size'>33</span>
Or
<span id='size'>
<b>33</b>
<strike>32</strike>
</span>
I would like to grab the value '33' on both cases, is there a CSS selector I can use?
I tried to use the following, #size with no b sibling or b which is a #size sibling:
document.querySelector('#size:not(>b), #size>b').innerText
But I keep getting an error- "Error: SYNTAX_ERR: DOM Exception 12"
According to w3 Spec only Simple Selectors are supported, the thing is that "greater-than sign" (U+003E, >)" is considered as part of the Simple Selectors definition.
You can't do it with a regular CSS selector, but you can do it in a few lines of JS:
var element = document.querySelector('#size');
var b = element.querySelector('b');
var text = b ? b.innerText : element.childNodes[0].nodeValue;
console.log(text);
So really you want significant text (ie other than whitespace, because in your second example there's probably tabs and returns between the span start tag and the b) of #size, or, if that doesn't exist, the significant text of its first element:
// Is text just whitespace?
function isWhitespace(text){
return text.replace(/\s+/,'').length === 0;
}
// Get the immediate text (ie not that of children) of element
function getImmediateText(element){
var text = '';
// Text and elements are all DOM nodes. We can grab the lot of immediate descendants and cycle through them.
for(var i = 0, l = element.childNodes.length, node; i < l, node = element.childNodes[i]; ++i){
// nodeType 3 is text
if(node.nodeType === 3){
text += node.nodeValue;
}
}
return text;
}
function getFirstTextNode(element){
var text = getImmediateText(element);
// If the text is empty, and there are children, try to get the first child's text (recursively)
if(isWhitespace(text) && element.children.length){
return getFirstTextNode(element.children[0])
}
// ...But if we've got no children at all, then we'll just return whatever we have.
else {
return text;
}
}
The day we'll have CSS Level 4 selectors and the parent selector you'll be able to use a simple selector but for now you can't do it directly.
You could iterate to find the first text node but here's a hacky solution :
var text = document.getElementById('size').innerHTML.split(/<.*?>/)[0];
To be used only if you have some idea of the content of your #size element.

GWT - Styling TreeItems

in my application I have a tree structure made out of treeitems.
What I wanted to do was change the background of certain tree items if their userObject satisfies certain conditions. The problem I have is when a root tree item is getting its background changed (only tested it on criteria being satisfied at tree items at the root level), all child treeitems of that tree item also have their background changed despite me going in and removing that style sheet on the children.
Long story short: I want it to only change the background on the tree item itself, and not its children.
code:
if(item.getUserObject() != null && ((Device)item.getUserObject()).getDeviceType() == type)
{
item.setStyleName("labelHighlight");
}
else
{
item.removeStyleName("labelHighlight");
}
for(int i = 0; i < item.getChildCount(); i++)
{
highlightNodes(type, item.getChild(i));
}
Use a widget instead of directly styling treeItem. Like this, you can change background of your widget and not the background of all your tree item

Resources