23

トグルボタンのように、2つの状態が押されているかどうかに関係なく、カスタムボタンを作成したいと思います。これを行うために2つの画像(押されたものと押されていないもの)がありますが、ボタンを作成して画像と一緒に表示するにはどうすればよいですか?ボタンは画像のサイズにする必要があります。
FXMLを使用していません。助けてくれてありがとう。

4

3 に答える 3

52

これを達成するためのいくつかの異なる方法があります、私は私のお気に入りの概要を説明します。

ToggleButtonを使用して、カスタムスタイルを適用します。必要なコントロールは「トグルボタンのようなもの」ですが、デフォルトのトグルボタンのスタイルとは異なって見えるため、これをお勧めします。

私の好みの方法は、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-background-*仕様よりも-fx-graphic仕様の方が適しています。

そしていくつかのサンプルコード:

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();
  }
}

これを行うことのいくつかの利点は次のとおりです。

  1. デフォルトのトグルボタンの動作を取得し、独自のフォーカススタイル、マウス、キーハンドラーなどを追加して、自分で再実装する必要はありません。
  2. アプリがモバイルデバイスなどの別のプラットフォームに移植された場合、マウスイベントなどではなく、タッチイベントに応答してすぐに機能します。
  3. スタイリングはアプリケーションロジックから分離されているため、アプリケーションのスタイルを簡単に変更できます。

別の方法は、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を使用する必要がないという利点があります。

最高のパフォーマンスと署名されていないアプレットおよびWebstartサンドボックスへの移植を容易にするために、画像をアプリにバンドルし、ネットからダウンロードするのではなく、相対パスURLで参照します。

于 2012-05-09T19:38:31.177 に答える
7

親から継承した独自のクラスを作成する必要があります。その上に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

    } 

}
于 2012-05-09T15:12:56.343 に答える
4

前の2つの答えの組み合わせがトリックをしました。ありがとう。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);
    }
}
于 2015-08-16T11:40:40.997 に答える