Hallo
In meinem Programm habe ich ein JFrame, auf dem ein JScrollPane liegt. In diesem ist wiederum ein Panel, in dem sehr viel gezeichnet wird. Genauer gesagt muss das JPanel einige (~300) Bilder halten, die dann dort reingemalt werden.
Natürlich sind es verschiedene Bilder, die gemalt werden, aber als Vereinfachung habe ich nun einfach 300x das gleiche Bild genommen (PNG, 477x400, 33,2Kb). Das sieht dann so aus:
Das Problem:
Wenn ich nach unten scrolle, "kommt das JScrollPane nicht mehr hinterher" und alles laggt.
Der Sourcecode (ein kleines SSCCE):
Wie kann ich das Problem lösen, dass das Scrollen so extrem langsam und laggy ist?
Am besten probiert ihr es selbst mal aus; im Anhang findet ihr eine ZIP-Datei, in der diese Klasse als Runnable JAR mit dem Test-Bild "X.png" und dem Sourcecode liegt. Scrollt einfach mal ein bisschen nach unten.
Bin dankbar für jede Hilfe!
(Anm:
Ich habe zum Test einmal die Variable "BufferedImage image" durch ein "VolatileImage image" ersetzt - das Zeichnen geht zwar viel schneller, allerdings sollen in der "richtigen Version" des Programms ~300 verschiedene Bilder im Speicher gehalten werden, weshalb VolatileImage dort wenig sinnvoll ist.)
In meinem Programm habe ich ein JFrame, auf dem ein JScrollPane liegt. In diesem ist wiederum ein Panel, in dem sehr viel gezeichnet wird. Genauer gesagt muss das JPanel einige (~300) Bilder halten, die dann dort reingemalt werden.
Natürlich sind es verschiedene Bilder, die gemalt werden, aber als Vereinfachung habe ich nun einfach 300x das gleiche Bild genommen (PNG, 477x400, 33,2Kb). Das sieht dann so aus:
Das Problem:
Wenn ich nach unten scrolle, "kommt das JScrollPane nicht mehr hinterher" und alles laggt.
Der Sourcecode (ein kleines SSCCE):
Java:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class DrawingTest extends JFrame
{
private JPanel panel = new JPanel()
{
private BufferedImage image = readImage("X.png");
@Override
public Dimension getPreferredSize()
{
return new Dimension(image.getWidth() * 3, image.getHeight() * 100);
}
@Override
public void paintComponent(Graphics graphics)
{
super.paintComponent(graphics);
long time = System.currentTimeMillis();
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 3; j++)
{
graphics.drawImage(image, image.getWidth() * j, image.getHeight() * i, null);
}
}
System.out.println(System.currentTimeMillis() - time + "ms");
}
};
public DrawingTest()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800, 800);
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.getVerticalScrollBar().setUnitIncrement(100);
add(scrollPane);
}
private BufferedImage readImage(String filename)
{
BufferedImage image = null;
try {
image = ImageIO.read(new File(filename));
image.flush();
}
catch (IOException e) {
throw new RuntimeException("Could not load");
}
return image;
}
public static void main(String[] args)
{
DrawingTest t = new DrawingTest();
t.setVisible(true);
}
}
Wie kann ich das Problem lösen, dass das Scrollen so extrem langsam und laggy ist?
Am besten probiert ihr es selbst mal aus; im Anhang findet ihr eine ZIP-Datei, in der diese Klasse als Runnable JAR mit dem Test-Bild "X.png" und dem Sourcecode liegt. Scrollt einfach mal ein bisschen nach unten.
Bin dankbar für jede Hilfe!
(Anm:
Ich habe zum Test einmal die Variable "BufferedImage image" durch ein "VolatileImage image" ersetzt - das Zeichnen geht zwar viel schneller, allerdings sollen in der "richtigen Version" des Programms ~300 verschiedene Bilder im Speicher gehalten werden, weshalb VolatileImage dort wenig sinnvoll ist.)