我有一个带有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