0

この前の質問と他のソースを参照しましたが、CountDownLatchを正しく機能させることができません。

背景:mainFrameは、dataEntryFrameという新しいフレームを作成します。dataEntryFrameの[送信]ボタンをクリックすると、レコードがデータベースに追加され、dataEntryFrameが破棄されます。この時点で、mainFrameはすべてのレコードを表示するjListをクリアしてリロードする必要があります。

問題:dataEntryFrameがロードされると、Javaがフリーズし、dataEntryFrameコンポーネントがロードされません。この部分を通過できません...次に、DataEntryFrameで、CountDownLatchは、送信ボタンがクリックされた後にのみデクリメントし、データベーステーブルにレコードを正常に追加し、それ自体を破棄する必要があります。または、ユーザーが[キャンセル]をクリックしたとき...

コード:メインフレームから

clearList();
CountDownLatch dataEntryDone = new CountDownLatch(1);
DataEntryFrame f = new DataEntryFrame(dataEntryDone);
Thread newThread = new Thread(f);
newThread.start();
dataEntryDone.await();
reLoadList();

コード:DataEntryFrameから

public void run(){
initComponents();
loadOtherData();
this.setVisible(true);
}
void submit(){
addRecord();
this.dispose()
dataEntryDone.countDown();
}
4

1 に答える 1

2

dataEntryFrameに新しいスレッドを使用し、mainFrameをブロックすると、Swingスレッドモデルに反します。Swingでは、SwingのUIコンポーネントへのすべての呼び出しは、イベントディスパッチスレッドで行う必要があります。これが開発中に発生していることを確認するために、UIコンポーネントが別のスレッドから使​​用されていることを検出した場合に例外をスローする再描画マネージャーをインストールできます。FEST- GUIコンポーネントへのアクセスがEDTで行われることのテストを参照してください。EDTで何かが発生することを確認するには、SwingUtilities.invokeAndWait /invokeLaterを使用します。

メインフレームは、CountDownLatchの代わりに、データ入力フレームを待つ必要はありません(また、そうすべきではありません)。これにより、メインフレームが適切に処理できるように、データ入力フレームがメインフレームに対してイベントを発生させます。リストの更新などのアクション。

水をさらに濁らせるために、データベースにデータを保存し、リストのデータをフェッチすることは、理想的にはイベントディスパッチスレッドで実行されるべきではありません。代わりに、SwingWorkerを使用して、独自のスレッドでこれらの操作を実行してください。ただし、すべてのUIコンポーネントにEDTからアクセスする必要があるというルールとは異なり、このバックグラウンド処理のルールは難しくはありませんが、応答性の高いUIを維持することをお勧めします。 UIスレッド(EDT)で実行されると、UIがフリーズします。

見る

于 2010-05-30T23:29:47.257 に答える