Skip to content

Instantly share code, notes, and snippets.

@jewelsea
Created August 17, 2012 22:45
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jewelsea/3383311 to your computer and use it in GitHub Desktop.
Save jewelsea/3383311 to your computer and use it in GitHub Desktop.
JavaFX sample of a round closing button
/**
* roundbutton.css: place in same directory as RoundButton.java and
* ensure the build system copies it to the same directory as RoundButton.class
*/
.root {
-fx-padding: 10;
-fx-background-color: coral;
}
.closebutton .button {
-fx-background-color: white, white;
-fx-background-radius: 16.4, 15;
-fx-background-insets: -1.4, 0;
-fx-border-radius: 15;
-fx-border-width: 2;
-fx-border-color: dimgrey;
-fx-padding: 0;
-fx-font-size: 0;
}
.closebutton .button:focused {
-fx-background-color: -fx-focus-color, white;
}
.closebutton .closetext {
-fx-stroke: dimgrey;
-fx-fill: dimgrey;
-fx-font-size: 20;
-fx-translate-y: -1;
}
.closebutton .closeicon {
-fx-stroke: dimgrey;
-fx-stroke-width: 2;
}
.closebutton:hover {
-fx-effect: innershadow(gaussian, blue, 15, 0, 0, 0);
}
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.SVGPathBuilder;
import javafx.scene.text.TextBuilder;
import javafx.stage.Stage;
/**
* Sample code for: https://forums.oracle.com/forums/thread.jspa?threadID=2428756 "Problem with a circle shaped border around a button"
*
* Demonstrates three different methods of creating an icon in a scalable close button.
*/
public class RoundButton extends Application {
public static void main(String[] args) { launch(args); }
private DoubleBinding scaleFactor;
@Override public void start(Stage primaryStage) {
EventHandler<ActionEvent> exitHandler = new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
Platform.exit();
}
};
HBox layout = new HBox(10);
layout.getChildren().addAll(
scaleTo( 60, closeButton(textCloseIcon(), exitHandler)),
scaleTo( 90, closeButton(pathCloseIcon(), exitHandler)),
scaleTo(120, closeButton(svgPathCloseIcon(), exitHandler))
);
layout.getStylesheets().add(this.getClass().getResource("roundbutton.css").toExternalForm());
primaryStage.setScene(new Scene(layout));
primaryStage.show();
}
private Region closeButton(Node closeIcon, EventHandler<ActionEvent> actionHandler) {
final double BUTTON_SIZE = 30;
StackPane closeButton = new StackPane();
closeButton.getStyleClass().add("closebutton");
Button button = new Button();
button.setOnAction(actionHandler);
closeIcon.setMouseTransparent(true);
closeButton.getChildren().addAll(button, closeIcon);
button.setMinSize(BUTTON_SIZE, BUTTON_SIZE);
closeButton.setPrefSize(BUTTON_SIZE, BUTTON_SIZE);
closeButton.setMaxSize(StackPane.USE_PREF_SIZE, StackPane.USE_PREF_SIZE);
return closeButton;
}
private Node textCloseIcon() {
return TextBuilder.create()
.text("X")
.styleClass("closetext")
.build();
}
private Node pathCloseIcon() {
Path path = new Path();
path.getElements().addAll(
new MoveTo( 9, 9),
new LineTo(21, 21),
new MoveTo( 9, 21),
new LineTo(21, 9)
);
path.getStyleClass().add("closeicon");
return path;
}
private Node svgPathCloseIcon() {
return SVGPathBuilder.create()
.content("M9 9 L21 21 M9 21 L21 9")
.styleClass("closeicon")
.build();
}
private Group scaleTo(double size, Region n) {
Group g = new Group(n);
scaleFactor = (new SimpleDoubleProperty(size)).divide(n.widthProperty());
n.scaleXProperty().bind(scaleFactor);
n.scaleYProperty().bind(scaleFactor);
return g;
}
}
@jewelsea
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment