Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a button appear to have been clicked or selected? (JavaFX2)

Tags:

javafx-2

When user presses a button in my JavaFX2.2 UI, a dark blue halo appears to show it was clicked. During the course of events, my program may want to 'unclick' it to show it is no longer selected.

I expected a button.setSelected(false); I remember Swing used to have this, but there isn't such a call in JavaFx. This article discusses drop shadows but I want to simply use the same appearance used when a button is clicked which isn't really a drop shadow. setEffect(new DropShadow()) Using setStyle() is ok, but what values to use?

like image 926
likejudo Avatar asked Apr 04 '13 18:04

likejudo


2 Answers

I think for your description, that you actually want a ToggleButton rather than a standard Button.

There is a nice Oracle tutorial on ToggleButtons.

enter image description here


Addressing Items from the Question

dark blue halo appears to show it was clicked

The blue halo is actually a focus ring indicating that a control has focus. To focus a control, you can invoke the requestFocus method.

During the course of events, my program may want to 'unclick' it to show it is no longer selected.

To remove focus from a control, you can call requestFocus on another control to focus on that control instead.

I expected a button.setSelected(false);

To have a button which can toggle between a selected and unselected state, use a ToggleButton. A ToggleButton has a setSelected method.

setEffect(new DropShadow()) Using setStyle() is ok, but what values to use

css style values for drop shadow effects are define in the JavaFX CSS Reference Guide.

It is visually equivalent to define the drop shadow effect in code via setEffect or via css with setStyle or applying a style class from a stylesheet. Of the three approaches, I would never recommend the setStyle approach, but only the css from stylesheet or the setEffect from code approach.


Related

Note there is an additional related property - armed:

Indicates that the button has been "armed" such that a mouse release will cause the button's action to be invoked. This is subtly different from pressed. Pressed indicates that the mouse has been pressed on a Node and has not yet been released. arm however also takes into account whether the mouse is actually over the button and pressed.

A button in an armed state has a slightly different look than one which is not in an armed state. Most programs never need to interact with the armed state of buttons.


Sample for styling the selected state

The standard way to differentiate a selected ToggleButton from one which is not Selected is to darken it to give it a depth style effect and make it appear further away when it has been pushed. Here is the standard toggle button css for JavaFX 2.2:

.toggle-button:selected {
    -fx-background-color:
        -fx-shadow-highlight-color,
        linear-gradient(to bottom, derive(-fx-color,-90%) 0%, derive(-fx-color,-60%) 100%),
        linear-gradient(to bottom, derive(-fx-color,-60%) 0%, derive(-fx-color,-35%) 50%, derive(-fx-color,-30%) 98%, derive(-fx-color,-50%) 100%),
        linear-gradient(to right, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0) 10%, rgba(0,0,0,0) 90%, rgba(0,0,0,0.3) 100%);
    -fx-background-insets: 0 0 -1 0, 0, 1, 1;
    /* TODO: -fx-text-fill should be derived */
    -fx-text-fill: -fx-light-text-color;
}

You can override this default behavior by defining your own stylesheet that provides an alternate definition for the selected state. The sample below will ensure that the selected state display is much more subtle than the standard, only darkening the selected state color a small fraction rather than a lot.

toggle-plain Unselected

toggle-selected Selected

Associated css:

/**
 * file: colored-toggle.css
 *   Place in same directory as ColoredToggle.java.
 *   Have your build system copy this file to your build output directory.
 **/

.root {
  -fx-background-color: cornsilk; 
  -fx-padding: 10;
}

.toggle-button {
  -fx-color: paleturquoise;
}

.toggle-button:selected {
    -fx-background-color:
        -fx-shadow-highlight-color,
        linear-gradient(to bottom, derive(-fx-color,-22%) 0%, derive(-fx-color,-15%) 100%),
        linear-gradient(to bottom, derive(-fx-color,-15%) 0%, derive(-fx-color,-10%) 50%, derive(-fx-color,-8%) 98%, derive(-fx-color,-12%) 100%);
}

.toggle-button:selected:focused {
    -fx-background-color:
        -fx-focus-color,
        linear-gradient(to bottom, derive(-fx-color,-22%) 0%, derive(-fx-color,-15%) 100%),
        linear-gradient(to bottom, derive(-fx-color,-15%) 0%, derive(-fx-color,-10%) 50%, derive(-fx-color,-8%) 98%, derive(-fx-color,-12%) 100%);
}

Source file:

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ColoredToggle extends Application {
  public static void main(String[] args) { Application.launch(ColoredToggle.class, args); }

  @Override public void start(Stage stage) {
    ToggleButton visibilityControl = new ToggleButton("Winterfell");

    VBox layout = new VBox(10);
    layout.setAlignment(Pos.CENTER);
    layout.getChildren().setAll(visibilityControl);

    layout.getStylesheets().add(getClass().getResource("colored-toggle.css").toExternalForm());

    stage.setScene(new Scene(layout));
    stage.show();
  }
}
like image 151
jewelsea Avatar answered Oct 17 '22 08:10

jewelsea


From a css stylesheet this command also works. There is no need for a toggle button. Once you press a different button, focus changes to the new one.

.button:focused{
    -fx-background-color: gray;
like image 4
rainer Avatar answered Oct 17 '22 06:10

rainer