[英]Javafx Extends ToggleButton
I create a custom toggleButton that extends from ToggleButton. 我创建了一个自ToggleButton扩展的自定义toggleButton。
The problem is that it doesnt respect the ToggleGroup given to. 问题是它不尊重给定的ToggleGroup。 I can select more than one. 我可以选择多个。 But if you set the default class ToogleButton
, it only allow me to select one at a time. 但是,如果您设置默认类ToogleButton
,那么它只能让我一次选择一个。
private void createAvatarButton(Avatar avatar) {
MPButton button = new MPButton(avatar.getPath());
button.setToggleGroup(avatarGroup);
button.setUserData(avatar);
button.setPrefHeight(100);
button.setPrefWidth(200);
button.textProperty().bind(I18N.getString(TAG.getKey(avatar.getName())));
tilePane.getChildren().add(button);
}
public class MPButton extends ToggleButton {
/**************************************************************************
*
* Private fields
*
**************************************************************************/
private String image;
/**************************************************************************
*
* Constructors
*
**************************************************************************/
/**
* Creates a new CheckComboBox instance with an empty list of choices.
*/
private MPButton() {
}
public MPButton(String image) {
initialize(image);
}
private void initialize(String image) {
this.image = image;
getStyleClass().setAll(DEFAULT_STYLE_CLASS);
setAccessibleRole(AccessibleRole.TOGGLE_BUTTON);
// alignment is styleable through css. Calling setAlignment
// makes it look to css like the user set the value and css will not
// override. Initializing alignment by calling set on the
// CssMetaData ensures that css will be able to override the value.
((StyleableProperty<Pos>)(WritableValue<Pos>)alignmentProperty()).applyStyle(null, Pos.CENTER);
setMnemonicParsing(true); // enable mnemonic auto-parsing by default
}
/***************************************************************************
* *
* Stylesheet Handling *
* *
**************************************************************************/
/** {@inheritDoc} */
@Override protected Skin<?> createDefaultSkin() {
return new MPButtonSkin(this, image);
}
/***************************************************************************
* *
* Stylesheet Handling *
* *
**************************************************************************/
private static final String DEFAULT_STYLE_CLASS = "toggle-button";
/** {@inheritDoc} */
@Override
public String getUserAgentStylesheet() {
return MPButton.class.getResource("/styles/component/c-mpbutton.css").toExternalForm();
}
}
public class MPButtonSkin extends BehaviorSkinBase<ToggleButton, BehaviorBase<ToggleButton>>{
// visuals
private final ToggleButton toggleButton;
private final StackPane stackPane;
private Blend blush;
private Glow selectGlow;
private ColorAdjust disabledAdjust, monochromeAdjust;
private ImageView iconImageView;
private Pane pane;
private static final String SYMBOL = "/img/main/symbol.png";
public MPButtonSkin(ToggleButton control, String image) {
super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
toggleButton = new ToggleButton();
toggleButton.setText(control.getText());
toggleButton.alignmentProperty().setValue(Pos.BOTTOM_LEFT);
toggleButton.setStyle("-fx-background-color:transparent;");
stackPane = new StackPane();
toggleButton.setPadding(new Insets(0, 0, 4, 20));
pane = new Pane();
ResponsiveUtil.bindImageUrlCover(pane, getClass().getResource(image).toExternalForm());
HBox hbox = new HBox();
hbox.alignmentProperty().setValue(Pos.BOTTOM_LEFT);
Image iconImage = new Image(getClass().getResource(SYMBOL).toExternalForm());
iconImageView = new ImageView();
iconImageView.setFitHeight(15);
iconImageView.setFitWidth(15);
hbox.getChildren().add(iconImageView);
hbox.setPadding(new Insets(0, 0, 6, 0));
// Color Adjust
disabledAdjust = new ColorAdjust();
disabledAdjust.setBrightness(-0.7);
selectGlow = new Glow(2.7f);
monochromeAdjust = new ColorAdjust();
monochromeAdjust.setSaturation(-1.0);
monochromeAdjust.setBrightness(0.5);
blush = new Blend(BlendMode.MULTIPLY, monochromeAdjust,
new ColorInput(0, 0, pane.getWidth(), pane.getHeight(), Color.GOLD));
toggleButton.selectedProperty().addListener((o, ov, nv) -> {
if (nv) {
blush.setTopInput(new ColorInput(0, 0, pane.getWidth(), pane.getHeight(), Color.GOLD));
pane.setEffect(blush);
} else {
pane.setEffect(selectGlow);
}
});
toggleButton.disabledProperty().addListener((ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean nv) -> {
if (nv) {
pane.setEffect(disabledAdjust);
iconImageView.setImage(iconImage);
} else {
pane.setEffect(null);
iconImageView.setImage(null);
}
});
addWidthProperty(control);
addHeightProperty(control);
toggleButton.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
stackPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
pane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
stackPane.getChildren().addAll(pane, hbox, toggleButton);
stackPane.alignmentProperty().setValue(Pos.BOTTOM_LEFT);
getChildren().add(stackPane);
}
private void addWidthProperty(ToggleButton control) {
pane.prefWidthProperty().bind(control.prefWidthProperty());
stackPane.prefWidthProperty().bind(control.prefWidthProperty());
}
private void addHeightProperty(ToggleButton control) {
pane.prefHeightProperty().bind(control.prefHeightProperty());
stackPane.prefWidthProperty().bind(control.prefWidthProperty());
}
/**************************************************************************
*
* Overriding public API
*
* @return double
**************************************************************************/
@Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
return stackPane.minWidth(height);
}
@Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
return stackPane.minHeight(width);
}
@Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
return stackPane.prefWidth(height);
}
@Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
return stackPane.prefHeight(width);
}
@Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
return getSkinnable().prefWidth(height);
}
@Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
return getSkinnable().prefHeight(width);
}
}
The problem arises in MPButtonSkin's constructor. 问题出现在MPButtonSkin的构造函数中。 You create a new ToggleButton
every time: 您每次创建一个新的ToggleButton
:
public MPButtonSkin(ToggleButton control, String image) {
super(control, new BehaviorBase<>(control, Collections.<KeyBinding> emptyList()));
toggleButton = new ToggleButton();
toggleButton.setText(control.getText());
toggleButton.alignmentProperty().setValue(Pos.BOTTOM_LEFT);
toggleButton.setStyle("-fx-background-color:transparent;");
// ...
}
The problem is that the new ToggleButton
doesn't refer to the same ToggleGroup
(set to null by default). 问题在于新的ToggleButton
不会引用相同的ToggleGroup
(默认情况下设置为null)。 You can add it manually after constructing the new ToggleButton
: 您可以在构造新的ToggleButton
之后手动添加它:
// ...
toggleButton = new ToggleButton();
toggleButton.setToggleGroup(control.getToggleGroup()); // add this line
// ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.