Вопрос по – JavaFX - создать пользовательскую кнопку с изображением

21

Я хотел бы создать пользовательскую кнопку с двумя состояниями нажатой или нет, например, кнопкой переключения. У меня есть два изображения для этого (нажата и не нажата), так как я могу создать кнопку и отобразить ее с моими изображениями? Кнопка должна принять размер изображения.
Я не использую FXML. Спасибо за помощь.

Ваш Ответ

3   ответа
3

сс, который наследуется от Button. Примечание: updateImages () должен быть вызван перед показом кнопки.

import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;

public class ImageButton extends Button {

    public void updateImages(final Image selected, final Image unselected) {
        final ImageView iv = new ImageView(selected);
        this.getChildren().add(iv);

        iv.setOnMousePressed(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent evt) {
                iv.setImage(unselected);
            }
        });
        iv.setOnMouseReleased(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent evt) {
                iv.setImage(selected);
            }
        });

        super.setGraphic(iv);
    }
}
6

унаследованный от родительского. Поместите ImageView на это, и на события mousedown и mouse up просто измените изображения ImageView.

public class ImageButton extends Parent {

    private static final Image NORMAL_IMAGE = ...;
    private static final Image PRESSED_IMAGE = ...;

    private final ImageView iv;

    public ImageButton() {
        this.iv = new ImageView(NORMAL_IMAGE);
        this.getChildren().add(this.iv);

        this.iv.setOnMousePressed(new EventHandler<MouseEvent>() {

            public void handle(MouseEvent evt) {
                iv.setImage(PRESSED_IMAGE);
            }

        });

        // TODO other event handlers like mouse up

    } 

}
Error: User Rate Limit Exceeded jerome
49

ИспользоватьКнопка-переключатель и применить собственный стиль к нему. Я предлагаю это, потому что ваш требуемый элемент управления "как кнопка переключения" но выглядит просто по-другому от стиля кнопки переключения по умолчанию.

Мой предпочтительный метод состоит в том, чтобы определить графику для кнопки в CSS:

.toggle-button {
  -fx-graphic: url('http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Pizza-icon.png');
}

.toggle-button:selected {
  -fx-graphic: url('http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Piece-of-cake-icon.png');
}

ИЛИ используйте прикрепленный CSS, чтобы определить фоновое изображение.

// file imagetogglebutton.css deployed in the same package as ToggleButtonImage.class
.toggle-button {
  -fx-background-image: url('http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Pizza-icon.png');
  -fx-background-repeat: no-repeat;
  -fx-background-position: center;
}

.toggle-button:selected {
  -fx-background-image: url('http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Piece-of-cake-icon.png');
}

Я предпочитаю спецификацию -fx-graphic над спецификациями -fx-background- *, поскольку правила для стилизации фоновых изображений хитры, и установка фона не приводит к автоматическому изменению размера кнопки к изображению, в то время как настройка графики делает это.

И пример кода:

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.StackPaneBuilder;
import javafx.stage.Stage;

public class ToggleButtonImage extends Application {
  public static void main(String[] args) throws Exception { launch(args); }
  @Override public void start(final Stage stage) throws Exception {
    final ToggleButton toggle = new ToggleButton();
    toggle.getStylesheets().add(this.getClass().getResource(
      "imagetogglebutton.css"
    ).toExternalForm());
    toggle.setMinSize(148, 148); toggle.setMaxSize(148, 148);
    stage.setScene(new Scene(
      StackPaneBuilder.create()
        .children(toggle)
        .style("-fx-padding:10; -fx-background-color: cornsilk;")
        .build()
    ));
    stage.show();
  }
}

Некоторые преимущества этого:

You get the default toggle button behavior and don't have to re-implement it yourself by adding your own focus styling, mouse and key handlers etc. If your app gets ported to different platform such as a mobile device, it will work out of the box responding to touch events rather than mouse events, etc. Your styling is separated from your application logic so it is easier to restyle your application.

Альтернативой является не использовать css и все еще использовать ToggleButton, но установить графическое изображение в коде:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.scene.*;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.*;
import javafx.scene.layout.StackPaneBuilder;
import javafx.stage.Stage;

public class ToggleButtonImageViaGraphic extends Application {
  public static void main(String[] args) throws Exception { launch(args); }
  @Override public void start(final Stage stage) throws Exception {
    final ToggleButton toggle      = new ToggleButton();
    final Image        unselected  = new Image(
      "http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Pizza-icon.png"
    );
    final Image        selected    = new Image(
      "http://icons.iconarchive.com/icons/aha-soft/desktop-buffet/128/Piece-of-cake-icon.png"
    );
    final ImageView    toggleImage = new ImageView();
    toggle.setGraphic(toggleImage);
    toggleImage.imageProperty().bind(Bindings
      .when(toggle.selectedProperty())
        .then(selected)
        .otherwise(unselected)
    );

    stage.setScene(new Scene(
      StackPaneBuilder.create()
        .children(toggle)
        .style("-fx-padding:10; -fx-background-color: cornsilk;")
        .build()
    ));
    stage.show();
  }
}

Преимущество подхода, основанного на коде, заключается в том, что вам не нужно использовать css, если вы не знакомы с ним.

Для лучшей производительности и простоты портирования на неподписанные песочницы апплета и веб-запуска, связывайте изображения с вашим приложением и ссылайтесь на них по относительным URL-адресам, а не загружайте их из сети.

Error: User Rate Limit Exceeded jerome
Error: User Rate Limit Exceeded jerome
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы