Using javafx, I have a button which in the css properties has the textFill set to white. Then during runtime it needs to be changed, which happens with this code:
import javafx.scene.control.Button;
import javafx.scene.paint.Color;
public class QAButton extends Button {
public QAButton(String text) {
this.textProperty().set(text);
}
public void setAnswerVisible(Boolean vis) {
if (vis) this.setTextFill(Color.GREEN);
else this.setTextFill(Color.BLUE);
}
}
However it doesn't do anything, the textFill will stay white. What can I do to change it during runtime?
Thank you.
Edit: I should add the css code:
.button {
-fx-text-fill: white;
}
And the button's id is set to
#question {
-fx-background-color: darkblue;
-fx-background-radius: 0;
-fx-max-width: 2000px;
-fx-max-height: 200px;
-fx-min-height: 80px;
}
Extraction from JavaFX CSS Reference (second section):
"The implementation allows designers to style an application by using style sheets to override property values set from code."
The setStyle API can fix your problem.
Example:
this.setStyle("-fx-text-fill: green");
Now all attributes in the style class will be overwritten.
If this is a problem, look here.
Related
I have code like this:
<theme-component theme="dark">
<my-component></my-component>
</theme-component>
Is it possible for my-component to know it is within theme-component with a theme of dark? Or do I also need to pass theme=dark manually into my-component?
my-component has styles defined like this:
static darkStyle = css`
:host {
--my-bkg: #535353;
--my-items: #474747;
--my-gutter: #4a4a4a;
--my-border: #474747;
--my-item-border: #535353; /* on dark themes only this is the same color as the background instead of the footer border */
--my-divider: #636363;
}
`;
static lightStyle = css`
:host {
--my-bkg: #b8b8b8;
--my-items: #c7c7c7;
--my-gutter: #ababab;
--my-border: #adadad;
--my-item-border: #adadad; /* on light themes only this is the same color as the footer border */
--my-divider: #9e9e9e;
}
`;
static styles = [this.darkStyle, sheet];
I would love to have some kind of ternary to switch between this.darkStyle or this.lightStyle. Or is there some kind of CSS I can write that is like
static styles = [css`
theme-component[theme=dark] :root {
--my-bkg: #535353;
}
`, sheet];
I see documentation about SuperElement.styles, but it's not clear to me how to use that when I am relying on variables based on an attribute here. I'm not trying to share a style as much as use the attribute to determine some new variables.
Edit after clarifications:
A component could technically find out the attribute on a direct parent component by imperatively doing the following:
this.parentElement.getAttribute('theme').
I am not sure how that could be done in CSS. Below this edit I've outlined a common approach to solving the issue of theming using CSS custom-properties which have the default behavior of inheriting through the shadow DOM. Also see video by Lit team: "How to style your Lit elements" for more context.
Original answer:
I think what you're looking for is the :host() CSS pseudo-class function.
Your setup is correct where the theme-component is providing CSS custom properties that inherit to all children. my-component does not need any changes.
The only change from your example that should be needed is:
static darkStyle = css`
:host([theme="dark"]) {
--my-bkg: #535353;
--my-items: #474747;
--my-gutter: #4a4a4a;
--my-border: #474747;
--my-item-border: #535353;
--my-divider: #636363;
}
`;
This will select and apply the dark theme CSS custom properties when the theme-component has the theme attribute set to value "dark". These custom properties will then inherit into the children.
Runnable sample:
<script type="module">
import {html, css, LitElement} from "https://cdn.jsdelivr.net/gh/lit/dist#2/core/lit-core.min.js";
class ThemeEl extends LitElement {
static styles = css`
:host {
--my-bkg: green;
display: block;
border: 2px dotted var(--my-bkg);
}
:host([theme="dark"]) {
--my-bkg: gray;
}
`;
render() { return html`<slot></slot>`; }
}
class ChildEl extends LitElement {
static styles = css`
:host {
display: block;
background-color: var(--my-bkg);
}
`;
render() { return html`<p>Child El</p>`; }
}
customElements.define('theme-el', ThemeEl);
customElements.define('child-el', ChildEl);
</script>
<theme-el>
<p>Default Theme</p>
<child-el></child-el>
</theme-el>
<theme-el theme="dark">
<p>Dark Theme</p>
<child-el></child-el>
</theme-el>
This technique can also be used such that a custom element can change its own host styling. By setting attributes on itself and using :host().
If the child component also needs to know what theme is set from JavaScript, that could also be communicated via a CSS custom property and queried with window.getComputedStyle(this).getPropertyValue(<custom property>).
The background is only showing white by default, are there any CSS codes that I can force it to blur or darken the background instead? I've tried using CSS but I was unable to find the class it was called, I've put the "hasBackdrop" attribute to false as well but it didn't affect anything.
CSS Code
::ng-deep .mat-dialog-container {
background-color: #fff;
color: #fff;
overflow: hidden;
}
p {
color: black;
}
HTML
<p>test-modal works!</p>
Code to call the modal
export class CallModalComponent implements OnInit {
constructor(public dialog: MatDialog) { }
openTestModal() {
this.dialog.open(TestModalComponent, {
hasBackdrop: false
});
}
ngOnInit(): void { }
you can add a classes to change the dialog backgrounds or the backdrop by provide it as custom class in open config paramter
const dialogRef = this.dialog.open(DialogContentExampleDialog,{
backdropClass:'backdrop-bg-orange',
panelClass:'bg-blue'
});
style.scss
.bg-blue .mat-dialog-container{
background: lightblue;
}
.backdrop-bg-orange {
background: orange;
}
it 's important to put the classes in the global style file , it will not work if you add the classes to component template because angular update all component style to work just for the current component (ViewEncapsulation)
stackblitz demo 🚀
I'm trying to change Button text color in a highlighted state on iOS using css.
Even though I can change the text color, it seems like some sort of opacity or other styling is also being applied and I can't figure out what it is or how to override it.
This is how the Button looks in a default state:
And this is how it looks in the highlighted state:
My code:
.facebookBtn {
background-color: #3b5998;
color: #fff;
&:highlighted {
color: #fff;
background-color: darken(#3b5998, 5%);
}
}
I can tell that the color parameter is working because if I change it to #000 it works (ofc it is not black either, rather some sort of transparent black).
I've tried applying opacity: 1; but it didn't help. It works as it should on Android though.
Any suggestions?
You can create a new button class that extends Button that will not get the default highlighted/tapped styling in iOS:
import { isIOS, Button } from '#nativescript/core';
export class PlainButton extends Button {
createNativeView() {
if (isIOS) {
return UIButton.buttonWithType(0);
}
return super.createNativeView();
}
}
To register this as a global component in nativescript-vue, you can do:
Vue.registerElement("PlainButton", () => PlainButton);
I'm new to JavaFX, and am confused by styles. I'm using OpenJFX 13.0.1. I have the following simple scene:
val oscs = HBox()
val osc1 = VBox()
val title = Text("Osc 1")
title.styleClass.add("text")
osc1.children.add(title)
oscs.children.add(osc1)
val root = BorderPane()
root.children.add(oscs)
val scene = Scene(root, 500.0, 400.0)
I have two issues:
-fx-text-fill isn't working to color the text, whereas -fx-fill is. I.e.
.text {
-fx-fill: #44FFFF;
}
works, whereas:
.text {
-fx-text-fill: #44FFFF;
}
does not. According to the docs, it seems like this is wrong.
Inheritance isn't working as I'd expect it to. Shouldn't the child nodes inherit from root?
The following doesn't work to color the label, regardless of whether it's -fx-fill or -fx-text-fill.
.root {
-fx-font-size: 24px;
-fx-font-family: sans-serif;
-fx-fill: #44FFFF;
-fx-background-color: #000000;
-fx-border-color: #44FF00;
-fx-border-width: 2px;
}
What am I doing wrong?
You probably got Label and Text confused.
Text is a subclass of Shape and does not provide a -fx-text-fill property. Furthermore Shape's -fx-fill property is not inherited. See CSS Reference Guide.
Other than going with Label you could use a descendant selector to assign the fill:
.root .text {
-fx-fill: #44FFFF;
}
Edit:
Label's -fx-text-fill is not inherited either. You should be able to fix both cases by specifying inherit as value for the -fx-text-fill or -fx-fill properties. The following should work for Text:
.root {
-fx-fill: #44FFFF;
-fx-background-color: #000000;
}
.text {
-fx-fill: inherit;
}
I'm learing JavaFx and I'm trying to change the css style of my window (Mastermind game) at runtime.
Currently it works with some objects like buttons, background, menu bar, labels and shapes.
But another object I'd like to change is the menu items (background and labels).
I've tried to use the next css code to acces it :
.context-menu {
-fx-background-color: linear-gradient(rgba(200,200,200,1),rgba(50,50,50,1) 80%);
}
It works on initalisation but not when changed at runtime.
For example, it works fine for the menu bar itself :
.menu-bar {
-fx-background-color: black;
-fx-selection-bar: #505050;
}
.menu-bar .label {
-fx-font-size: 12pt;
-fx-font-family: "Segoe UI Light";
-fx-text-fill: white;
-fx-opacity: 0.9;
}
In the FXMLcontroller I call the following code to change the skin :
#FXML private AnchorPane generalPane;
private final String themeNormal = getClass().getResource("/mastermindStyles/MasterMind_Normal.css").toExternalForm();
#FXML
void handleSkinNormal(ActionEvent event){
generalPane.getStylesheets().clear();
generalPane.getStylesheets().add(themeNormal);
}
How can I do it?
I've found it :
To use predefinite styles (like Modena and Caspian) :
Application.setUserAgentStylesheet(STYLESHEET_MODENA);
To use your own css stylesheet :
Application.setUserAgentStylesheet(null);
StyleManager.getInstance().addUserAgentStylesheet(
getClass().getResource("NewSkin.css").toExternalForm());