java Gui friert scheinbar zufällig ein

Diskutiere java Gui friert scheinbar zufällig ein im AWT, Swing, JavaFX & SWT Bereich.
N

Nesselbrand

Ich habe ein Client Server system programmiert, wo man sich bestimmte dateien vom Server herunterladen kann. Während des download Vorgangs friert aber das Gui ein und die Prozentanzeige sieht man somit auch nicht.

Der Client:
Code:
import javax.swing.tree.DefaultMutableTreeNode;
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;

public class Client {

    public static Gui gui;
    public static String sendpath;
    public static double filesize;

    public Client(Gui gui) {
        Client.gui = gui;
    }

    public static void requestPath() {
        try {
            Socket client = new Socket(Main.hostaddres, Main.port);
            DataOutputStream out = new DataOutputStream(client.getOutputStream());
            DataInputStream in = new DataInputStream(client.getInputStream());
            out.write(0);

            ObjectInputStream oin = new ObjectInputStream(in);
            Gui.root = (DefaultMutableTreeNode) oin.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void initDownload(String path) {
        try {
            StringWriter sw = new StringWriter();
            Socket client = new Socket(Main.hostaddres, Main.port);
            DataOutputStream out = new DataOutputStream(client.getOutputStream());
            DataInputStream in = new DataInputStream(client.getInputStream());
            ArrayList<String> pathbuilder = new ArrayList<>();

            for (int i = 0; i < path.length(); i++) {
                pathbuilder.add(path.substring(i, i + 1));
            }

            for (String s : pathbuilder) {
                if (s.equals("\\")) {
                    sw.append("\\");
                }
                sw.append(s);
            }
            sendpath = sw.toString();


            out.write(1);
            out.writeUTF(sendpath);

            filesize = Double.parseDouble(in.readUTF());

            download();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void download() {
        try {

            Socket client = new Socket(Main.hostaddres, Main.port);
            DataOutputStream out = new DataOutputStream(client.getOutputStream());
            DataInputStream in = new DataInputStream(client.getInputStream());
            FileOutputStream fout = new FileOutputStream(Client.gui.outputpath.getText());

            out.write(2);
            out.writeUTF(sendpath);

            int n;
            double count = 0;
            byte[] buffer = new byte[1000000000];
            while ((n = in.read(buffer)) > 0) {
                fout.write(buffer, 0, n);
                count += n;
                System.out.println(n);
                gui.setProgressBar1((((count / 1024) / 1024)/filesize) * 100);
                
                if ((((count / 1024) / 1024)/filesize) * 100 == 100){
                    break;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Ohne diesen Abschnitt:

Code:
                if ((((count / 1024) / 1024)/filesize) * 100 == 100){
                    break;
                }
würde das Programm nach dem fertigen download auch weiter freezen.

Die Gui:
Code:
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.io.File;

public class Gui {
    private JTree tree;
    private JPanel panel1;
    private JButton downloadSelectedFileButton;
    public JTextField outputpath;
    private JProgressBar progressBar1;
    public JTextField outputBytesDownloades;
    public static DefaultMutableTreeNode root;
    public Client client = new Client(this);

    public Gui() {
        downloadSelectedFileButton.addActionListener(e -> {
            if (!new File(String.valueOf(tree.getLastSelectedPathComponent())).isDirectory()){
                if (outputpath.getText().length() == 0){
                    JOptionPane.showMessageDialog(null,"Bitte geben sie einen Pfad an!");
                    return;
                }
                Client.initDownload(String.valueOf(tree.getLastSelectedPathComponent()));
            } else JOptionPane.showMessageDialog(null, "Bitte wählen sie eine Datei und kein Verzeichniss aus!");
        });
    }

    public static void initGui() {
        JFrame frame = new JFrame("Gui");
        frame.setContentPane(new Gui().panel1);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        frame.setSize(500,500);
        frame.setLocationRelativeTo(null);
    }

    private void createUIComponents() {
        tree = new JTree(root);
        tree.setToggleClickCount(1);
    }



    public void setProgressBar1(double progress){
        progressBar1.setValue((int) progress);
        panel1.validate();
        System.out.println((int) progress + "%");
    }
}
Ich habe für die Gui den Gui Builder von IntelliJ Idea verwendet in der vreateUIComponents Methode kreiere ich mir den Jtree selber, da dass mit dem Gui Builder nicht funktioniert. Wie kann ich des fixen?
Schonmal Danke im Vorraus
 
N

Nesselbrand

Hat sich erledigt. Ich habe die Download Methode einfach in nen anderen Thread verlegt.
 
L

LimDul

Event Dispatching Thread.

Das ist der Swing-Hauptthread, der für die Abarbeitung der Events zuständig ist, wie auch für das zeichnen etc.
Wenn du also irgendwo z.B. in einem ActionListener bist, läuft das in der Regel in genau dem Thread. Wenn du dann da lange Aufgaben machst blockierst du denn mit dem Effekt, den du gesehen hast - die Gui ist eingefroren, da auch nichts mehr gezeichnet werden kann.

Lagerst du deine Berechnungen nun aus in einen anderen Thread, hat man das typische Synchronisierungsproblem. Was passiert, wenn du von einem Label in dem Thread den Text ändert, während es gezeichnet wird? Da können die seltsamsten Dinge passieren. In 95% der Fälle geht das gut, aber die restlichen 5% findet man nie. Daher darfst du, wenn du einen eigenen Thread startest keine Gui Elemente direkt ändern. Wenn du welche ändern willst geht das über SwingUtilities.invokeLater bw. SwingUtilities.invokeAndWait. Die sorgen dafür, dass die Änderungen wieder im richtigen Thread passieren.
 
Thema: 

java Gui friert scheinbar zufällig ein

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben