I'm working with JavaFX 8 on Windows 10. In a WebView with a dark background, I can see the light grey corner when the scrollbars are visible. WebView"manages scrolling automatically." I already tried this, as well as other selectors:
.corner {
-fx-background-color: black;
}
And also
.corner {
-fx-background-color: black;
}
.scroll-bar > .corner {
-fx-background-color: black;
}
.scroll-pane > .corner {
-fx-background-color: black;
}
.scroll-bar .corner {
-fx-background-color: black;
}
.scroll-pane .corner {
-fx-background-color: black;
}
.web-view .scroll-bar .corner {
-fx-background-color: black;
}
.web-view .scroll-pane .corner {
-fx-background-color: black;
}
But it doesn't work. So what could I do?
Example code: Main class
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.loadContent("<html><body><pre>This is a very very very very very very long string </pre><b>test</b><p>1</p><p>2</p><p>3</p></body></html>");
webEngine.setUserStyleSheetLocation("data:,body { background: black; color: white; } ");
StackPane root = new StackPane();
root.setPadding(new Insets(5));
root.getChildren().add(webView);
webView.setStyle("-fx-background-color:black;");
root.setStyle("-fx-background-color:black;");
root.getStylesheets().add("style.css");
primaryStage.setTitle("JavaFX Test");
primaryStage.setScene(new Scene(root, 300, 150));
primaryStage.show();
}
}
style.css
.scroll-bar .track {
-fx-background-color: black;
}
.scroll-bar .thumb {
-fx-background-color: brown;
}
.corner {
-fx-background-color: black;
}
This also has an awful behavior where the scrollbars only appear when I hover with the mouse, but nevermind. This doesn't happen in my main application. I just want to change the color of the grey square in the corner.
I am unable to reproduce the effect on Mac OS X v10.13.6 with Java v1.8.0_201. Because WebView "manages scrolling automatically" and JavaFX uses WebKit, #Pagbo suggests using -webkit-scrollbar-corner, as suggested here. In another context, #DVarga suggests using -fx-background-color, as shown here. As the effect may be platform/version dependent, I've added a complete example and screenshot for reference. In particular, the lower-right corner is overlain by the vertical scrollbar's decrement button. Stretching the window to hide the vertical scrollbar reveals the horizontal scrollbar's increment button. The corner is always occupied by a scrollbar button or black.
Main.java
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.loadContent("<html><body><pre>"
+ "This is a very very very very very very long string<br>"
+ System.getProperty("os.name") + " v"
+ System.getProperty("os.version") + "; Java v"
+ System.getProperty("java.version")
+ "</pre><b>test</b><p>1</p><p>2</p><p>3</p></body></html>");
webEngine.setUserStyleSheetLocation("data: ,body "
+ "{ background: black; color: white; } "
+ "::-webkit-scrollbar-corner { background: #0c0c0c; } ");
StackPane root = new StackPane();
root.setPadding(new Insets(5));
root.getChildren().add(webView);
webView.setStyle("-fx-background-color:black;");
root.setStyle("-fx-background-color:black;");
root.getStylesheets().add("style.css");
primaryStage.setTitle("JavaFX Test");
primaryStage.setScene(new Scene(root, 300, 150));
primaryStage.show();
}
}
style.css
.scroll-bar .track {
-fx-background-color: black;
}
.scroll-bar .thumb {
-fx-background-color: brown;
}
.corner {
-fx-background-color: black;
}
I am currently facing a problem with javafx table. I have a tableview that shows a list of subjects. The background color of each row depends if a subject is able to be enrolled or not. Subjects with green background can be enrolled and subjects with pink background cannot be enrolled. The problem occurs when scrolling the table.
TableView before scrolling
TableView after scrolling down and up
After scrolling, the background color of rows have changed and the subjects with green background might become pink and vice versa. This works perfectly without adding a css to the table.
Code I used to set the background color of rows
tblAvailableSubjects.setRowFactory((TableView<Subject> param) -> {
TableRow<Subject> row = new TableRow<>();
row.emptyProperty().addListener((obs, wasEmpty, isEmpty) -> {
if(isEmpty) {
row.setContextMenu(null);
row.setStyle("-fx-border-color: transparent");
} else {
Subject subject = row.getItem();
if(subject.getSubjectEvaluation().equals(SubjectEvaluation.COMPLETED)) {
row.setStyle("-fx-background: #B2EBF2");
} else if(subject.getSubjectEvaluation().equals(SubjectEvaluation.FAILED)) {
row.setStyle("-fx-background: #FF0000");
row.setContextMenu(tblAvailableContext);
} else if(subject.getSubjectEvaluation().equals(SubjectEvaluation.OKAY)) {
row.setStyle("-fx-background: #8BC34A");
row.setContextMenu(tblAvailableContext);
} else if(subject.getSubjectEvaluation().equals(SubjectEvaluation.ENROLLWITHCOREQ)) {
row.setStyle("-fx-background: #FFEB3B");
row.setContextMenu(tblAvailableContext);
} else if(subject.getSubjectEvaluation().equals(SubjectEvaluation.CANTENROLL)) {
row.setStyle("-fx-background: #FFCDD2");
}
}
});
return row;
});
CSS for table
.table-view {
/* Constants used throughout the tableview. */
-fx-table-header-border-color: transparent;
-fx-table-cell-border-color: -fx-box-border;
/* Horizontal Lines*/
-fx-background-color: transparent;
}
.table-view .filler, .table-view .column-header
{
-fx-size: 40;
-fx-border-style: null;
-fx-border-color: rgb(200.0, 200.0, 200.0);
-fx-border-width: 0 0 1 0;
-fx-background-color: transparent;
}
.table-view .show-hide-columns-button
{
-fx-background-color: transparent;
}
.table-view .column-header .label,
.table-view .column-drag-header .label
{
-fx-alignment: CENTER_LEFT;
}
.table-view .column-header-background
{
-fx-background-color: transparent;
}
.table-row-cell {
-fx-cell-size: 30px;
}
.table-cell {
-fx-border-color: transparent;
-fx-border-width: 1;
}
EDIT: The subject's SubjectEvaluation value doesn't change, it seems that it switches the context menu and background color between rows when scrolling.
I hope someone could help me with this. Thanks.
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.
I want my button to have a transparent black bar on the bottom with a opacity of 75%. The button name should appear on top of the black bar. I have drawn a draft below.
So far I have tried with no success:
.button{
-fx-background-color: #5a9bdc;
-fx-font-size: 16;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
-fx-text-fill: #ffffff;
}
.button:hover {
-fx-background-color: #97c0dc;
}
UPDATE:
So this is how my css looks:
.button-stats.parent{
-fx-background-color: #5a9bdc;
-fx-font-size: 16;
-fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );
-fx-text-fill: #ffffff;
}
.button-stats:hover {
-fx-background-color: #97c0dc;
}
.button-stats.element{
padding: 20px;
color: rgba(255,255,255,.4);
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
Here is a sample, it isn't going to be exactly what you want, but may help you in getting to where you want. It is based upon button styles found in modena.css in the jfxrt.jar that ships with Java 8.
Images are shown for unhovered and hovered and armed states (armed is when the button is pressed and the shadow is removed).
I did not provide info here for a focused state, so you will need to develop that yourself if you want it.
super-button.css
.button {
-custom-solid-button-color: lightgreen;
-custom-translucent-button-color: rgba(00, 80, 00, 0.75);
-custom-button-color:
linear-gradient(to bottom,
-custom-solid-button-color 0%,
-custom-solid-button-color 64%,
-custom-translucent-button-color 65%);
-fx-background-color: -custom-button-color;
-fx-background-insets: 0;
-fx-background-radius: 0;
-fx-text-fill: whitesmoke;
-fx-padding: 3.333333em 0.666667em 0.333333em 0.666667em;
-fx-font-size: 30px;
-fx-effect: dropshadow(gaussian, black, 10, 0, 3, 3);
}
.button:hover {
-custom-solid-button-color: derive(lightgreen, 20%);
-fx-effect: dropshadow(gaussian, goldenrod, 10, 0, 3, 3);
}
.button:armed {
-custom-solid-button-color: derive(lightgreen, -10%);
-fx-effect: null;
-fx-background-insets: 2 2 0 0;
}
SuperButton.java
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.*;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class SuperButton extends Application {
private static final String BACKGROUND_IMAGE_LOC =
"http://edugeography.com/images/great-barrier-reef/great-barrier-reef-04.jpg";
#Override
public void start(Stage stage) {
Button button = new Button("I \u2764 Sea Turtles");
ImageView background = new ImageView(
new Image(BACKGROUND_IMAGE_LOC, 400, 0, true, true)
);
StackPane layout = new StackPane(
background,
button
);
StackPane.setAlignment(button, Pos.BOTTOM_CENTER);
StackPane.setMargin(button, new Insets(0, 0, 15, 0));
Scene scene = new Scene(layout);
scene.getStylesheets().add(getClass().getResource(
"super-button.css"
).toExternalForm());
stage.setResizable(false);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Getting the translucent area at the base is slightly tricky, especially because you are applying a drop shadow effect. What happens with a drop shadow effect is that the drop shadow is visible through the translucent area. Normally, when you have an opaque foreground, you can see the shadow through the foreground, but when you have a translucent foreground, the shadow mars the translucent effect a bit. To understand what I mean, review the above images and note the difference between the translucent area in the images with and without a drop shadow involved.
So you might want to rethink the design to not use the drop shadow. There are ways around this using clips, but it gets a bit more complicated and you cannot achieve it using just CSS (you will also need to write some custom skin code in Java, which I won't demonstrate here).
Try
.button {
-fx-opacity: 0.7;
}
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.