質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

527閲覧

JavaFXでのBackgroundImageの中央指定

glat2238

総合スコア124

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2018/03/15 05:46

編集2018/03/17 01:02

###JavaFXでのBackgroundImageの中央指定
今、JavaFXで簡単なアプリケーションを作成しているのですが画像を読み込めても中央に表示することができません。(画面を縮小すると画像が左寄りになってしまう)
BackgroundPosition.CENTERを追加したのですが画像が左寄りです。
これを中央に寄せられないでしょうか?
できなければ画面の横を縮めたら縦も比例して縮まるように設定などできないでしょうか。
どなたか教えてください。

該当のソースコード

public class Main extends Application {

@Override public void start(Stage stage) throws MalformedURLException, URISyntaxException { Image img = new Image(new File(SFile.getApplicationPath(Main.class).getParent +File.separator +"data" + File.separator + "client" + File.separator + "image" + File.separator + "image.png").toURI().toURL().toString()); BackgroundSize bs = new BackgroundSize(BackgroundSize.AUTO, BackgroundSize.AUTO, false,false, false, true); BackgroundImage bimg = new BackgroundImage(img, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER, bs); Background background = new Background(bimg); StackPane root = new StackPane(); root.setBackground(background); Scene scene = new Scene(root, 800, 500); stage.setScene(scene); stage.setFullScreen(true); stage.show(); } public static void main(String[] args) { launch(args); }

}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

BackgroundSizeのcovertをfalseにcontainをtrueにしてみてはいかがでしょうか?


追記:質問者さんの本来の期待(処理をごりごり書くのではなく、制約として記述すること?)はCSSあるいはCSS相当のBackgroundによる指定だと思うのですが、自分には指定方法がわかりません。

回避策として多少処理を書くのであれば次のようには書けると思います。背景画像ではなくStackPaneの一番底にImageViewを配置する方法です。ImageViewならfitWidth, fitHeight, viewportの各プロパティーを制御することで比較的自由度の高い配置がプログラミングできるかと思います。

java

1public class FxImageTest extends Application { 2 @Override 3 public void start(Stage stage) throws Exception { 4 Image img = new Image(FxImageTest.class.getResource("image2.jpg") 5 .toURI().toURL().toString()); 6 7 StackPane root = new StackPane(); 8 9 ImageView iv = new ImageView(); 10 iv.fitWidthProperty().bind(root.widthProperty()); 11 iv.fitHeightProperty().bind(root.heightProperty()); 12 Binding<Rectangle2D> viewport = Bindings.createObjectBinding( 13 () -> { 14 Image image = iv.getImage(); 15 if (image == null) return null; 16 double vpWidth = Math.max(1, image.getWidth()); 17 double vpHeight = Math.max(1, image.getHeight()); 18 double imageRatio = vpWidth / vpHeight; 19 Bounds bounds = root.getBoundsInLocal(); 20 double boundsRatio = Math.max(1, bounds.getWidth()) 21 / Math.max(1, bounds.getHeight()); 22 if (boundsRatio > imageRatio) { 23 // 元画像の上下をカット 24 vpHeight = vpWidth / boundsRatio; 25 } else { 26 // 元画像の左右をカット 27 vpWidth = vpHeight * boundsRatio; 28 } 29 return new Rectangle2D( 30 (image.getWidth() - vpWidth) * 0.5, 31 (image.getHeight() - vpHeight) * 0.5, 32 vpWidth, vpHeight); 33 }, 34 root.boundsInLocalProperty(), iv.imageProperty()); 35 iv.setImage(img); // viewportの初期値を設定するため。 36 37 viewport.addListener((ob, ov, nv) -> iv.setViewport(nv)); // ※補足参照 38 39 Button button = new Button("toggle background"); 40 button.setOnAction(ev -> iv.setImage(iv.getImage() == null ? img : null)); 41 button.setPrefSize(150, 30); 42 43 root.getChildren().addAll(iv, button); 44 45 Scene scene = new Scene(root, 800, 500); 46 47 stage.setScene(scene); 48 stage.show(); 49 } 50}

※補足:
コード中の※の行ですが、本当は
iv.viewportProperty().bind(viewport);
と書きたいところですが、そうやってしまうとstack overflowが起きます。

JavaFXのプロパティーのバインドはObserverパターンを非常に簡単に利用できる点はよいのですが、ジオメトリー(ノードのレイアウト)にかかわるプロパティーに下手に依存関係を定義してしまうと内部のレイアウト処理の実装からの影響で、依存関係の循環が発生してしまう点に注意が必要です。

本件ではChangeListener経由でviewportプロパティーの設定をすることで一応回避できているように見えますが、ChangeListenerは万能ではなく、プロパティーの依存関係に本質的に巡回関係ができてしまうとどうやってもNGになる場合もあります。

投稿2018/03/15 06:04

編集2018/03/17 06:12
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

glat2238

2018/03/15 06:25

すみません聞き方が悪かったです。 containをtrueにすると中央になるのですが余白ができてしまって… Swingを使っていたころは縦と横の小さいほうの割合に合わせて中央に配置していたので端は(見えないため)自動でカットされていたのですが、FXでそれをすると左端に寄ってしまうのですが他に解決する方法はないでしょうか?
KSwordOfHaste

2018/03/15 06:52

失礼しました。 - 画像のアスペクト比を保ったまま - 中央寄せで - 空白部分がないように入りきらない部分を切り捨てる といういうことですね。 目的にあってなかったので、BAは無理につけない方がよいです。他のよい回答がついたらBAの付け替えはお気遣いなくどうぞ。
glat2238

2018/03/15 06:58

すいません。色々めんどくさくしてしまって…
KSwordOfHaste

2018/03/15 07:30 編集

「CSSのみを使って上記のようにするにはどうすればよいか?」という観点で調べてみてはいかがでしょう?JavaFXのBackgroundは要するにCSSの機能を表した一つの実装ですので完全に一致しないまでもCSSでできることならそのとおりにすれば実現できる可能性があると思います。 調べて分からなかったら、JavaFXのタグに加えてHTML/CSSのタグを追加してJavaFXが目的だけどHTML/CSSで背景画像をこうするにはどうしたらよいかという質問に拡張してみるとコメントがつきやすいかも知れません。JavaFXは使わなくてもHTML/CSSのエキスパートの方は多いと思います。 (自分は恥ずかしながらCSSド素人なんです...スミマセン)
glat2238

2018/03/15 07:34

ありがとうございます。CSSについて調べてみます。 (私もCSS全然わからなくて困ってますw)
glat2238

2018/03/17 06:09

出来ました! ありがとうございます。
KSwordOfHaste

2018/03/17 06:15

cssでできたかどうかに興味がありますが・・・ひょっとして自分の追記(回避策)ぐらいしかありませんでした?
glat2238

2018/03/19 03:57

CSSでやっても同じ結果でしたw 何かのバグですかね?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問