Cell background exceeds cell height - javafx

I have a TableView with several columns and rows.
This is an excerpt of the CSS:
.table-view {
-fx-font-size: 8.0pt;
}
.table-row-cell {
-fx-cell-size: 1.8em;
}
In the cell factory is:
StringBuilder style = new StringBuilder();
if (item.getWeight() != null) {
style.append("-fx-font-weight: ").append(item.getWeight()).append("; ");
}
if (item.getTextColor() != null) {
style.append("-fx-text-fill: ").append(item.getTextColor().toString().replace("0x","#")).append("; ");
}
if (item.getBackgroundColor() != null) {
style.append("-fx-background-color: ").append(item.getBackgroundColor().toString().replace("0x","#")).append("; ");
}
setStyle(style.toString());
Now, the problem is that when I set a background color the background gets larger than the cell height.
I do not find where the problem is.

Related

How to change the text color in rows of TableView?

I am trying to update row background color and text in tableview. But i am able to update only background colour. But i am not able to update text color using -fx-text-fill. Could someone help.
#FXML
private void initialize(){
tablename.setRowFactory(tv -> new TableRow<ClassName>()
{
#Override
public void updateItem(ClassName item, boolean empty)
{
super.updateItem(item, empty);
if (item == null)
{
setText(null);
setStyle("");
}
else
{
if (item.gettest().equals("a") {
setStyle("-fx-background-color: #38ee00; -fx-text-fill: green;");
}
if (item.gettest().equals("b") {
setStyle("-fx-background-color: #efe939; -fx-text-fill: red;");
}
}
}
});
}
The TableView colors the background of it's rows from modena.css which is why you can override this property using inline style. The -fx-text-fill property is set for the TableCells though and therefore the values inherited from the TableRow are not used.
I recommend using a CSS stylesheet yourself and applying a pseudoclass to the rows
final PseudoClass green = PseudoClass.getPseudoClass("green");
tablename.setRowFactory(tv -> new TableRow<ClassName>() {
#Override
public void updateItem(ClassName item, boolean empty) {
super.updateItem(item, empty);
boolean gr = (item != null) && item.gettest().equals("a");
pseudoClassStateChanged(green, gr);
}
});
CSS Stylesheet (needs to be applied to the TableView, an ancestor or the scene)
.table-row-cell:filled {
-fx-background-color: #efe939;
}
.table-row-cell:filled:green {
-fx-background-color: #38ee00;
}
.table-row-cell:filled .table-cell {
-fx-text-fill: red;
}
.table-row-cell:filled:green .table-cell {
-fx-text-fill: green;
}
Firts you need to get the current ROW :
TableRow<CallLogs> currentRow = getTableRow();
After that you can set the colors as you are doing, but in the currentRow:
if (item.gettest().equals("a") {
currentRow.setStyle("-fx-background-color: #38ee00; -fx-text-fill: green;");
}
if (item.gettest().equals("b") {
currentRow.setStyle("-fx-background-color: #efe939; -fx-text-fill: red;");
}

JavaFX how to hide empty column cell in tableView

I am using a tableView with UNCONSTRAINED_RESIZE_POLICY.
And I want set all empty column cell to white background.
This is the current view.
I am trying to search the empty node, but I can't find it even if I search all the nodes contained in tableView by following code (test function):
private void test() {
ArrayList<Node> nodes = getAllNodes(tableView);
nodes.forEach(node -> {
if(node instanceof TableCell) {
if(((TableCell) node).getText() == null || ((TableCell) node).getText().isEmpty()) {
System.out.println(true);
}
}
});
}
public static ArrayList<Node> getAllNodes(Parent root) {
ArrayList<Node> nodes = new ArrayList<Node>();
addAllDescendents(root, nodes);
return nodes;
}
private static void addAllDescendents(Parent parent, ArrayList<Node> nodes) {
for (Node node : parent.getChildrenUnmodifiable()) {
nodes.add(node);
if (node instanceof Parent)
addAllDescendents((Parent)node, nodes);
}
}
Use a CSS stylesheet to apply the styles to remove the background from TableRowCells and instead add the background to the TableCells:
/* overwrite default row style */
.table-row-cell {
-fx-background-color: transparent;
-fx-background-insets: 0;
}
/* apply row style to cells instead */
.table-row-cell .table-cell {
-fx-background-color: -fx-table-cell-border-color, -fx-background;
-fx-background-insets: 0, 0 0 1 0;
}
.table-row-cell:odd {
-fx-background: -fx-control-inner-background-alt;
}
/* fix markup for selected cells/cells in a selected row */
.table-row-cell:filled > .table-cell:selected,
.table-row-cell:filled:selected > .table-cell {
-fx-background: -fx-selection-bar-non-focused;
-fx-table-cell-border-color: derive(-fx-background, 20%);
}
.table-view:focused > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled:selected .table-cell,
.table-view:focused > .virtual-flow > .clipped-container > .sheet > .table-row-cell .table-cell:selected {
-fx-background: -fx-selection-bar;
}
scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
Note: There are no TableCells outside of existing columns. The background is applied to the TableRowCells.
Also retrieving the cells from a virtualizing control is a bad idea:
The cells are created during the first layout pass. They may not be present at the time you run your code.
Interacting with the control (e.g. by resizing it, scrolling it, ect.) may result in creation of additional cells. Any modifications you've done to the cells you found before by traversing the scene are not applied to those new nodes automatically.
The easiest way is:
.table-row-cell:empty {
-fx-background-color: transparent;
}

JavaFx button style

I have problem to add style to button controll from external css file,I trying something like this,example button.getStyleSheets().add(".../... .css");
I trying to select one button controll,not multiple buttons.I think to set style to button from external css file,and I would change code somewhere to works(I can fix that,over ObservableLis list=button.getStyleSheets(); .......) but I can't add external file to button.
//when I click left mouse button,selected them and if I type delete key delete him
else if(e.getButton() == MouseButton.PRIMARY && e.getClickCount() == 1)
{
//Ako se stisne taster delete da se izbrise dobavljac
universal_dobavljac.addEventHandler(KeyEvent.KEY_PRESSED, (ee) ->{
if(ee.getCode() == KeyCode.DELETE)
{
//Potvrda za brisanje dobavljača
ButtonType da=new ButtonType("Da", ButtonBar.ButtonData.OK_DONE);
ButtonType ne=new ButtonType("Ne", ButtonBar.ButtonData.CANCEL_CLOSE);
Alert alert=new Alert(Alert.AlertType.CONFIRMATION,"Da li želite da obrišete "+dob.getNaziv_firme()+ " dobavljača?",da,ne);
alert.setHeaderText(null);
Optional<ButtonType> result=alert.showAndWait();
if(result.isPresent() && result.get() == da)
{
//brisanje iz tilepane
tilePane.getChildren().remove(universal_dobavljac);
//brisanje dobavljaca iz baze
try{
transaction=session.beginTransaction();
session.delete(dob);
transaction.commit();
}
catch(HibernateException ex)
{
if(transaction != null)
{
transaction.rollback();
}
}
Alert alertt=new Alert(Alert.AlertType.INFORMATION);
alertt.setHeaderText(null);
alertt.setContentText("Uspešno ste izbrisali "+dob.getNaziv_firme()+" dobavljača");
alertt.show();
}
}
});
////////////////
//THIS comments bellow don't works -> Path is good,I check at least hundred times
//universal_dobavljac.getStylesheets().add(getClass().getResource("Finansije/Dobavljaci/kada_je_selektovan_dobavljac.css").toExternalForm());
universal_dobavljac.setStyle("-fx-font-weight: bold; -fx-font-size: 36px; -fx-font-family: Book Antiqua; -fx-pref-width: 303px; -fx-pref-height: 230px; -fx-background-image: url(\"Finansije/icon_hover.png\"); -fx-background-color: transparent; -fx-cursor: hand");
universal_dobavljac.addEventHandler(MouseEvent.MOUSE_EXITED,(event) ->{
//universal_dobavljac.getStylesheets().add(getClass().getResource("Finansije/Dobavljaci/kada_je_selektovan_dobavljac.css").toExternalForm());
universal_dobavljac.setStyle("-fx-font-weight: bold; -fx-font-size: 36px; -fx-font-family: Book Antiqua; -fx-pref-width: 303px; -fx-pref-height: 230px; -fx-background-image: url(\"Finansije/icon_hover.png\"); -fx-background-color: transparent; -fx-cursor: hand");
});
}
The problem is down bellow.

JavaFX8 CustomRowFactory ContextMenu background image not entirely visible

I've set the following custom row factory:
treeTblViewFiles.setRowFactory(new Callback<TreeTableView<FileModel>, TreeTableRow<FileModel>>() {
#Override
public TreeTableRow<FileModel> call(TreeTableView<FileModel> treeTableView) {
final TreeTableRow<FileModel> row = new TreeTableRow<>();
final ContextMenu rowMenu = new ContextMenu();
MenuItem removeItem = new MenuItem("Remove");
removeItem.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
int currentPlaylistIndex = m_playlists.indexOf(row.getTreeItem().getParent().getValue());
boolean itemRemoved = false;
if (row.getItem().getClass().equals(Song.class)) {
itemRemoved = m_playlists.get(currentPlaylistIndex).getSongs().remove(row.getItem());
m_playlists.get(currentPlaylistIndex).updatePlaylist((Song) row.getItem());
} else if (row.getItem().getClass().equals(Playlist.class)) {
itemRemoved = m_playlists.remove(row.getTreeItem().getValue());
}
TreeItem<FileModel> treeItem = row.getTreeItem();
// may need to check treeItem.getParent() is not null:
treeItem.getParent().getChildren().remove(treeItem);
treeTblViewFiles.getSelectionModel().clearSelection();
if (MyApp.DEBUG) {
System.out.println(m_playlists.size());
if (currentPlaylistIndex > -1) {
System.out.println(m_playlists.get(currentPlaylistIndex).getSongs().size());
}
}
}
});
rowMenu.getItems().add(removeItem);
row.contextMenuProperty().bind(Bindings.when(Bindings.isNotNull(row.itemProperty()))
.then(rowMenu)
.otherwise((ContextMenu) null));
return row;
}
});
and in my css I have:
/******************
* ContextMenu
******************/
.context-menu{
-fx-background-color: transparent;
}
.context-menu .menu-item{
-fx-background-image: url("styles/cm_bg.png");
-fx-background-repeat: no-repeat;
-fx-background-position: center;
-fx-background-color: transparent;
}
.context-menu .menu-item .label{
-fx-text-fill: #ababab;
-fx-font-weight: normal;
-fx-font-size: 12pt;
}
The problem is that it doesn't show the entire image(which is 220x40) but only the width that suits the 'Remove' string. The right-most part is cut.
EDIT:
Simplified version(the same result goes for a contextMenu on a Label):
ContextMenu cm = new ContextMenu();
MenuItem mi = new MenuItem("Test");
cm.getItems().addAll(mi);
lblUploader.setContextMenu(cm);
Why is that happening and how to solve it?
Thanks in advance.
Problem solved with the following .css:
.context-menu {
-fx-background-color: transparent;
-fx-min-width: <image_width>;
-fx-min-height: <image_height>;
}
Just remember to set the preferred(or min) sizes.

How to style a custom TreeCell with CSS in ScalaFX?

I want to change the background colour of a custom TreeCell using CSS, but setting the style property on the tree cell doesn't work. I can style the tree with alternate yellow and grey cells with a CSS file that looks like this:
.tree-cell:disabled {
-fx-padding: 3 3 3 3;
-fx-background-color: white;
}
.tree-cell:selected {
-fx-background-color: blue;
}
.tree-cell:even {
-fx-background-color: yellow;
}
.tree-cell:odd {
-fx-background-color: grey;
}
.tree-cell:drag-over {
-fx-background-color: plum;
}
and change the fill style of the text with an event handler that looks like this:
onDragEntered = (event: DragEvent) => {
val db = event.getDragboard
if (db.hasContent(customFormat)) {
textFill = Color.DEEPSKYBLUE
style() = "tree-cell:drag-over"
}
event.consume()
}
but the style of the tree cells doesn't change.
I eventually found the answer to my own question. The CSS file now looks like this:
.tree-cell:disabled {
-fx-padding: 3 3 3 3;
-fx-background-color: white;
}
.tree-cell:selected {
-fx-background-color: blue;
}
.tree-cell:filled:even {
-fx-background-color: lightyellow;
}
.tree-cell:filled:odd {
-fx-background-color: lightsteelblue;
}
.tree-cell.drag-over:filled {
-fx-background-color: plum;
}
I now get a plum colour when dragging over a filled cell. Empty cells stay white.
In order to get here I needed to understand the rules of "CSS specificity", although it was eventually possible to simplify the finished CSS file to make each case exactly match one selector.
The ScalaFX code now looks like this:
import scala.collection.JavaConversions._
// Copy the list, so that it isn't modified in place.
var oldStyleClass: util.Collection[String] = styleClass.toList
onDragEntered = (event: DragEvent) => {
val db = event.getDragboard
if (db.hasContent(customFormat)) {
textFill = Color.DEEPSKYBLUE
// Remember the original style by taking a copy.
oldStyleClass = styleClass.toList
// Restyle filled cells with .tree-cell.dragover:filled
// for the duration of the drag
styleClass.add("drag-over")
}
event.consume()
}
onDragExited = (event: DragEvent) => {
val db = event.getDragboard
if (db.hasContent(customFormat)) {
textFill = Color.BLACK
}
// Restore the original style.
styleClass.setAll(oldStyleClass)
event.consume()
}
Somewhere along the way I lost the animation for a failed drop. Otherwise I'm happy (but somewhat lonely in ScalaFX-land.)

Resources