Ich habe JSrollPane mit einem JPanel als ViewPort-Komponente. In diesem JPanel verwende ich paintComponent um ein Raster von 64x64px Quadraten zu zeichnen. Der JPanel ist ziemlich groß, 28'672px um 14'336px, immer noch wird das Raster sofort gezeichnet und alles scheint in Ordnung zu sein. Das Problem ist, dass das Scrollen vertikal oder horizontal dazu führt, dass die CPU-Auslastung ziemlich hoch steigt, je schneller ich blättern kann, je höher es geht. Die CPU-Auslastung beträgt beim Scrollen zwischen 35-50%. Wenn Sie JPanel in derselben Größe ohne das darauf gezeichnete Raster scrollen, wird nur sehr wenig CPU verwendet. Das Raster ist also sicherlich die Ursache des Problems. Dieses Raster ist der grundlegendste Teil dessen, was ich im Scrollfenster vorhabe. Wenn es jetzt schlecht läuft, befürchte ich, dass es unbrauchbar wird, wenn mehr "Inhalt" hinzugefügt wird.JPanel mit Gitter gemalt, verursacht hohe CPU-Auslastung beim Scrollen
Meine Frage (n) Warum benutzt das System so viel CPU, um über dieses Raster zu scrollen? Wird das Raster bei jeder Änderung der Position der Bildlaufleiste neu gezeichnet? Gibt es eine bessere oder effizientere Möglichkeit, ein scrollbares Raster zu zeichnen?
Ich hatte eine Idee, nur das Raster des sichtbaren Bereichs (durch Koordiaten) zu zeichnen und dann diesen sichtbaren Bereich neu zu zeichnen, wenn die Bildlaufleisten verschoben werden, aber dies würde repaint viel aufrufen. Wenn möglich, möchte ich das gesamte Raster beim Start zeichnen und dann nur auf Befehl neu zeichnen.
Hier ist ein barebones Arbeitsbeispiel meines JPanel Grid.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;
public class GridTest extends JFrame
{
static JScrollPane scrollPane;
static JPanel contentPane,gridPane;
public static void main(String[] args) {
GridTest frame = new GridTest();
frame.setVisible(true);
}
public GridTest(){
setTitle("Grid Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setBounds(300, 100, 531, 483);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
scrollPane = new JScrollPane();
scrollPane.setBounds(0, 0, 526, 452);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
contentPane.add(scrollPane);
gridPane = new JPanel() {
public void paintComponent(Graphics g){
super.paintComponent(g);
drawGrid(g);
g.dispose();
}};
Dimension gridPaneSize = new Dimension(28672,14336);
//Dimension gridPaneSize = new Dimension(4096,4096);
gridPane.setBackground(Color.BLACK);
gridPane.setPreferredSize(gridPaneSize);
scrollPane.setViewportView(gridPane);
}
public static void drawGrid(Graphics g)
{
int width = gridPane.getWidth();
int height = gridPane.getHeight();
g.setColor(Color.gray);
// draw horizontal long lines
for(int h = 0; h < height; h+=64){
g.drawLine(0, h, width, h);
}
// draw even grid vert lines
for(int w = 0; w < width; w+=64){
for(int h = 0; h < height; h+=128){
g.drawLine(w, h, w, h+64);
}
}
// draw odd grid vert lines
for(int w = 32; w < width; w+=64){
for(int h = 64; h < height; h+=128){
g.drawLine(w, h, w, h+64);
}
}
}
}
EDIT: Die aktualisierte/fixed Version dieses Codes ist unten, auf die Frage in meiner Antwort.
Sie sind tatsächlich die Verarbeitung und Malerei auf 28672 x 14336 Oberfläche. Sie können es auf nur einen sichtbaren Clip reduzieren. – tenorsax