I would like to adjust the line height of an HTMLEditor in JavaFx with css rules but can't find the name of the rule.
I tried -fx-line-height and a few other but none of them worked. Is it even possible, or is the HTMLEditor too restricted?
The HTML editor edits HTML, you need to specify the line-height in HTML based CSS (not JavaFX CSS).
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.web.HTMLEditor;
import javafx.stage.Stage;
public class SpacedOut extends Application {
private static final String HTML_TEXT =
"<p style=\"line-height:1.5\">\n" +
" <span style=\"font-size:12pt\">The quick brown fox jumps over the lazy dog.</span><br />\n" +
" <span style=\"font-size:24pt\">The quick brown fox jumps over the lazy dog.</span>\n" +
"</p>";
#Override
public void start(Stage stage) throws Exception{
HTMLEditor editor = new HTMLEditor();
editor.setHtmlText(HTML_TEXT);
Scene scene = new Scene(new Pane(editor));
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Related
All I am trying to do, is add a separator in between elements in a VBox, but I want the separator line to be a different color than the default. Let's chose red for example.
The only CSS I could find that would change the line color is this:
.separator {
-fx-padding: 8;
}
.separator .line {
-fx-background-color: red;
-fx-pref-height: 5;
}
But that seems to add a second line and it does not color the primary line as you can see here:
It needs to look like this:
Here is a working example showing the problem. If you run this code, you will need to add this to your POM file:
<dependency>
<groupId>com.simtechdata</groupId>
<artifactId>Switcher</artifactId>
<version>1.3.4</version>
</dependency>
And create a CSS file called Separator.css and place it in the resources folder. The contents of the css file are already in this post (the first code snipped that I posted).
Here is the running class:
package sample;
import com.simtechdata.Switcher;
import javafx.application.Application;
import javafx.scene.control.Label;
import javafx.scene.control.Separator;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
private final ClassLoader resource = ClassLoader.getSystemClassLoader();
#Override
public void start(Stage primaryStage) throws Exception{
String separatorCSS = resource.getResource("Separator.css").toExternalForm(); AnchorPane ap = new AnchorPane();
ap.setPrefWidth(300);
ap.setPrefHeight(400);
Switcher.addScene(10,ap,300,400);
ap.setStyle("-fx-background-color: black");
Label label1 = new Label("Example Text");
Label label2 = new Label("More Example Text");
label1.setStyle("\t-fx-font-size: 24pt;\n" +
"\t-fx-font-family: \"Segoe UI Semibold\";\n" +
"\t-fx-text-fill: rgb(255,155,0);\n" +
"\t-fx-alignment: center;\n");
label2.setStyle("\t-fx-font-size: 24pt;\n" +
"\t-fx-font-family: \"Segoe UI Semibold\";\n" +
"\t-fx-text-fill: rgb(255,155,0);\n" +
"\t-fx-alignment: center;\n");
Separator separator = new Separator();
separator.getStylesheets().add(separatorCSS);
VBox vbox = new VBox();
vbox.getChildren().addAll(label1,separator,label2);
ap.getChildren().add(vbox);
Switcher.showScene(10);
}
public static void main(String[] args) {
launch(args);
}
}
Does anyone know how to change the color of a JavaFX Separator line either programmatically or by using CSS?
Thank you,
Mike Sims
By default, a Separator has a border (for a horizontal separator the border is on the top). This is the white line you're seeing.
Just remove the border, e.g.:
.separator .line {
-fx-background-color: red;
-fx-pref-height: 5;
-fx-border-color: null ;
}
I'm attempting to have two transparent WebViews displayed one on top of the other.
They display alright, however, hyperlinks can only clicked for the WebView at the top.
My understanding is that by setting setPickOnBounds(false), clicks on transparent pixels of the top WebView should go through to the bottom WebView. However, it does appear to be work this way, with the top WebView blocking all clicks.
Is there a way to have overlapping WebView with hyperlinks working for both?
Example:
import java.lang.reflect.Field;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.w3c.dom.Document;
public class DoubleWebViews extends Application {
#Override
public void start(Stage primaryStage) {
new WebPage(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
static class WebPage{
WebView webViewBack = new WebView();
WebView webViewFront = new WebView();
public WebPage(Stage mainstage){
setupWebView(webViewBack, "<a href='https://www.google.com'>URL 1</a> can't be clicked!");
setupWebView(webViewFront, "<br><br><br><a href='https://www.google.com'>URL 2</a>");
StackPane root = new StackPane(webViewBack, webViewFront);
root.setPickOnBounds(false);
Scene scene = new Scene(root);
mainstage.setScene(scene);
mainstage.initStyle(StageStyle.TRANSPARENT);
}
void setupWebView(WebView webView, String html){
webView.setPickOnBounds(false); // doesn't work?
WebEngine webEngine = webView.getEngine();
webEngine.documentProperty().addListener(new DocListener(webEngine));
webEngine.loadContent("<body style='background : rgba(0,0,0,0);font-size: 70px;text-align:center;'>" + html + "</body>");
}
static class DocListener implements ChangeListener<Document>{
private final WebEngine webEngine;
public DocListener(WebEngine webEngine) { this.webEngine = webEngine;}
#Override
public void changed(ObservableValue<? extends Document> observable, Document oldValue, Document newValue) {
try {
// Use reflection to retrieve the WebEngine's private 'page' field.
Field f = this.webEngine.getClass().getDeclaredField("page");
f.setAccessible(true);
com.sun.webkit.WebPage page = (com.sun.webkit.WebPage) f.get(this.webEngine);
page.setBackgroundColor((new java.awt.Color(0, 0, 0, 0)).getRGB());
} catch (Exception ignored) {}
}
}
}
}
I've not found an elegant solution yet, but this works.
First, the mouse events received by the front WebView webViewFront need to be forwarded to webViewBack:
webViewFront.addEventFilter(MouseEvent.ANY, event -> webViewBack.fireEvent(event));
This will enable clicks, drags, etc to work on both frames.
As for using the correct cursor, that is a little tricky. Only the cursor of the front WebView is displayed. Therefore, our back WebView must be allowed to modify the front cursor:
webViewBack.cursorProperty().addListener((obs, oldCursor, newCursor) -> webViewFront.setCursor(newCursor));
The problem is now that webViewFront constantly resets its cursor to default if a mouse event occurs and there is no hyperlinks at that location in webViewFront. Therefore, we prevent this reset:
webViewFront.cursorProperty().addListener((obs, oldCursor, newCursor) -> {
if (newCursor != null && "DEFAULT".equals(newCursor.toString())) {
webViewFront.setCursor(webViewBack.getCursor());
}
});
Together, these three changes allow two overlapping WebView with hyperlinks working for both.
I cannot sign in to Google in JavaFX WebView. The page doesn't load when I click the 'Next' button.
Other logins on different websites work fine.
Here is an example you can run:
import javafx.application.Application;
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 App extends Application
{
#Override
public void start(Stage primaryStage) throws Exception
{
WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();
webEngine.load("https://calendar.google.com");
StackPane root = new StackPane();
root.getChildren().add(browser);
primaryStage.setScene(new Scene(root, 600, 600));
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
Screenshot here
Short Version:
Add the following line to your main method, before you load the page:
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
Long Version:
My first instinct was that JavaScript wasn't working, but I tested dummy emails and correctly got the error:
Couldn't find your Google Account
So it seemed like some JavaScript was working, but not the part which enabled the user to continue to enter their password. I added the following listener to listen for console errors, which I found here:
com.sun.javafx.webkit.WebConsoleListener.setDefaultListener(
(webView, message, lineNumber, sourceId) ->
System.out.println("Console: [" + sourceId + ":" + lineNumber + "] " + message)
);
This resulted in the following error:
Console: [null:0] XMLHttpRequest cannot load
https://ssl.gstatic.com/accounts/static/_/js/blahblahblah
Origin https://accounts.google.com is not allowed by
Access-Control-Allow-Origin.
This is a security feature called Same-Origin Policy. It's designed to stop pages being able to load scripts from potentially malicious third-party websites.
I searched for "Same Origin Policy JavaFX" and found the following question which will solve your problem.
The full application with both the fix and the additional logging is:
public class CalendarController extends Application
{
#Override
public void start(Stage primaryStage) throws Exception
{
WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();
com.sun.javafx.webkit.WebConsoleListener.setDefaultListener(
(webView, message, lineNumber, sourceId)-> System.out.println("Console: [" + sourceId + ":" + lineNumber + "] " + message)
);
webEngine.load("http://calendar.google.com");
StackPane root = new StackPane();
root.getChildren().add(browser);
primaryStage.setScene(new Scene(root, 600, 600));
primaryStage.show();
}
public static void main(String[] args)
{
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
launch(args);
}
}
I have been trying to remove the percentage text below the ProgressIndicator, but is unsuccessful. I have found several mentions of this and tried the accepted answer, but it does not work
Using Java 8 Update 121
package com.company.mytest;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ProgressApp extends Application {
public static void main(String[] args) {
launch(args);
}
/* (non-Javadoc)
* #see javafx.application.Application#start(javafx.stage.Stage)
*/
#Override
public void start(Stage stage) throws Exception {
ProgressIndicator progress = new ProgressIndicator();
progress.setProgress(0.5f);
StackPane root = new StackPane();
root.getChildren().add(progress);
Scene scene = new Scene(root);
scene.getStylesheets()
.add(getClass().getResource("progress.css").toExternalForm());
stage.setScene(scene);
stage.setWidth(300);
stage.setHeight(300);
stage.setTitle("JavaFX 8 app");
stage.show();
}
}
I know the CSS is loaded, because I am able to change the percentage font size. This is the CSS content of the progress.css file.
.progress-indicator .percentage {
visibility: hidden;
}
Setting the -fx-fill attribute to null seems solving the problem:
.progress-indicator .percentage {
-fx-fill:null;
}
Update:
Setting only this attribute hides the percentage text, but still takes up the space.
A possible workaround is to set the -fx-padding attribute of the ProgressIndicator:
.progress-indicator .percentage {
-fx-fill:null;
}
.progress-indicator {
-fx-padding: 0 0 -16 0;
}
The only problem is the hardcoded value: if the CSS for .progress-indicator .percentage is changed (e.g. bigger font size) then this also has to be adapted.
Alternatively a programatic solution in this answer: How can I avoid the display of percentage values, when using the ProgressIndicator of JavaFX UI Controls
Actually searched everywhere but any answer can't help me, sohere's the problem:
I want to add a custom font to my buttons. I already tried to write a css java class and a lot of other solutions, but nothing helped my.
/code deleted/
I'd be so glad if anyone could help me!
Update:
I tried this:
package view;
import ...
public class SceneStyle {
ImageView header = new ImageView("/view/images/header.jpg");
ImageView chatImg = new ImageView("/view/images/chat_win.jpg");
//Layout Style
//public String font1 = "Impact";
//public String font2 = "Comic Sans MS";
public static String color1 = "#00adf0";
public static String color2 = "#0076a3";
public void setLabelStyle(Label label) {
label.setStyle("-fx-font-family: Inconsolata:700; -fx-font-size: 25");
Scene scene = new Scene(label);
scene.getStylesheets().add("https://fonts.googleapis.com/css?family=Inconsolata:700");
label.setTextFill(Color.GRAY);
}
public void setLabelStyle2(Label label){
label.setStyle("-fx-font-family: Inconsolata:700; -fx-font-size: 25");
Scene scene = new Scene(label);
scene.getStylesheets().add("https://fonts.googleapis.com/css?family=Inconsolata:700");
label.setTextFill(Color.GRAY);
}
public void setLabelStyle3(Label label){
label.setStyle("-fx-font-family: Inconsolata:700; -fx-font-size: 25");
Scene scene = new Scene(label);
scene.getStylesheets().add("https://fonts.googleapis.com/css?family=Inconsolata:700");
label.setTextFill(Color.RED);
}
public void setButtonStyle(Button button){
button.setStyle("-fx-font-family: Inconsolata:700; -fx-font-size: 30; -fx-font-style: normal");
Scene scene = new Scene(button);
scene.getStylesheets().add("https://fonts.googleapis.com/css?family=Inconsolata:700");
button.setTextFill(Color.web(color2));
button.setPrefWidth(190);
}
public void setBorderPaneStyle(BorderPane pane, VBox btnBox, HBox scoreBox){
pane.setTop(header);
pane.setLeft(btnBox);
pane.setRight(chatImg);
pane.setBottom(scoreBox);
pane.getLeft().setStyle("-fx-background-image: url(\"/view/images/border_left.jpg\");");
pane.getBottom().setStyle("-fx-background-image: url(\"/view/images/bottom.jpg\");");
//pane.getCenter().setStyle("-fx-background-image: url(\"/view/images/center.jpg\");");
//TODO: why can't I implement this?
}
public static String getFontColor1(){ return color1; }
public static String getFontColor2(){ return color2; }
Thanks for the detailed answers, but actually I don't want to write a start method which is overwritten. Just want to implemtent the font in my code. And yes now I'm trying with the Google Fonts.
Thanks for answering my question.
Here is a simple example of how to use custom fonts in your JavaFX application. This example is just an edited version of the sample FontLoad application.
Output
Project Structure
The follow diagram is the project structure.
Java Class
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class FontLoad extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Label label = new Label("JavaFX Application");
Button button = new Button("My Button");
VBox box = new VBox(15, label, button);
box.setAlignment(Pos.CENTER);
Scene scene = new Scene(box, 500, 300);
scene.getStylesheets().add(getClass().getResource("/fontstyle.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Stylesheet
#font-face {
font-family: 'Fleftex';
src: url('fonts/Fleftex_M.ttf');
}
.label {
-fx-font-family: 'Fleftex';
-fx-font-size: 20;
}
.button .text {
-fx-font-family: 'Fleftex';
}
Update >= 8u60
Starting with this version the attribute “font-family” is ignored and you have to use the real name of the TTF.
By example: to use the font “Fleftex” contained on the file Fleftex_M.ttf You have to use this CSS file :
#font-face {
src: url(“fonts/Fleftex_M.ttf”);
}
.label {
-fx-font-family: 'Fleftex';
}
Here is a little example showing how to load and set a custom font.
package createfont;
import java.io.IOException;
import java.io.InputStream;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class CustomFontTest extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
String currentFontFile = "English Gothic, 17th c..TTF";
InputStream fontStream = CustomFontTest.class.getResourceAsStream(currentFontFile);
if (fontStream != null) {
Font bgFont = Font.loadFont(fontStream, 36);
fontStream.close();
final Button button = new Button("Press me");
button.setFont(bgFont);
BorderPane root = new BorderPane();
root.setCenter(button);
Scene scene = new Scene(root, 500, 100);
primaryStage.setTitle("CustomFontTest");
primaryStage.setScene(scene);
primaryStage.show();
} else {
throw new IOException("Could not create font: " + currentFontFile);
}
}
public static void main(String[] args) {
launch(args);
}
}
I tried this:
public void setLabelStyle(Label label) {
label.setStyle("-fx-font-family: Inconsolata:700; -fx-font-size: 25");
Scene scene = new Scene(label);
scene.getStylesheets().add("https://fonts.googleapis.com/css?family=Inconsolata:700");
label.setTextFill(Color.GRAY);
in each method. Because I don't want write a new methode which overrides the start method just like above. (Actually thanks for this detailed answer, but it isn't what I am searching for).
But also my solution doesn't work well...