I'm working on a simple back/forward-navigation with Vaadin existing of two buttons, each with a label and an icon (arrows left and right).
navigator = getUI().getNavigator();
if (!StringUtils.isEmpty(backViewID)) {
backButton = new Button(backButtonI18n, IconCache.FAST_REWIND_BUTTON.getIconResource());
backButton.addClickListener(getBackButtonListener());
}
if (!StringUtils.isEmpty(nextViewID)) {
nextButton = new Button(nextButtonI18n, IconCache.FAST_FORWARD_BUTTON.getIconResource());
nextButton.addClickListener(getNextButtonListener());
}
How can I align the icons on each button? Currently it looks like
"<< Back" ">> Next", because icons are aligned on the left and text is aligned on the right side. I now want to align the icon for the next-button on the right side and the text on the left, to make it look like "<< Back" "Next >>".
I hope someone can help me with that.
Cheers, Hendrik
If you're using Valo, this is relatively easy. You just need to add a style name which is already shipped with the theme forwardButton.addStyleName(ValoTheme.BUTTON_ICON_ALIGN_RIGHT):
public class ButtonsComponent extends HorizontalLayout {
public ButtonsComponent() {
Button backButton = new Button("Back", FontAwesome.ARROW_LEFT);
Button forwardButton = new Button("Forward", FontAwesome.ARROW_RIGHT);
forwardButton.addStyleName(ValoTheme.BUTTON_ICON_ALIGN_RIGHT);
addComponent(backButton);
addComponent(forwardButton);
}
}
Alternatively you can just copy the same exact CSS from the valo-button-icon-align-right-style into your theme, and add that particular style to your button: forwardButton.addStyleName("my-custom-button-with-right-alligned-icon");
.my-custom-button-with-right-alligned-icon {
[class*="wrap"] {
display: inline-block;
}
.v-icon {
float: right;
$padding-width: ceil($v-unit-size/2.4);
margin-left: $padding-width + ceil($padding-width/-5);
+ span:not(:empty) {
margin-left: 0;
}
}
}
Either way, you should end up with something similar to:
Related
I'm trying to add a submenu to my MenuButton and it doesn't seem to be able to accept a Menu as a child. Is it possible to do this, or do I need to use some other kind of menu? My menu is set up like this:
class DotMenuButton: MenuButton() {
item("item 1").action {
//action 1
}
item("item 2").action {
//action 2
}
//here is where I would like a submenu
menu("sub menu") {
item("sub menu item 1").action {
//sub menu action 1
}
}
}
I am using TornadoFX but if there is a way to do this in plain JavaFX I can adapt it. Any suggestions would be appreciated.
Edit: As of tornadofx 1.7.19-SNAPSHOT the above code now works. :-)
I have committed support for submenus in MenuButton, so your code above will now work with the the latest snapshot release.
I have a toggle button in my program that starts/stops a script. I would like for this button to be green and say "START" when the button is not selected, and red and say "STOP" when it is selected. More importantly, I would like the unselected hover color to be a slightly darker version of the original green, and the selected hover color to be a slightly darker version of the red color. My current CSS for this button looks like this:
#startStopButton {
-fx-border-color:#d4d4d4;
-fx-background-color:#85eca5;
-fx-background-image: url("startButton.png");
-fx-background-size: 50px;
-fx-background-repeat: no-repeat;
-fx-background-position: 80% 50%;
-fx-alignment: CENTER_LEFT;
-fx-effect: dropshadow(three-pass-box, #e7e7e7, 15, 0, 0, 0);
}
#startStopButton:hover {
-fx-background-color:#80dc9c;
}
#startStopButton:selected{
-fx-background-color: #ff6060;
-fx-text:"STOP";
}
#startStopButton:selected:focused{
-fx-background-color: #ff6060;
-fx-text:"STOP";
}
Currently, this will work fine, except for when the button turns red. In this case, there is no hover effect. Within my FXML controller, there is a function that is activated every time this button is clicked:
private void startStopClick()
{
if(startStopButton.isSelected())
{
startStopButton.setText(" STOP");
// startStopButton.setStyle()
}
else {
startStopButton.setText(" START");
}
}
Is there any way to 1) set the button text within CSS so that I can leave that out of my controller?
2) Get the current toggle button state in CSS, so that I can have multiple hover effects. For example, something like this:
#startStopButton:unselected{
-fx-background-color: #ff6060;
-fx-text:"STOP";
}
If there is no way to do this in CSS, can I set the hover styles in the Java code in the FXML controller?
CSS properties are only available for the look of nodes. With a few exceptions the basic JavaFX nodes don't allow you to specify content via CSS. The text property of buttons is no exception; it cannot be set using CSS.
As for the colors: The rules occuring last override values assigned by rules with the same precedence occuring before them. This means the background color assigned by the rules for #startStopButton:selected and #startStopButton:selected:focused always override the color #startStopButton:hover assigns.
Since in both cases you want a darker color when hovering, the derive function and a lookedup color may work for you.
Example
#Override
public void start(Stage primaryStage) {
ToggleButton btn = new ToggleButton();
btn.getStyleClass().add("start-stop");
btn.textProperty().bind(Bindings.when(btn.selectedProperty()).then(" STOP").otherwise(" START"));
Pane p = new Pane(btn);
Scene scene = new Scene(p);
scene.getStylesheets().add("style.css");
primaryStage.setScene(scene);
primaryStage.show();
}
style.css
.start-stop.toggle-button {
base-color: #85eca5;
-fx-background-color: base-color;
}
.start-stop.toggle-button:selected {
base-color: #ff6060;
}
.start-stop.toggle-button:hover {
-fx-background-color: derive(base-color, -20%);
}
If you cannot use derive since you need to specify different colors for all 4 states you could still rely on looked-up colors to avoid relying on the rule ordering:
.start-stop.toggle-button {
unselected-color: blue;
selected-color: yellow;
-fx-background-color: unselected-color;
}
.start-stop.toggle-button:hover {
unselected-color: red;
selected-color: green;
}
.start-stop.toggle-button:selected {
-fx-background-color: selected-color;
}
I use this CSS to add icon to menuItem on JavaFX application:
#mniOpen > .label{
-fx-graphic:url(media/open.png);
}
It works, but one problem: my menuItem has a shortcut key (Ctrl+O), so in this item there are two label. In the result, the icon repeats twice for this menuItem:
How can remove the second icon (for Ctrl+O) ?
Using css
#mniOpen > .label{
-fx-graphic: url("media/open.png");
}
#mniOpen .accelerator-text{
-fx-graphic: none;
}
Without using css
Image openIcon = new Image(getClass().getResourceAsStream("media/open.png"));
ImageView openView = new ImageView(openIcon);
openView.setFitWidth(15);
openView.setFitHeight(15);
MenuItem newMenuItem = new MenuItem("Open");
newMenuItem.setGraphic(openView);
newMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.O, KeyCombination.CONTROL_DOWN));
Can anyone please help me with wrapping the text in a legend of a javafx chart. I have pie charts and bar charts. All the legends are placed at bottom. I tried the following but couldn't get it working.
for (Node node : pie.lookupAll(".chart-legend")) {
if (node instanceof Text) {
System.out.println("Text instance");
((Text) node).setWrappingWidth(380);
((Text) node).setManaged(true);
}
if (node instanceof Label) {
System.out.println("Label instance");
((Label) node).setWrapText(true);
((Label) node).setManaged(true);
((Label) node).setPrefWidth(380);
}
}
EDIT:
See the highlighted part. Still some text is not visible.
I finally got it. Trying to wrap text in css didn't work as label width cannot be controlled there. So the following code can be used to wrap the text programmatically.
for (Node node : pie.lookupAll(".chart-legend-item")) {
if (node instanceof Label) {
System.out.println("Label instance");
((Label) node).setWrapText(true);
((Label) node).setManaged(true);
((Label) node).setPrefWidth(380);
}
}
Did you have a look at the CSS documentation?
This link is refering to the chart legend section:
JavaFX CSS Reference
As mentioned, it's of the type Label, so we can have a look here as well.
-fx-wrap-text possibly does the trick. Of course you would need to write and attach your own CSS file to your program...
For a more detailed example, please refer to your JDKs jfxrt.jar, unzip it and look for the modena.css, which is the default CSS file.
Regards.
Daniel
Edit: I got the following snipped to actually have an impact on or application after all:
.chart-legend {
-fx-background-color: transparent;
-fx-padding: 20px;
}
.chart-legend-item-symbol {
-fx-background-radius: 0;
}
.chart-legend-item {
-fx-text-fill: #191970;
}
But it is important, where you place it in your CSS. In my first attempt, I placed it above the CSS rule, which set the default label text color.
When I noticed this, I put it at the end of my CSS file: et vĂ³ila - it worked.
So please have a second look, that your placed accordingly in your own CSS.
Here is a strange problem I am having, althougt I have a work around I would still like to understand why it is happening.
Here is my Composite class
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.*;
public class ExpandingOvalButton extends Composite implements HasClickHandlers
{
private PushButton button;
private Label label = new Label();
private AbsolutePanel panel = new AbsolutePanel();
public ExpandingOvalButton(String text)
{
int width = 40;
initWidget( panel );
Image image = new Image( "icons/ovalBlueButton.png");
label.setText(text);
width = width + (text.length() * 8);
String widthStr = width + "px";
image.setWidth(widthStr);
image.setHeight("50px");
button = new PushButton( image );
button.setWidth(widthStr);
button.setHeight("50px");
panel.setSize(widthStr, "50px");
panel.add(button, 0, 0);
panel.add(label, 18, 14);
}
...
It works perfectly for me when I add it to a flex table along with other widget and then I can apply css styles to the flextable and position it fine. Problem is if I want to apply css positioning to a ExpandingOvalButton instance which does not sit inside of an other panel it does not work properly.
private ExpandingOvalButton startBtn = new ExpandingOvalButton("Start");
startBtn .getElement().setId("myId");
#myId
{
position: absolute;
left: 30%;
top: 120px;
}
This will NOT position itself 30% from the left side.
However if I add startBtn to a Panel and then apply the same CSS style to the Panel it WILL position itself 30% from the left.
panel.add(startBtn);
panel.getElement().setId("myId");
Anyone come across this before or know what might be causing it?
If you look at the source code for AbsolutePanel, you will find this in the constructor:
DOM.setStyleAttribute(getElement(), "position", "relative");
This has priority over the styles declared in your css. You can force it to use absolute positioning by doing something similar:
DOM.setStyleAttribute(startBtn.getElement(), "position", "absolute");