我有一個帶有JPanel作爲ViewPort組件的JSrollPane。在這個JPanel上,我使用paintComponent繪製一個64x64px的正方形網格。 JPanel非常大,28'672px×14'336px,網格仍然是即時繪製的,一切看起來都很好。問題在於,垂直或水平滾動會導致CPU使用率跳得相當高,滾動得越快,滾動越快。滾動時,CPU使用率可達35-50%之間。滾動相同大小的JPanel而沒有繪製網格,使用的CPU很少,所以網格肯定是問題的原因。這個網格是我打算在scrollpane內部做的最基本的部分,如果它現在表現不好,我擔心在添加更多「內容」之後它將不可用。帶有網格的JPanel畫在上面,滾動時會導致高CPU使用率
我的問題爲什麼它使用這麼多的CPU來滾動這個網格,每次滾動條的位置發生變化時,網格是否會重新繪製?有沒有更好或更有效的方法來繪製可滾動的網格?
我有一個想法,只繪製可見區域的網格(通過座標),然後重新繪製滾動條被移動時的可見區域,但這將調用重新繪製很多。如果可能,我想在啓動時繪製整個網格,然後僅根據命令重新繪製。
這是我的JPanel網格的準系統工作示例。
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);
}
}
}
}
編輯:此代碼的更新/固定版本如下,在我的問題的答案。
你實際上是在加工和畫上28672 X 14336面。您可以將其縮小爲僅限可見剪輯。 – tenorsax 2013-03-02 18:30:39