概要

Modalで透明なJDialogを表示することで、親のJFrame全体への入力操作をブロックします。

スクリーンショット

BlockingDialog.png

サンプルコード

JButton button = new JButton("Stop 5sec");
button.addActionListener(e -> {
  Window w = SwingUtilities.getWindowAncestor(getRootPane());
  JDialog dialog = new JDialog(w, Dialog.ModalityType.APPLICATION_MODAL);
  dialog.setUndecorated(true);
  dialog.setBounds(w.getBounds());
  dialog.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
  int color = check.isSelected() ? 0x22_FF_00_00 : 0x01_00_00_00;
  dialog.setBackground(new Color(color, true));
  new BackgroundTask() {
    @Override protected void done() {
      if (!isDisplayable()) {
        cancel(true);
        return;
      }
      dialog.setVisible(false);
    }
  }.execute();
  dialog.setVisible(true);
});
// ...
class BackgroundTask extends SwingWorker<String, Void> {
  @Override protected String doInBackground() throws InterruptedException {
    Thread.sleep(5_000);
    return "Done";
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、以下のような設定を行ったJDialogを表示することで親JFrameのタイトルバー、閉じる、最大化、最小化ボタンを含めて一定時間入力不可にするテストを行っています。

  • モーダル(Dialog.ModalityType.DOCUMENT_MODAL)なJDialogを作成
  • dialog.setUndecorated(true)でタイトルバーなどの装飾を非表示に設定
  • JDialogのカーソルをCursor.WAIT_CURSORに設定
  • JDialogの背景色を透明(完全に透明ではない)に設定
  • 注: このサンプルにはJDialogの表示を途中で中断する方法がない

参考リンク

コメント