Hallo zusammen,
bei meinem Programm, dass die Millionen von Eintragen einliest (siehe weitere Threads in diesem Unterforum), gibt es noch ein kleines Problem.
Während dem Einleseprozess, der mehr als 17 Sekunden dauert, wird ein endlicher Ladebalken (also einer mit Prozentangaben) angezeigt. Wenn die Anzahl der Einträge in der Datei groß ist (also z.B 1.Million), dann klappt das ganze fast perfekt (fast heißt, dass der Ladebalken sich in den ersten 2 Sekunden [Schätzung!] nicht bewegt und dann auf 2% springt, d.h. auf ca. 16.000 eingelesene Einträge, und dann normal weiterläuft).
Damit wären wir auch schon beim Problem: Wenn ich jetzt eine Datei mit z.B. nur 50 Einträgen einlese, sind die Einträge eingelesen, obwohl der Ladebalken erst bei ein paar Prozent steht. Das Updaten des Ladebalkens wird aber mittels eines invokeLater gemacht -> wenn das Einladen fertig ist müsste doch der Ladebalken noch auf 100% gefüllt werden, oder?
Ich habe im Code drei Standardausgaben eingaubt. Seht euch das erst mal an:
Wenn ich das ganze jetzt mit einer Mio. Einträge laufen lasse, dann sieht die Ausgabe so aus [nur ein Auszug]:
-> d.h. hin und wieder wird das invokeLater ausgeführt (d.h. heißt doch, dass dann gerade der EventDispatchingThread Rechnerkapazität hat um die GUI (sprich den Ladebalken) zu aktualisieren, oder?). Wie man sieht hängt der aber hinter dran (invokeWert: 1479; der Zeilenwert aber schon bei 1925!). Ich habe in meinen Programm kein Sleep eingebaut, um somit Kapazität für das invokeLater zur Verfügung zustellen. Könnte es daran liegen? Das Problem ist halt auch: wenn ich eines einbauen täte, würde der eh schon recht lang dauernde Einleseprozess noch deutlich verlängert!
Kann es sein, dass wenn das Einlesen fertig ist, die invokeLater-Funktion nicht mehr ausgeführt wird, dass heißt der Ladebalken nicht mehr vollends gefüllt wird? Oder woran liegt es, dass der Balken bei wenigen Zeilen in der einzulesenden Datei nicht richtig gefüllt wird?
Dem würde aber die folgende Ausgabe bei einer Datei mit 35 Zeilen (es werden aber nur 34 Zeilen eingelesen, aber des ist ein anderes Problem -> anderer Thread) entgegensprechen:
So wie ich das interpretiere, wird doch erst alles eingelesen und dann müsste doch im Nachhinein (was eigentlich nicht so gewollt ist, aber besser als einen leeren Balken) der Balken noch bis auf 100% gefüllt werde, da ja für alle Zeilen die invokeFunktion aufgerufen wurde.
Hoffe auf Hilfe. Habe das mit den Threads noch nicht 100% durchsteigen.
Habe deshalb auch noch eine zweite Frage:
In der Funktion setValue ist ein invokeAndWait drinnen. Ist dies sinnvol? Bin mir da net sicher.
Grüße - spacegaier
bei meinem Programm, dass die Millionen von Eintragen einliest (siehe weitere Threads in diesem Unterforum), gibt es noch ein kleines Problem.
Während dem Einleseprozess, der mehr als 17 Sekunden dauert, wird ein endlicher Ladebalken (also einer mit Prozentangaben) angezeigt. Wenn die Anzahl der Einträge in der Datei groß ist (also z.B 1.Million), dann klappt das ganze fast perfekt (fast heißt, dass der Ladebalken sich in den ersten 2 Sekunden [Schätzung!] nicht bewegt und dann auf 2% springt, d.h. auf ca. 16.000 eingelesene Einträge, und dann normal weiterläuft).
Damit wären wir auch schon beim Problem: Wenn ich jetzt eine Datei mit z.B. nur 50 Einträgen einlese, sind die Einträge eingelesen, obwohl der Ladebalken erst bei ein paar Prozent steht. Das Updaten des Ladebalkens wird aber mittels eines invokeLater gemacht -> wenn das Einladen fertig ist müsste doch der Ladebalken noch auf 100% gefüllt werden, oder?
Ich habe im Code drei Standardausgaben eingaubt. Seht euch das erst mal an:
Code:
public void run(JProgressBar progress, File file, JLabel labelPrices)
{
final int bytesReadForLinecount = 20;
int current = 0;
status = progress;
BufferedReader br = null;
try
{
try
{
br = new BufferedReader(new FileReader(file));
try
{
br.mark(bytesReadForLinecount);
}
catch(IOException e)
{
e.printStackTrace();
}
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
char tmp[] = new char[bytesReadForLinecount];
try
{
br.read(tmp, 0, bytesReadForLinecount-1);
}
catch(IOException e1)
{
e1.printStackTrace();
}
String tmp_2 = new String(tmp);
if(tmp_2.contains("\r\n"))
{
System.out.println("Win");
lineCount = (int)file.length() / 7;
}
else
{
System.out.println("Other OS");
lineCount = (int)file.length() / 6;
}
setMinMax(0, lineCount);
vectorPrices = new Vector<Float>(lineCount);
try
{
br.reset();
} catch (IOException e1)
{
e1.printStackTrace();
}
while(current < lineCount && !isInterrupted())
{
System.out.println("Zeile: " + current); // ERSTE AUSGABE !!!
setValue(++current);
try
{
vectorPrices.add(Float.parseFloat(br.readLine()));
labelPrices.setText("Eingelesene Preise: " + current);
}
catch(NumberFormatException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
catch(OutOfMemoryError e)
{
e.printStackTrace();
}
finally
{
if(br == null)try{br.close();}catch(IOException e){e.printStackTrace();}
}
status = null;
}
private void setMinMax(final int min, final int max)
{
try{
SwingUtilities.invokeAndWait(new Runnable()
{
public void run()
{
status.setMinimum(min);
status.setValue(min);
status.setMaximum(max);
}
});
}
catch(Exception e)
{
}
}
private void setValue(final int value)
{
System.out.println("Wert in 'setValue()': " + value); // ZWEITE AUSGABE !!!
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
System.out.println("Wert in 'invokeLater()': " + value); // DRITTE AUSGABE !!!
status.setValue(value);
}
catch(NullPointerException ex)
{
}
}
});
}
Wenn ich das ganze jetzt mit einer Mio. Einträge laufen lasse, dann sieht die Ausgabe so aus [nur ein Auszug]:
- Wert in 'setValue()': 1900
Zeile: 1900
Wert in 'setValue()': 1901
Zeile: 1901
Wert in 'setValue()': 1902
Zeile: 1902
Wert in 'setValue()': 1903
Zeile: 1903
Wert in 'setValue()': 1904
Zeile: 1904
Wert in 'setValue()': 1905
Zeile: 1905
Wert in 'setValue()': 1906
Zeile: 1906
Wert in 'setValue()': 1907
Zeile: 1907
Wert in 'setValue()': 1908
Zeile: 1908
Wert in 'setValue()': 1909
Zeile: 1909
Wert in 'setValue()': 1910
Zeile: 1910
Wert in 'setValue()': 1911
Zeile: 1911
Wert in 'setValue()': 1912
Zeile: 1912
Wert in 'setValue()': 1913
Zeile: 1913
Wert in 'setValue()': 1914
Zeile: 1914
Wert in 'setValue()': 1915
Zeile: 1915
Wert in 'setValue()': 1916
Zeile: 1916
Wert in 'setValue()': 1917
Zeile: 1917
Wert in 'setValue()': 1918
Zeile: 1918
Wert in 'setValue()': 1919
Zeile: 1919
Wert in 'setValue()': 1920
Zeile: 1920
Wert in 'setValue()': 1921
Zeile: 1921
Wert in 'setValue()': 1922
Zeile: 1922
Wert in 'setValue()': 1923
Zeile: 1923
Wert in 'setValue()': 1924
Wert in 'invokeLater()': 1479
Wert in 'invokeLater()': 1480
Wert in 'invokeLater()': 1481
Wert in 'invokeLater()': 1482
Wert in 'invokeLater()': 1483
Wert in 'invokeLater()': 1484
Wert in 'invokeLater()': 1485
Zeile: 1924
Wert in 'setValue()': 1925
Zeile: 1925
Wert in 'setValue()': 1926
Zeile: 1926
Wert in 'setValue()': 1927
Zeile: 1927
Wert in 'setValue()': 1928
Zeile: 1928
Wert in 'setValue()': 1929
Zeile: 1929
Wert in 'setValue()': 1930
Zeile: 1930
Wert in 'setValue()': 1931
Zeile: 1931
Wert in 'setValue()': 1932
Zeile: 1932
Wert in 'setValue()': 1933
Zeile: 1933
Wert in 'setValue()': 1934
Zeile: 1934
Wert in 'setValue()': 1935
Zeile: 1935
Wert in 'setValue()': 1936
Zeile: 1936
Wert in 'setValue()': 1937
-> d.h. hin und wieder wird das invokeLater ausgeführt (d.h. heißt doch, dass dann gerade der EventDispatchingThread Rechnerkapazität hat um die GUI (sprich den Ladebalken) zu aktualisieren, oder?). Wie man sieht hängt der aber hinter dran (invokeWert: 1479; der Zeilenwert aber schon bei 1925!). Ich habe in meinen Programm kein Sleep eingebaut, um somit Kapazität für das invokeLater zur Verfügung zustellen. Könnte es daran liegen? Das Problem ist halt auch: wenn ich eines einbauen täte, würde der eh schon recht lang dauernde Einleseprozess noch deutlich verlängert!
Kann es sein, dass wenn das Einlesen fertig ist, die invokeLater-Funktion nicht mehr ausgeführt wird, dass heißt der Ladebalken nicht mehr vollends gefüllt wird? Oder woran liegt es, dass der Balken bei wenigen Zeilen in der einzulesenden Datei nicht richtig gefüllt wird?
Dem würde aber die folgende Ausgabe bei einer Datei mit 35 Zeilen (es werden aber nur 34 Zeilen eingelesen, aber des ist ein anderes Problem -> anderer Thread) entgegensprechen:
- Zeile: 0
Wert in 'setValue()': 1
Wert in 'invokeLater()': 1
Zeile: 1
Wert in 'setValue()': 2
Zeile: 2
Wert in 'setValue()': 3
Zeile: 3
Wert in 'setValue()': 4
Zeile: 4
Wert in 'setValue()': 5
Zeile: 5
Wert in 'setValue()': 6
Zeile: 6
Wert in 'setValue()': 7
Zeile: 7
Wert in 'setValue()': 8
Zeile: 8
Wert in 'setValue()': 9
Zeile: 9
Wert in 'setValue()': 10
Zeile: 10
Wert in 'setValue()': 11
Zeile: 11
Wert in 'setValue()': 12
Zeile: 12
Wert in 'setValue()': 13
Zeile: 13
Wert in 'setValue()': 14
Zeile: 14
Wert in 'setValue()': 15
Zeile: 15
Wert in 'setValue()': 16
Zeile: 16
Wert in 'setValue()': 17
Zeile: 17
Wert in 'setValue()': 18
Zeile: 18
Wert in 'setValue()': 19
Zeile: 19
Wert in 'setValue()': 20
Zeile: 20
Wert in 'setValue()': 21
Zeile: 21
Wert in 'setValue()': 22
Zeile: 22
Wert in 'setValue()': 23
Zeile: 23
Wert in 'setValue()': 24
Zeile: 24
Wert in 'setValue()': 25
Zeile: 25
Wert in 'setValue()': 26
Zeile: 26
Wert in 'setValue()': 27
Zeile: 27
Wert in 'setValue()': 28
Zeile: 28
Wert in 'setValue()': 29
Zeile: 29
Wert in 'setValue()': 30
Zeile: 30
Wert in 'setValue()': 31
Zeile: 31
Wert in 'setValue()': 32
Zeile: 32
Wert in 'setValue()': 33
Zeile: 33
Wert in 'setValue()': 34
Wert in 'invokeLater()': 2
Wert in 'invokeLater()': 3
Wert in 'invokeLater()': 4
Wert in 'invokeLater()': 5
Wert in 'invokeLater()': 6
Wert in 'invokeLater()': 7
Wert in 'invokeLater()': 8
Wert in 'invokeLater()': 9
Wert in 'invokeLater()': 10
Wert in 'invokeLater()': 11
Wert in 'invokeLater()': 12
Wert in 'invokeLater()': 13
Wert in 'invokeLater()': 14
Wert in 'invokeLater()': 15
Wert in 'invokeLater()': 16
Wert in 'invokeLater()': 17
Wert in 'invokeLater()': 18
Wert in 'invokeLater()': 19
Wert in 'invokeLater()': 20
Wert in 'invokeLater()': 21
Wert in 'invokeLater()': 22
Wert in 'invokeLater()': 23
Wert in 'invokeLater()': 24
Wert in 'invokeLater()': 25
Wert in 'invokeLater()': 26
Wert in 'invokeLater()': 27
Wert in 'invokeLater()': 28
Wert in 'invokeLater()': 29
Wert in 'invokeLater()': 30
Wert in 'invokeLater()': 31
Wert in 'invokeLater()': 32
Wert in 'invokeLater()': 33
Wert in 'invokeLater()': 34
So wie ich das interpretiere, wird doch erst alles eingelesen und dann müsste doch im Nachhinein (was eigentlich nicht so gewollt ist, aber besser als einen leeren Balken) der Balken noch bis auf 100% gefüllt werde, da ja für alle Zeilen die invokeFunktion aufgerufen wurde.
Hoffe auf Hilfe. Habe das mit den Threads noch nicht 100% durchsteigen.
Habe deshalb auch noch eine zweite Frage:
In der Funktion setValue ist ein invokeAndWait drinnen. Ist dies sinnvol? Bin mir da net sicher.
Grüße - spacegaier