Skip to content

Instantly share code, notes, and snippets.

@seraphy
Created December 26, 2018 04:22
Show Gist options
  • Save seraphy/af06d3fdb39719f6c17f2e429c86e62a to your computer and use it in GitHub Desktop.
Save seraphy/af06d3fdb39719f6c17f2e429c86e62a to your computer and use it in GitHub Desktop.
Swingによるリサイズ可能なエラーダイアログの実装例
package jp.seraphyware.learnswing;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Point;
import java.awt.Window;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
* Swingによるリサイズ可能なエラーダイアログの実装例
*/
public class ErrorDialogExample implements Runnable {
@Override
public void run() {
// プライマリスクリーンの中央位置を取得する
GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
Point pt = genv.getCenterPoint();
// 中央にサイズ0、透過、枠装飾なしで、見えないダミーフレームを表示させる
// これによりタスクバーにはウィンドウがあることを示し、このウィンドウにエラーダイアログを関連づける
JFrame dummyFrame = new JFrame();
dummyFrame.setUndecorated(true);
dummyFrame.setSize(0, 0);
dummyFrame.setOpacity(0);
dummyFrame.setLocation(pt);
dummyFrame.setVisible(true);
showErrorDialog(dummyFrame, new Exception("test exception!"));
dummyFrame.dispose(); // ダミーを破棄する
}
/**
* 例外が発生したことを示すリサイズ可能なダイアログを表示する.<br>
* @param parent ダイアログを表示する親、null可
* @param ex 例外、nullの場合はなにもせずに戻る.
*/
public static void showErrorDialog(Component parent, Throwable ex) {
if (ex == null) {
return;
}
// 例外を表示するパネルの生成
JTextArea textArea = new JTextArea();
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw); // 例外のコールスタックをパネルに表示できるように出力
pw.close();
textArea.setText(sw.toString());
textArea.setSelectionStart(0);
textArea.setSelectionEnd(0);
textArea.setEditable(false);
JScrollPane scr = new JScrollPane(textArea);
scr.setPreferredSize(new Dimension(400, 150));
scr.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scr.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
// ダイアログの表示
//JOptionPane.showMessageDialog(parent, scr, "ERROR", JOptionPane.ERROR_MESSAGE);
// 以下、JOptionPaneの既定の処理を真似つつ、リサイズ可能なダイアログを作成する
JOptionPane pane = new JOptionPane(scr, JOptionPane.ERROR_MESSAGE);
Window window = getWindowForComponent(parent);
System.out.println("window=" + window);
JDialog dialog;
String title = "ERROR";
if (window instanceof Frame) {
dialog = new JDialog((Frame) window, title, true);
} else {
dialog = new JDialog((Dialog) window, title, true);
}
Container contentPane = dialog.getContentPane();
// xボタンでダイアログを破棄する
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
contentPane.setLayout(new BorderLayout());
contentPane.add(pane, BorderLayout.CENTER);
dialog.setResizable(true);
dialog.pack();
dialog.setLocationRelativeTo(parent);
pane.addPropertyChangeListener(JOptionPane.VALUE_PROPERTY, new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (dialog.isVisible() && event.getNewValue() != null) {
// ボタン押下等によりダイアログの結果が確定したらダイアログを破棄する
dialog.dispose();
}
}
});
dialog.setVisible(true);
}
static Window getWindowForComponent(Component parentComponent)
throws HeadlessException {
if (parentComponent == null)
return JOptionPane.getRootFrame();
if (parentComponent instanceof Frame || parentComponent instanceof Dialog)
return (Window) parentComponent;
return getWindowForComponent(parentComponent.getParent());
}
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new ErrorDialogExample());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment