ここから質問投稿すると、最大4000ポイント当たる!!!! >>

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);
}
}
*******************************************************************

このQ&Aに関連する最新のQ&A

DB 意味」に関するQ&A: DBエラーの意味

A 回答 (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の使用を検討してみてもいいかも。
    • good
    • 0

意味がいまいち分からないんだけど



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);

}
}

補足日時:2010/08/13 14:22
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aと関連する良く見られている質問

QJavaでのログイン画面についての質問です。

ログイン画面
ID、PASSWORDを入力

・データベースに登録してあった場合
 次の画面へ遷移
・データベースに登録がなかった場合
 ID、PASSWORDの入力を残したままログイン画面へ

という機能を作成したいんですが、書き方がよくわかりません。(特にDB参照の部分)

データの送受信はPOST、パラメータの送受信はbean で行い、
パラメータのチェックはJavascript、ログイン時の情報をsessionで保持し、遷移毎にチェックを行うとういう仕様になってます。

Aベストアンサー

リクエストパラメータの取得
 getParameterメソッド

DBへの接続、SQLの作成、実行、結果の取得
これは検索すればたくさんサンプルがあります。
とりあえず1例として↓をあげときます。
 http://www.hellohiro.com/jdbc.htm

QArrayListの使い方がわかりません。(超初心者です。)

情報管理用のクラス[Hito]を作成する。
プロパティ
 String name
double taijyu
double sincho
double nenrei

・メインクラスでHitoをArrayListに5つ格納し、それぞれの値を表示させるという課題に挑んでいます。

2週間前からjavaを勉強し始めたばかりで、ようやくオブジェクト指向や、クラスというものどんなものか多少イメージがわいてきた程度です。ArrayListについては配列と違い、格納するデータ数の数をはじめから決めなくてもいいというぐらいしかわかっていません。(これでさえ違うかも?)

 どのように組みはじめばいいか、そしてArrayListはどのように使えばいいのか教えていただけますか? よろしくお願いします。

Aベストアンサー

ほかの方の説明で理解を深めたら、以下のコーディングを打ち込んでコンパイルします。
C:\java\OKWeb>javac TestHito.java
成功したら、

C:\java\OKWeb>java TestHito
で実行してみてください。
C:\java\OKWeb>java TestHito
名前 あきら 体重 74.3 身長 184.3 年齢 35
名前 まみ 体重 44.5 身長 168.4 年齢 28

と表示されます。
先ず動く事で感動を得る事が大切だと思います。
import java.util.*;

class Hito {
private String name;
private double taijyu;
private double sincho;
private int nenrei;

public Hito(){
name="";
taijyu=0;
sincho=0;
nenrei=0;
}

public void setName(String name){
this.name = name;
}
public void setTaijyu(double taijyu){
this.taijyu = taijyu;
}
public void setSincho(double sincho){
this.sincho = sincho;
}
public void setNenrei(int nenrei){
this.nenrei = nenrei;
}
public String getName(){
return name;
}
public double getTaijyu(){
return taijyu;
}

public double getSincho(){
return sincho;
}
public int getNenrei(){
return nenrei;
}
}

public class TestHito{


public static void main(String []args){
Hito[] hito =new Hito[5];
for(int i = 0; i < 5; i++){
hito[i] = new Hito();
}
hito[0].setName("あきら");
hito[1].setName("まみ");
hito[0].setTaijyu(74.3);
hito[1].setTaijyu(44.5);
hito[0].setSincho(184.3);
hito[1].setSincho(168.4);
hito[0].setNenrei(35);
hito[1].setNenrei(28);
ArrayList result = new ArrayList();
result.add(hito[0]);
result.add(hito[1]);
for(int i = 0; i<result.size(); i++){
hito[i]=(Hito)result.get(i);
System.out.println("名前 "+hito[i].getName()+
" 体重 "+hito[i].getTaijyu()+
" 身長 "+hito[i].getSincho()+
" 年齢 "+hito[i].getNenrei());
}

}
}

ほかの方の説明で理解を深めたら、以下のコーディングを打ち込んでコンパイルします。
C:\java\OKWeb>javac TestHito.java
成功したら、

C:\java\OKWeb>java TestHito
で実行してみてください。
C:\java\OKWeb>java TestHito
名前 あきら 体重 74.3 身長 184.3 年齢 35
名前 まみ 体重 44.5 身長 168.4 年齢 28

と表示されます。
先ず動く事で感動を得る事が大切だと思います。
import java.util.*;

class Hito {
private String name;
private double taijyu;
private double sincho;
...続きを読む

QString型の日付(2005/11/25)の比較

Java初心者です。String型で2005/11/25 のように2つString型で日付を取得したときに、大小の比較をしたいのです。どういう方法が考えられますか?よろしくお願いします。

Aベストアンサー

書式がyyyy/mm/ddで決め打ちならば他の方が書かれているとおりString#compareTo()で充分でしょう。
yyyy/m/dなど書式が不定の場合には、java.text.DateFormatを利用してjava.util.Dateに変換して比較するか、/で文字列を分解し、年・月・日を抽出してそれぞれを比較するなどが考えられます。

Qデータベースに変数の値を挿入

 HTMLのフォームから、getParameterで取得した値(id,name,club)をデータベースに挿入したいのですが、
String sql="insert into test_table values(id,name,club)";
 と記述してもその文字列がそのままテーブルに反映されてしまいます。
 もちろん、
String sql="insert into test_table values('12','●田○郎','野球部')";
とあらかじめ記述しておけばこのデータがテーブルに挿入されるのですが・・・。
 PHPでは確かvalues('{$id}','{$name}','{$club}')のように記述すればできたので戸惑っています。
 JAVAでSQL文に変数を含める場合、どのように記述すればいいのでしょうか?

Aベストアンサー

String sql="insert into test_table values(" + id + "," + name + "," + club + ")";

でいけます。
""で括られている中は文字列なので、変数として扱いたければ文字列の外に出せば良いだけです。
id、name、clubが文字型であるなら、↓のようにシングルクォートで括りましょう。

String sql="insert into test_table values('" + id + "','" + name + "','" + club + "')";

QJWindow、JFrameでモーダル化の方法

先日は、お世話になりました。
再度質問をさせていただきたく思います。

JWindow、JFrameでJDialogと同等の処理をしようと自作しております。
大体はできたのですが、モーダル化ができません。

親画面でsetEnable(false)で操作できないようにし、
子画面でボタンが押されたら、dispase()するのと同時に、親画面を
setEnable(ture)にして操作可能にすることはできるのですが、
この処理では、親画面が子画面を呼び出した後も、
親画面の処理は進んでしまいますよね。

子画面でボタンが押下されるまで親画面の処理をとめるにはどのようにすればいいのでしょうか。

javaのバージョンは1.4です。
よろしくお願いいたします。

Aベストアンサー

//何の検証もない、"信頼できない"コードを書いてみました。
//どこまで正しいのかわからないので、
//仕事には使いたくない感じですが。

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;


class MyEQ extends EventQueue{
public void d(AWTEvent e){dispatchEvent(e);}
}


public class Demo implements ActionListener{
boolean blocking;static Frame f;
static MyEQ myEQ=new MyEQ();
{Toolkit.getDefaultToolkit().getSystemEventQueue().push(myEQ);}

public static void main(String[] args){
f=new Frame("Main Frame");
Button b=new Button("モーダルダイアログ表示");
b.addActionListener(new Demo());f.add(b);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.pack();f.setVisible(true);
}

public void actionPerformed(ActionEvent e){
System.out.println("start");
modalStart();
System.out.println("end");
}

private void eventPump(){
AWTEvent event=null;
while(blocking){
try{event=myEQ.getNextEvent();}catch(Exception e){}
myEQ.d(event);
}
}

private void modalStart(){
MyDialog d=new MyDialog("モーダルダイアログ",this);
f.setEnabled(false);d.setVisible(true);
blocking=true;eventPump();
}

void modalEnd(){
blocking=false;f.setEnabled(true);
}
}

class MyDialog extends Frame{
Demo demo;
MyDialog(String title,Demo demo){
super(title);
this.demo=demo;
Button b=new Button("(^^)");
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("(^^)");
}
});
add(b);pack();
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
MyDialog.this.demo.modalEnd();dispose();
}
});
}
}

//何の検証もない、"信頼できない"コードを書いてみました。
//どこまで正しいのかわからないので、
//仕事には使いたくない感じですが。

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;


class MyEQ extends EventQueue{
public void d(AWTEvent e){dispatchEvent(e);}
}


