Witam.
Mam dość dziwny problem dotyczący wątków. Napisałem program, którego jednym z elementów jest wczytanie zawartości pliku i wrzucenie go do JTextArea. Z uwagi na to, że wczytywanie binarne dla dużych plików czasem trwało dość długo zainteresowałem się tematem wątków - samo wczytywanie dałem do jednego wątku a w drugim podałem stworzenie okna z JProgressBarem, żeby pokazać, że program nie zawiesił się. Drugi wątek czekał na zakończenie pierwszego a następnie, jeśli pierwszy był już nieaktywny zamykał okno z paskiem postępu. Kod jest spory bo program robi jeszcze parę innych rzeczy ale podałem najważniejsze fragmenty:
package project;
/**
* Project application
*
* @author Fazid
* @version 1.10 Alfa 08/04/25
*/
import java.awt.*;
import java.awt.Image.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
public class Main {
public static void main (String[] args)
{
Window okno = new Window();
}
}
class Window extends JFrame
{
public static String tekst;
static JButton cancel;
static JDialog bar;
static CImport w1;
static CWait w2;
static JTextArea textArea;
static JFileChooser fc;
Window() {
fc = new JFileChooser();
/*---Budowanie okna głównego---*/
tekst="";
}
class ButtonsL extends MouseAdapter
{
public void mousePressed (MouseEvent e)
{
JButton src = (JButton) e.getSource();
/*Obsługa wszystkich przycisków w programie*/
if (src==cancel)
{
w1.interrupt();
bar.dispose();
}
}
}
class CMenu implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
/*---MENU_EVENT_SYSTEM---*/
JMenuItem src = (JMenuItem) e.getSource();
if (src==open)
{
int returnVal = fc.showOpenDialog(Window.this);
if (returnVal==fc.APPROVE_OPTION)
{
w1 = new CImport();
w2 = new CWait(w1);
w1.start();
w2.start();
}
}
/*---END_OF_MENU_EVENT_SYSTEM---*/
}
}
class CImport extends Thread
{
public void run()
{
File plik=fc.getSelectedFile();
tekst="";
try
{
FileInputStream fstr = new FileInputStream(plik);
InputStreamReader str = new InputStreamReader(fstr,"UTF-8");
BufferedReader bf = new BufferedReader(str);
int znak = bf.read();
while( znak != -1 )
{
tekst += (char) znak;
znak = bf.read();
}
textArea.setText(tekst);
}
catch (FileNotFoundException ex)
{
textArea.setText("Brak pliku");
}
catch (IOException ex)
{
textArea.setText("Blad odczytu");
}
}
}
class CWait extends Thread
{
Thread w;
CWait(Thread j)
{
w=j;
}
public void run()
{
bar= new JDialog();
bar.setTitle("Czekaj...");
bar.setLayout(null);
bar.setSize(300,110);
bar.setLocationRelativeTo(null);
bar.setModal(true);
bar.addWindowListener(new Koniec());
JProgressBar progress = new JProgressBar(0,100);
progress.setBounds(30,20,240,20);
progress.setIndeterminate(true);
cancel = new JButton("Anuluj");
cancel.setBounds(170,45,100,20);
cancel.addMouseListener(new ButtonsL());
bar.add(cancel);
bar.add(progress);
bar.setVisible(true);
while (w.isAlive())
{
}
bar.dispose();
}
class Koniec extends WindowAdapter
{
public void windowClosing (WindowEvent e)
{
e.getWindow().dispose();
w1.interrupt();
w2.interrupt();
}
}
}
}
W działaniu wygląda to tak, że pojawia się okno wyboru pliku, po wybraniu pliku pojawia się okno z paskiem postępu jednak to okno nigdy nie znika. Ale dane są wczytane bo za jakiś czas pojawia się zaimportowany tekst. więc mimo zakończenia pracy przez wątek pierwszy ten drugi nie kończy pracy. Jeżeli zamknę okno z paskiem postępu używając krzyżyka dostaję informację w konsoli:
Disposal was interrupted:
java.lang.InterruptedException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at java.awt.EventQueue.invokeAndWait(EventQueue.java:992)
at java.awt.Window.doDispose(Window.java:994)
at java.awt.Dialog.doDispose(Dialog.java:1243)
at java.awt.Window.dispose(Window.java:937)
at project.Window$CWait.run(Main.java:324)
Wskazuje na linijkę bar.dispose();
Nie mam pojęcia dlaczego całość nie działa - będę wdzięczny za pomoc ;)