java(swing)で、登録ボタンを押すとファイルを読み込みDBに登録する処理です。
その処理で、登録ボタンを押すと、ダイアログを起動して、処理中とメッセージ表示したいのですが、データが多く、画面が固まった状態になり、メッセージが表示されないのです。何かいい方法ありますでしょうか?
*******************************************************************
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class topMain {
public static void main(String[] args) {
//メニュー画面を起動する
topMain frame = new topMain();
frame.topFrame();
}
private void topFrame() {
JFrame jf = new JFrame();
//フレームのサイズ設定
jf.setSize(1000, 600);
jf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
jf.getContentPane().setLayout(null);
JButton b1 = new JButton("登録ボタン");
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//ダイアログボックスを開く
//ダイアログボックスは起動するが、
//メッセージが表示されない、
//おそらく大きいデータを読むとき画面が固まるため
//重いファイルを読み込む
//DB登録処理
//ダイアログを閉じる
}
});
jf.getContentPane().add(b1);
b1.setBounds(40, 400, 240, 100);
jf.setVisible(true);
}
}
*******************************************************************
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
actionPerformedメソッドはswingでの表示や入力などを処理している唯一のスレッドであるイベントディスパッチスレッド上で呼ばれ実行される。
したがってactionPerformed内で時間の掛かる処理をすることは表示処理などを行う機会が失われるのでこれを行ってはならない。
替わりにactionPerformed内では時間の掛かる処理を開始する機会だけを与えて、その処理自体は別スレッドで行うようにする。
例えばactionPerformed内を以下のような感じに。
final JDialog d = new JDialog();
d.add(new JLabel("ファイル読み込み&DB登録中"));
d.pack();
d.setVisible(true);
new Thread(new Runnable() {
public void run() {
...時間の掛かる処理をここに記述...
SwingUtilities.invokeLater(new Runnable() {
public void run() {
d.setVisible(false);
d.dispose();
}
});
}
}).start();
「時間の掛かる処理を行った後、ダイアログを閉じる」という処理をrunメソッドに書き、それを別スレッドで実行する。
上の例は非モーダルダイアログの場合で、モーダルダイアログの場合はsetVisible(true)した時点でダイアログが閉じられるまで処理が先に進まなくなるので、
final JDialog d = new JDialog((JFrame)null, true);
final JProgressBar pb = new JProgressBar();
pb.setIndeterminate(true);
pb.setStringPainted(true);
d.add(pb);
d.pack();
d.addWindowListener(new WindowAdapter() {
@Override public void windowOpened(WindowEvent e) {
new Thread(new Runnable() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
pb.setString("ファイルから読み込み中");
}
});
...時間の掛かる読み込み処理をここに記述...
SwingUtilities.invokeLater(new Runnable() {
public void run() {
pb.setString("DBへ登録中");
}
});
...時間の掛かる登録処理をここに記述...
SwingUtilities.invokeLater(new Runnable() {
public void run() {
d.setVisible(false);
d.dispose();
}
});
}
}).start();
}
});
d.setVisible(true);
のようにダイアログを開いた時点でスレッドを開始するようにWindowListenerを前もってダイアログに登録しておく方法が考えられる。
もし進捗状況まで示したいならJProgressBarやProgressMonitor、ProgressMonitorInputStreamなどが結構便利だと思う。
また、別スレッドでの実行を記述する場合に1.6以降ならSwingWorkerの使用を検討してみてもいいかも。
No.1
- 回答日時:
意味がいまいち分からないんだけど
DBから読み込むデータが多くて
VMへの負荷が高くて
ダイアログにメッセージを表示する余裕がない
ってこと?
だとしたら、読み込みを開始する前に
ダイアログを表示すれば良いんじゃない?
この回答への補足
回答ありがとうございます。
以下のソースを実行したとき、LABEL「実行中」の値を表示したいのですが、ダイアログが固まった状態になり、値が表示されないのです。
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class topMain {
public static void main(String[] args) {
//メニュー画面を起動する
topMain frame = new topMain();
frame.topFrame();
}
private void topFrame() {
JFrame jf = new JFrame();
//フレームのサイズ設定
jf.setSize(1000, 600);
jf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
jf.getContentPane().setLayout(null);
JButton b1 = new JButton("登録ボタン");
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//ダイアログボックスを開く
JDialog jd =new JDialog();
jd.setTitle("ddddddddd");
jd.getContentPane().add(new JLabel("実行中"),BorderLayout.CENTER);
//jd.getContentPane().setLayout(null);
jd.setBounds(10, 10, 50, 20);
jd.setSize(100,100);
jd.setVisible(true);
//ファイルを読み込む
long i=0;
while(true){
if(i==800000000){
break;
}
i++;
//ダイアログを閉じる
jd.dispose();
System.out.println("END");
}
});
jf.getContentPane().add(b1);
b1.setBounds(40, 400, 240, 100);
jf.setVisible(true);
}
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- C言語・C++・C# 大量のデータを読み込んで表示する速度を改善したい 8 2023/05/07 13:29
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- SQL Server DBのテーブルの設計ができず困っています。 2 2023/06/29 16:43
- JavaScript [Java] Edgeでのアドレスバー非表示について 3 2022/04/20 17:51
- その他(プログラミング・Web制作) pythonのグローバル変数 2 2022/11/25 18:02
- HTML・CSS ボタンをクリックした時に、入力フォームのすぐ下部に、「入力欄が空白です」というテキストメッセージが表 1 2022/04/27 16:25
- 電子マネー・電子決済 QUICPayの登録ができない。 4 2023/06/10 10:57
- JavaScript 入力フォームの javascript で メールアドレスの正規チェックをを行い、ボタンをクリックして 2 2022/04/27 16:06
- Access(アクセス) Access 登録ボタンからサブフォームの更新 1 2022/07/22 10:23
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
tryの終了
-
Java
-
JavaScriptからJAVAクラスを呼...
-
doGetとdoPostの違い
-
javascriptの繰り返し処理が終...
-
ユーザー名とテキストフィール...
-
ServletからJSPに遷移させた後...
-
java(swing)で、登録ボタンを押...
-
ブラウザを閉じた後のサーバ側...
-
Javaの再帰でメソッド呼び出す...
-
flush()メソッドについて・・・
-
数値の定数を付ける時
-
スレッド1とスレッド2を交互に...
-
「UIスレッド」「マルチスレッ...
-
データ未入力時のエラー処理が...
-
処理実行後、終了させないで最...
-
Javaでのデバッグコード削除
-
PHPでDB処理中にプログレスバー...
-
バッチ処理をJavaで
-
重たい処理のタイムアウト強制終了
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
tryの終了
-
doGetとdoPostの違い
-
Javaプログラムからポップアッ...
-
SwingUtilities.invokeLater(ne...
-
Javaでのデバッグコード削除
-
Tomcat高負荷時の設定について
-
JavaScriptからJAVAクラスを呼...
-
データ未入力時のエラー処理が...
-
アコーディオンメニューをアン...
-
ブラウザを閉じた後のサーバ側...
-
[Java] while(true)の意味
-
数値の定数を付ける時
-
Javaアプリケーション実行の返...
-
ラジオボタンの選択判定
-
onBlurとonFocusの処理順序につ...
-
スレッド1とスレッド2を交互に...
-
WPF C#でF10のイベント取得方法...
-
flush()メソッドについて・・・
-
ExcelVBA で文字列の特定の文字...
-
無限ループをわざと作って時計...
おすすめ情報