I can't figure out how can I apply this kind of effect to the text-field in javaFX 2 using css (-fx-... :...);
I need something like in the screenshot. I have an panel with that background and i need for the text field to darken it up a little (it looks like an inner shadow).
I tried using smaller opacity on the panel and high opacity on the text input but is not working properly.
Thanks.
Run this sample app:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class StyleDemo extends Application {
#Override
public void start(Stage primaryStage) {
TextField txt = new TextField("text");
txt.setLayoutY(150);
txt.setPrefHeight(50);
txt.setStyle("-fx-background-color: rgb(0,0,0,0.11); -fx-text-fill: white; -fx-font-size: 28; -fx-font-weight: bold");
Pane root = new Pane();
root.setStyle("-fx-background-image: url(\"http://i.stack.imgur.com/ThghN.png\"); -fx-background-repeat: stretch; -fx-background-size: 300 250;");
root.getChildren().add(txt);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
To give an inner shadow effect to the text field, check this link out:
http://docs.oracle.com/javafx/2.0/api/javafx/scene/doc-files/cssref.html#typeeffect
Related
I´d like to apply this style programatically:
.rating:disabled > .container:disabled .button:disabled{
-fx-pref-height:15;
-fx-background-size: cover;
-fx-padding: 0;
}
I have tried this, but doesnt work:
ratingHeigth.bind(mainBorderPane.prefHeightProperty().divide(0.0355));
vipRating.styleProperty().bind(Bindings.concat(".rating:disabled > .container:disabled .button:disabled{ -fx-pref-height: ", ratingHeigth.asString(), ";}"));
This is undocumented behavior, as far as I am aware (so you might not want to rely on it), but you can create a "looked-up-size" in a similar manner to a "looked-up color" (which is documented).
In your external CSS stylesheet, do
.rating {
disabled-button-size: 15 ;
}
.rating:disabled > .container:disabled .button:disabled{
-fx-pref-height: disabled-button-size ;
-fx-background-size: cover;
-fx-padding: 0;
}
Then in Java do
vipRating.styleProperty().bind(ratingHeight.asString("disabled-button-size: %f ;"));
Your code doesn't work, because inline styles simply apply the actual style specified by the string to the node on which you call setStyle(...): an inline style does not include selectors.
The idea in the solution above is to define a "looked-up size" (sort of a CSS variable) in the CSS file that defines the height you want. Then use setStyle to change the value of that "looked-up size". This value is inherited by child nodes, so it's enough to set it using setStyle on a the container with the rating CSS class.
Here's a (simpler) SSCCE. Move the slider and the button will change size:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.IntegerBinding;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class LookedUpSizeTest extends Application {
#Override
public void start(Stage primaryStage) {
Button button = new Button("Test");
StackPane stack = new StackPane(button);
BorderPane root = new BorderPane(stack);
Slider sizeSlider = new Slider(30, 350, 40);
stack.styleProperty().bind(sizeSlider.valueProperty().asString("button-size: %f ;"));
root.setBottom(sizeSlider);
Scene scene = new Scene(root, 400, 400);
scene.getStylesheets().add("style.css");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
style.css:
.root {
button-size: 20 ;
}
.button {
-fx-pref-height: button-size ;
}
I have a working TextField with my CSS fill color, and a Label. But when I try a Text control, I have not figured out how to set the fill color in CSS (and I have tried many things).
Label label = new Label("Machine ID");
TextField textField = new TextField("1");
Text text = new Text("1");
.css:
.text-input {
-fx-text-fill: blue;
}
.label {
-fx-text-fill: blue;
}
First note that Text has no style class by default. So you need to add the style class:
Text text = new Text("1");
text.getStyleClass().add("my-text");
Then you can use the -fx-fill property inherited from Shape:
.my-text {
-fx-fill: blue ;
}
SSCCE:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class TextCSSTest extends Application {
#Override
public void start(Stage primaryStage) {
VBox root = new VBox(10);
TextField textField = new TextField("Text Field");
Label label = new Label("Label");
Text text = new Text("Text");
text.getStyleClass().add("my-text");
root.getChildren().addAll(textField, label, text);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(20));
Scene scene = new Scene(root);
scene.getStylesheets().add("text-css-test.css");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
text-css-test.css:
.my-text {
-fx-fill: blue ;
}
.label {
-fx-text-fill: green ;
}
.text-input {
-fx-text-fill: red ;
}
Based on the JavaFX CSS reference, Text doesn't have this property like Label and TextField do. So I'm not sure it is possible.
I just want to create copiable label in JavaFX.
I have tried to create TextField that have no background, have no focus border and default background color, but I have no success.
I have found a lot of questions how to remove focus background from control but all of that looks like "hacks".
Is there are any standard solution to implement copyable text?
You can create a TextField without the border and background color with css:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class CopyableLabel extends Application {
#Override
public void start(Stage primaryStage) {
TextField copyable = new TextField("Copy this");
copyable.setEditable(false);
copyable.getStyleClass().add("copyable-label");
TextField tf2 = new TextField();
VBox root = new VBox();
root.getChildren().addAll(copyable, tf2);
Scene scene = new Scene(root, 250, 150);
scene.getStylesheets().add(getClass().getResource("copyable-text.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
and
copyable-text.css:
.copyable-label, .copyable-label:focused {
-fx-background-color: transparent ;
-fx-background-insets: 0px ;
}
This is the solution I used, where there is a small button besides the label to be able to copy the text:
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import org.controlsfx.glyphfont.FontAwesome;
import org.controlsfx.glyphfont.Glyph;
import java.util.Locale;
public class CopiableLabel extends Label
{
public CopiableLabel()
{
addCopyButton();
}
public CopiableLabel(String text)
{
super(text);
addCopyButton();
}
public CopiableLabel(String text, Node graphic)
{
super(text, graphic);
}
private void addCopyButton()
{
Button button = new Button();
button.visibleProperty().bind(textProperty().isEmpty().not());
button.managedProperty().bind(textProperty().isEmpty().not());
button.setFocusTraversable(false);
button.setPadding(new Insets(0.0, 4.0, 0.0, 4.0));
button.setOnAction(actionEvent -> AppUtils.copyToClipboard(getText()));
Glyph clipboardIcon = AppUtils.createFontAwesomeIcon(FontAwesome.Glyph.CLIPBOARD);
clipboardIcon.setFontSize(8.0);
button.setGraphic(clipboardIcon);
setGraphic(button);
setContentDisplay(ContentDisplay.RIGHT);
}
}
Does anyone know of a class that i can use that is essential a rectangle, BUT it has text in the middle of the rectangle and the rectangle has a fill color along with a border color(the border can be changed to red or something along those lines)
Essentially right now i have a pane, and i want to make a 2D grid(10x10), where each individual object in the grid is a rectangle-typed object that has a number text center justified, a fill color, and a border color.
Note: I've tried to use gridpane, but the lack of documentation that i've found has led me to believe i can only set the fill color, and each cell in the grid pane does NOT look like a separate object like i want it to. I've also tried to implement rectangle but the rectangle doesn't have text or a border that i can manipulate.
Thank you for your help.
Just use a Label. Here's a proof of concept:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class CustomLabelDemo extends Application {
#Override
public void start(Stage primaryStage) {
Label label = new Label("Hello World");
label.setStyle(
"-fx-alignment: center;"
+"-fx-padding: 6px;"
+"-fx-background-color: red, -fx-background;"
+"-fx-background-insets: 0, 4px;"
);
StackPane root = new StackPane(label);
primaryStage.setScene(new Scene(root, 350, 75));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The way the css is working here is that it defines two backgrounds: the first (and thus the one at the back) is red; the one in front is set to -fx-background, which is the color defined in the default stylesheet for the background of most controls. Corresponding to these are two insets for the two backgrounds: the first set to zero, and the second set to 4 pixels. This means that 4 pixels of the red border will be visible. The padding is just set to make sure the text doesn't overlap the outer background (the border).
In a real application, you should put the style in an external file. You can also define a "looked-up-color" for the border color; this will make it much easier to change the color at runtime:
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 CustomLabelDemo extends Application {
#Override
public void start(Stage primaryStage) {
Label label = new Label("Hello World");
label.getStyleClass().add("custom-label");
Button changeColorButton = new Button("Change to green");
changeColorButton.setOnAction(event -> label.setStyle("custom-label-border-color: green;"));
VBox root = new VBox(10, label, changeColorButton);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 350, 75);
scene.getStylesheets().add("custom-label.css");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
with custom-label.css:
.custom-label {
custom-label-border-color: red ;
-fx-alignment: center;
-fx-padding: 6px;
-fx-background-color: custom-label-border-color, -fx-background;
-fx-background-insets: 0, 4px;
}
.button {
-fx-alignment: center ;
}
If you have a fixed set of states that the colors represent, you might want to use a pseudoclass to represent the state:
import javafx.application.Application;
import javafx.css.PseudoClass;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class CustomLabelDemo extends Application {
#Override
public void start(Stage primaryStage) {
Label label = new Label("Hello World");
label.getStyleClass().add("custom-label");
CheckBox errorCheckBox = new CheckBox("Error");
PseudoClass errorState = PseudoClass.getPseudoClass("error");
errorCheckBox.selectedProperty().addListener((obs, wasSelected, isNowSelected) ->
label.pseudoClassStateChanged(errorState, isNowSelected));
VBox root = new VBox(10, label, errorCheckBox);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 350, 75);
scene.getStylesheets().add("custom-label.css");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
custom-label.css:
.custom-label {
custom-label-border-color: green ;
-fx-alignment: center;
-fx-padding: 6px;
-fx-background-color: custom-label-border-color, -fx-background;
-fx-background-insets: 0, 4px;
}
.custom-label:error {
custom-label-border-color: red ;
}
.check-box {
-fx-alignment: center ;
}
I think your best bet is to make a custom control, exposing the properties you need.
See http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm for info and examples.
I want to implement a simple popup control, which should be styleable with CSS.
It's all working fine the only question is how to add content (a Node in JavaFX) to it?
The PopupWindow.getContent() method is deprecated in JavaFX 2.2.6 and not working with CSS, I am able to see the content but the CSS-selector will not work then.
So what is the best solution to add content myself, should I implement my own Skin class for that purpose or is there a simple way to just make it work?
I have prepared a simple use case:
import javafx.scene.control.Label;
import javafx.scene.control.PopupControl;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
public class PopupTest extends PopupControl {
public PopupTest() {
getStyleClass().add("popup"); // not working!?
StackPane pane = new StackPane();
pane.getStyleClass().add("pane");
Rectangle rectangle = new Rectangle(250, 250);
rectangle.getStyleClass().add("rect");
Label text = new Label("popup test");
text.getStyleClass().add("text");
pane.getChildren().addAll(rectangle, text);
// how to display to pane when the popup is shown?
getContent().addAll(pane);
}
}
For completeness here are my MainApplication and CSS file:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public class MainApplication extends Application {
#Override
public void start(Stage stage) throws Exception {
Group root = new Group();
final Scene scene = new Scene(root);
scene.getStylesheets().add(MainApplication.class.getResource("style.css").toExternalForm());
final Button button = new Button("show popup");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
PopupTest popup = new PopupTest();
popup.show(scene.getWindow());
}
});
root.getChildren().add(button);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
style.css:
.popup {
-fx-font-size: 24px;
}
.popup .rect {
-fx-fill: green;
}
.popup .text {
-fx-text-fill: white;
-fx-font-weight: bold;
}
The ".popup" selector is not working here, if I set it to the "pane" it will style the popup window so the css is correct: pane.getStyleClass().add("popup"); // working with this "fix".
That seems to work:
getScene().setRoot(pane);
About the style class not working: PopupControl doesn't have a getStylesheets() method. So maybe it can only be styled directly by setStyle(...)? You can work around that by simply styling pane or by wrapping pane in a root pane and styling that.