ともさんのHP >プロブラミング >JavaFX >JavaFX Alertダイアログを最前面


JavaFX Alertダイアログを最前面に表示する方法

JavaFXではAlertクラスを用いてメッセージダイアログを表示します。こちらもご覧下さい。
このAlertダイアログを常に最前面に表示できるようなClassを作りましたので紹介します。

広告


いきさつ

普通に使うのであれば問題ないのですが、表示元の親Stageが、常に前面表示(alwaysOnTop)にセットされていた場合、ダイアログはこのStageの背面に表示されてしまいます。
並べて表示されれば判りますが、完全に隠れるとフリーズしたように見えてしまいます。
現在作成しているフリーソフトでは、親ステージの設定のために子ステージを開き、親ステージ上のノードをマウスで選択する場面があります。
この時、子ステージをalwaysOnTopに設定しておかないと、親ステージ上をクリックした瞬間に子ステージが隠れてしまいます。
この子ステージの上にダイアログを表示させていのです。
普通にダイアログを表示させたら、子ステージの裏に隠れてしまいます。ダイアログもalwaysOnTopに設定すればよいのですが、StageのようにsetAlwaysOnTop()メソッドが用意されていません。

解決策

Alertオブジェクトと同時にStageオブジェクトも作り、Alert内のDialogPaneをStageに貼り付けます。
Alertは表示せず、StageをalwaysOnTopに設定したうえで表示させます。
これで解決。


ダイアログを親Stageの中央に表示する

ダイアログはそのままだとモニターの中央に表示されます。これだとマウスの移動量が大きいので、親になるStageの中央に表示させるメソッドも次いでにつけました。

/**位置を親stageの中心にする*/
private void setPosition( Stage stage ){
 if(stage==null){ return; }
 this.setX( stage.getX() + stage.getWidth()/2. -dpane.getPrefWidth()/2. );
 this.setY( stage.getY() + stage.getHeight()/2. -dpane.getPrefHeight()/2. );
 return;
}


広告

サンプルプログラム

AlertTopは常に前面表示されるメッセージダイアログクラスです。
警告ダイアログを最前面に表示

package tomojavalib.swingfx;

import java.util.Optional;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.DialogPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonBase;

public class AlertTop extends Stage{
DialogPane dpane = null;
Alert alert = null;
public Optional<ButtonType> buttonType = null;

public AlertTop(Stage stage , AlertType alertType , String information , ButtonType b1 ) {
super(StageStyle.UTILITY);
 alert = new Alert(AlertType.INFORMATION , information , b1 );
 this.setOnTop();
 this.setPosition( stage );
}

public AlertTop(Stage stage , AlertType alertType , String information , ButtonType b1, ButtonType b2 ) {
super(StageStyle.UTILITY);
 alert = new Alert(AlertType.INFORMATION , information , b1 , b2 );
  this.setOnTop();
  this.setPosition( stage );
}

public AlertTop(Stage stage , AlertType alertType , String information , ButtonType b1, ButtonType b2 , ButtonType b3 ) {
super(StageStyle.UTILITY);
 alert = new Alert(AlertType.INFORMATION , information , b1 , b2 ,b3 );
  this.setOnTop();
  this.setPosition( stage );
}

/**位置を親stageの中心にする*/
private void setPosition( Stage stage ){
 if(stage==null){ return; }
 this.setX( stage.getX() + stage.getWidth()/2. -dpane.getPrefWidth()/2. );
 this.setY( stage.getY() + stage.getHeight()/2. -dpane.getPrefHeight()/2. );
 return;
}


/**常に前面に表示*/
private void setOnTop(){
 alert.getDialogPane().setPrefSize(300, 200);
 dpane = alert.getDialogPane();
 for (ButtonType buttonType : dpane.getButtonTypes()) {
  ButtonBase button = (ButtonBase) dpane.lookupButton(buttonType);
  button.setOnAction(evt -> {
   dpane.setUserData(buttonType);
   this.close();
  });
 }
dpane.getScene().setRoot(new Group());
dpane.setPadding(new Insets(10, 0, 10, 0));
Scene scene = new Scene(dpane);
this.setScene(scene);
this.initModality(Modality.APPLICATION_MODAL);
this.setAlwaysOnTop(true);
this.setResizable(false);
return;
}

/**結果を返す*/
public Optional<ButtonType> getResult(){
 this.showAndWait();
 //System.out.println("result: "+result.orElse(null));
 buttonType = Optional.ofNullable((ButtonType) dpane.getUserData());
 return buttonType ;
}

}


実行クラス

ページトップの動画は下記クラスを実行したものです。

package tomojavalib.swingfx;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.input.MouseEvent;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.*;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class AlertTopTestFx extends Application {
Stage stage = null;
Text t = null;

 public static void main(String[] args) {
  Application.launch(args);
 }

 @Override
 public void start(Stage stage) throws Exception {
  this.stage = stage;
  stage.setTitle("JavaFX楽天 ");
  VBox pane = new VBox();
  Scene scene = new Scene(pane, 320, 240);
  Button b = new Button("ボタン");
  b.setOnMouseClicked((MouseEvent e)->{ mouseClicked( e ); });
  t = new Text(" ");
  pane.getChildren().add( b );
  pane.getChildren().add( t );
  stage.setScene(scene);
  stage.show();
  stage.setAlwaysOnTop(true);
 }

private void mouseClicked(MouseEvent e){
 AlertTop aot = new AlertTop( this.stage , AlertType.INFORMATION , "テストです"  , ButtonType.YES , ButtonType.NO );
 ButtonType button  = aot.getResult().orElse( ButtonType.CANCEL );
 t.setText( button.getText() );
 //if( button.getText().equals("はい") ){ System.exit(0); }
}

}


最終更新日: 2018-02-21 07:15:35

ともさんのHP >プロブラミング >JavaFX >JavaFX Alertダイアログを最前面

このエントリーをはてなブックマークに追加
広告
おすすめ記事
新着ページ

備中鍬の修繕  
薪ストーブの掃除  
普通のブラウスの作りかた  
竹の固縛  
あじさいの栽培、手入れ、増やしかた  
除草剤の特性  
ガゼボのDIY  
アロハシャツ(開襟シャツ)の型紙  
トウモロコシ栽培  
ヒマワリの栽培、手入れ、増やしかた  
クサガメ飼のいかた  

私の他のサイト

ともさんの箱庭(ブログ)
家庭菜園
3D-CAD
洋裁CAD

いいねなど

 RSS 
PageSpeedInsights
html5チェック

Author: Tomoyuki Ito

このサイトの文章・写真の無断転載を禁じます