我正在使用swing编写一个java应用程序,我需要在正方形上方绘制一个网格。为此,我使用drawLine(...)
类提供的Graphics
方法。
除了绘制每一条线需要花费大量时间(50条线超过20秒......)之外,一切正常。我甚至可以看到实时绘制的线条。奇怪的是,水平线的绘制速度比垂直线快(几乎是瞬间)。
我可能做错了什么。这是网格的代码。
public void drawGrid(Graphics g){
g.setColor(new Color(255, 255, 255, 20));
int width = getWidth();
int height = (int) (width * Utils.PLATE_RATIO);
int step = pixelSize*gridSpacing;
Color bright = new Color(255, 255, 255, 100);
Color transparent = new Color(255, 255, 255, 20);
for(int ix = insets.left + step;
ix < width; ix += step){
if(((ix - insets.left) / step) % 10 == 0){
g.setColor(bright);
}
else{
g.setColor(transparent);
}
g.drawLine(ix, insets.top, ix, height+insets.top);
}
for(int iy = insets.top+step;
iy < (insets.top + height); iy += step){
if(((iy - insets.top) / step) % 10 == 0){
g.setColor(bright);
}
else{
g.setColor(transparent);
}
g.drawLine(insets.left, iy, width + insets.left, iy);
}
}
答案 0 :(得分:4)
您发布的代码很好,没有任何问题。
下面是使用您的方法的组件的一个工作示例(稍微简化):
public static class MyGrid extends JComponent
{
private int step = 10;
public MyGrid ()
{
super ();
}
public Dimension getPreferredSize ()
{
return new Dimension ( 500, 500 );
}
protected void paintComponent ( Graphics g )
{
super.paintComponent ( g );
drawGrid ( g );
}
public void drawGrid ( Graphics g )
{
int width = getWidth ();
int height = getHeight ();
Color bright = new Color ( 255, 255, 255, 200 );
Color transparent = new Color ( 255, 255, 255, 100 );
for ( int ix = step; ix < width; ix += step )
{
if ( ( ix / step ) % 10 == 0 )
{
g.setColor ( bright );
}
else
{
g.setColor ( transparent );
}
g.drawLine ( ix, 0, ix, height );
}
for ( int iy = step; iy < height; iy += step )
{
if ( ( iy / step ) % 10 == 0 )
{
g.setColor ( bright );
}
else
{
g.setColor ( transparent );
}
g.drawLine ( 0, iy, width, iy );
}
}
}
我猜这段代码之外还有一些问题。
P.S。有点偏离但是...
我建议你计算绘画区域的可见部分(使用JComponent的getVisibleRect ()
方法或图形g.getClip ().getBounds ()
方法)并限制你的绘画只用那个区域。
如果组件的绘制非常大(例如,组件面积为10000x10000像素),那么小优化可以加速组件的绘制。
答案 1 :(得分:-1)
根据@sureshKumar的建议,以下是我使用Double-Buffering解决问题的方法。我只是在绘制一个屏幕外图像,并在绘图结束时简单地调用drawImage()
。这似乎可以解决问题。
编辑:只有当您想要从drawGrid()
方法之外调用您的绘画方法(在我的情况下为paintComponent(...)
)时,这似乎才有用。
以下是代码:
private Graphics bufferGraphics;
private Image offScreen;
private Dimension dim;
//other attributes not shown...
public CentralPanel(){
//Some initialization... (not shown)
//I added this listener so that the size of my rectangle
//and of my grid changes with the frame size
this.addComponentListener(new ComponentListener() {
@Override
public void componentResized(ComponentEvent e) {
dim = getVisibleRect().getSize();
offScreen = createImage(dim.width, dim.height);
bufferGraphics = offScreen.getGraphics();
repaint();
revalidate();
}
//other methods of ComponentListener not shown
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(offScreen, 0, 0, null);
}
public void drawGrid(){
int width = dim.width - insets.left - insets.right;
width -= (width % plateSize.getXSize());
int height = (int) (width*Utils.PLATE_RATIO);
height -= (height % plateSize.getYSize());
int step = pixelSize*gridSpacing;
Color bright = new Color(255, 255, 255, 100);
Color transparent = new Color(255, 255, 255, 20);
for(int ix = insets.left + step;
ix < (width+insets.left); ix += step){
if(((ix - insets.left) / step) % 10 == 0){
bufferGraphics.setColor(bright);
}
else{
bufferGraphics.setColor(transparent);
}
//I am now drawing on bufferGraphics instead
//of the component Graphics
bufferGraphics.drawLine(ix, insets.top, ix, height+insets.top);
}
step *= Utils.PLATE_RATIO;
for(int iy = insets.top+step;
iy < (insets.top + height); iy += step){
if(((iy - insets.top) / step) % 10 == 0){
bufferGraphics.setColor(bright);
}
else{
bufferGraphics.setColor(transparent);
}
bufferGraphics.drawLine(insets.left, iy, width + insets.left, iy);
}
}
P.S。:如果这应该作为我的问题的编辑添加,请告诉我,我会这样做。