public class Demo implements ActionListener{
boolean blocking;static Frame f;
static MyEQ myEQ=new MyEQ();
{Toolkit.getDefaultToolkit().getSystemEventQueue().p...続きを読む

Q子→親ウインドウへデータを受け渡し、子ウィンドウを閉じる。

このような処理はできないでしょうか?

子ウィンドウはコード番号の検索用。該当のコードのリンクをクリックすると、そのコード番号を親ウィンドウのテキストボックスへ落とし込む。そのタイミングで、子ウィンドウは閉じる。
子→親ウインドウへのデータの受け渡しと、子ウィンドウのクローズを同時に行うようなイメージです。
よろしくお願いします。

Aベストアンサー

こんにちは

【親ウィンドウ】
<form action="xxx.php" method="POST" name="myForm">
顧客コード
<input type="text" name="kokyaku_cd" size="10">
<a href="javascript:void(0)" onClick="window.open('search.html','search','menubar=no,height=400,width=300');">検索</a>
</form>

【子ウィンドウ】
<script language="javascript"><!--
function ich(n) {
window.opener.document.myForm.kokyaku_cd.value=n;
window.close();
}
//--></script>

<table>
<tr>
<th>顧客コード</th>
<th>顧客名称</th>
</tr>
<tr>
<td><a href="javascript:ich('ABC商店')">0001</a></td>
<td>ABC商店</td>
</tr>
<tr>
<td><a href="javascript:ich('DEF商店')">0002</a></td>
<td>DEF商店</td>
</tr>
</table>

もしくはNo.1様の言うようにidを設定して
【親画面】
<input type="text" name="kokyaku_cd" size="10" id="kokyaku_cd">

【子画面 function内】
window.opener.document.getElementById("kokyaku_cd").value=n;

でできると思います

こんにちは

【親ウィンドウ】
<form action="xxx.php" method="POST" name="myForm">
顧客コード
<input type="text" name="kokyaku_cd" size="10">
<a href="javascript:void(0)" onClick="window.open('search.html','search','menubar=no,height=400,width=300');">検索</a>
</form>

【子ウィンドウ】
<script language="javascript"><!--
function ich(n) {
window.opener.document.myForm.kokyaku_cd.value=n;
window.close();
}
//--></script>

<table>
<tr>
<th>顧客コード</th>
<t...続きを読む

Qボタンを押してテキストエリアの内容をクリアする方法

自分のHPにテキスト翻訳機能をつけようと思い
Google language APIを利用したサイトに習い以下のように
作ってみました。(ソース提供してあった場所からいただきました)

この中にはリセットボタンがなかったので自分でつけてみたのですが、
テキストエリアの内容をうまくクリアする方法がわかりません。
リセットボタンを押したら左右両方のテキストエリアの内容をクリア
したいのです。

おそらく scriptのところにfunction reset()という内容を
つけなければならないのではと言うところまでは分かるのですが。
私のレベルには限界がありますので、どうぞよろしくご教授ください。

スクリプトを貼ります。
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8"></meta>
<style type="text/css">
textarea { height: 50px; width: 250px }
</style>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("language", "1");
// 画面初期化時に言語選択ボックスを作成する
function init() {
var langList = document.getElementById("target-language");
// (1) Language APIで使える言語をループしてリストに表示
for (var lang in google.language.Languages) {
var langOpt = new Option(lang, google.language.Languages[lang]);
langList.options[langList.options.length] = langOpt;
}
}
// body.onload時にinit()が呼ばれるようにする
google.setOnLoadCallback(init);

function translate() {
var source = document.getElementById("source").value;
// (2) 入力された文字列から、言語を自動的に判別する
google.language.detect(source, function(detectResult) {
if (detectResult.error) {
alert("Error:" + error.message); return;
}
// 選択されている言語を取得
var langList = document.getElementById("target-language");
targetLang = langList.options[langList.selectedIndex].value;
// 翻訳
google.language.translate(
source,
detectResult.language,
targetLang,
function(result) {
if (result.error) {
alert("Error:" + result.message);
return;
}
document.getElementById("result").value = result.translation;
});
});
}

</script>
</head>
<body>
<center>
<textarea id="source"></textarea>

<textarea id="result"></textarea><br>
Translate into <select id="target-language"></select>

<button onclick="translate()">Translate</button>
<button onclick="reset()">Reset</button>

</center>
</body>
</html>

自分のHPにテキスト翻訳機能をつけようと思い
Google language APIを利用したサイトに習い以下のように
作ってみました。(ソース提供してあった場所からいただきました)

この中にはリセットボタンがなかったので自分でつけてみたのですが、
テキストエリアの内容をうまくクリアする方法がわかりません。
リセットボタンを押したら左右両方のテキストエリアの内容をクリア
したいのです。

おそらく scriptのところにfunction reset()という内容を
つけなければならないのではと言うところまでは分...続きを読む

Aベストアンサー

function reset(){
document.getElementById("source").value ='';
document.getElementById("result").value ='';
}

Qcsvファイルを2次元配列に格納

Javaの勉強をしています。
csvファイルを読み込んで2次元配列に格納する方法を教えて下さい。
1次元の配列なら下記のようにして出来たのですが、2次元の配列に格納する方法が分かりません。

------------------------------
try {
File csv = new File("xxx.csv");
BufferedReader brf = new BufferedReader(new FileReader(csv));
while(brf.ready()) {
String line = brf.readLine();
String[] data = line.split(",");
for(int j=0; j<data.length; j++) {
System.out.print(data[j] + "\t");
}
System.out.println();
}
brf.close();
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
---------------------------
一度はできないのかと思い、上記の1次元配列のdata[j]を2次元配列のarray[i][j]に代入してみたのですが出来ませんでした。
回答宜しくお願い致します。

Javaの勉強をしています。
csvファイルを読み込んで2次元配列に格納する方法を教えて下さい。
1次元の配列なら下記のようにして出来たのですが、2次元の配列に格納する方法が分かりません。

------------------------------
try {
File csv = new File("xxx.csv");
BufferedReader brf = new BufferedReader(new FileReader(csv));
while(brf.ready()) {
String line = brf.readLine();
String[] data = line.split(",");
for(int j=0; j<data.length; j++) {
System.out.pr...続きを読む

Aベストアンサー

#1です。

> ファイル全体の行数はファイルを読み終わってからでないとわからないのですが、その場合どうすればよいのでしょう??

#2の方が書いておられるように、ArrayListなど適当なコレクションクラスにファイルを読み込み、行数が分かってから配列をnewすればいいでしょう。

import java.util.ArrayList;

ArrayList<String[]> al = new ArrayList<String[]>();
while (...) {
String line = brf.readLine();
al.add(line.split(",")); /* ArrayListへ読み込み */
}

String[][] array = new String[al.size()][];
for (i = 0; i < al.size(); i++) {
array[i] = al.get(i); /* ArrayListから配列へ */
}

勉強頑張ってください。

Qjavascriptからjavaを呼び出したい

javascriptの勉強中です。
javascriptでajaxを用いてjavaのメソッドにアクセスし、結果をjavascriptに返す、という実装をしたいのですが上手く行きません。

流れとしては以下のようなものを想定しています。

js
/project/WebContent/js/testJS.js(画面の値を引数としてtestJavaクラスのtestMethodメソッドを呼び出す)

java
/project/src/java/jp/co/application/util/testJava.java(受け取った引数の値をtestDAOクラスのtestDAOMethodメソッドに渡す)

java
/project/src/java/jp/co/application/dao/testDAO.java(受け取った値を用いてDBにアクセスし、結果をjsに返す)

まず技術的に、同じプロジェクト内のjavaメソッドをjs上で呼び出し、結果を受け取るということは可能なのでしょうか。
ご教示お願いします。

Aベストアンサー

#3 です。

> 「javaを使わない」という条件だと、XMLのリクエストのみで実現は可能でしょうか。
DB上にあるデータを全てXML化して置いておけば出来なくはありません。
ただ、その場合は静的データ(XML)で管理することになるので、DBを使用する意味がなくなると思うのですが…。

DBを利用するならサーバサイドスクリプトの存在は必須です。

1. DBの内容をサーバ意サイドスクリプトで出力
2. 出力データを JavaScript で受け取り、カレンダーに描画する

このような処理が必要になります。
出力データのフォーマットは JSON, XML 何でも良いですが、JavaScript で認識しやすいデータが望ましいですね。
DBデータがあらかじめキャッシュして置ける内容なら初めからJavaScriptに全データをObjectとして渡しておくのが理想だと思います。
月が変化する毎にリクエストを発行する必要がなくなりますので、コードを単純化できます。
その場合は、カレンダーを出力するHTMLをサーバサイドスクリプトで書いて、JSONを出力しておくのが楽な実装ですね。

# Re: mifu223さん

#3 です。

> 「javaを使わない」という条件だと、XMLのリクエストのみで実現は可能でしょうか。
DB上にあるデータを全てXML化して置いておけば出来なくはありません。
ただ、その場合は静的データ(XML)で管理することになるので、DBを使用する意味がなくなると思うのですが…。

DBを利用するならサーバサイドスクリプトの存在は必須です。

1. DBの内容をサーバ意サイドスクリプトで出力
2. 出力データを JavaScript で受け取り、カレンダーに描画する

このような処理が必要になります。
出力データのフォーマッ...続きを読む


人気Q&Aランキング