Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Swing:抽绳非常慢_Java_Swing_Graphics_Fullscreen_Doublebuffered - Fatal编程技术网

Java Swing:抽绳非常慢

Java Swing:抽绳非常慢,java,swing,graphics,fullscreen,doublebuffered,Java,Swing,Graphics,Fullscreen,Doublebuffered,我正在使用swing编写一个java应用程序,其中需要在正方形上方绘制一个网格。为此,我使用了Graphics类提供的drawLine(…)方法 一切都很好,只是画每条线需要很多时间(50条线需要20秒以上…)。我甚至可以看到实时绘制的线条。一件奇怪的事情是水平线的绘制速度比垂直线快(几乎是瞬间) 我可能做错了什么。下面是网格的代码 public void drawGrid(Graphics g){ g.setColor(new Color(255, 255, 255, 20));

我正在使用swing编写一个java应用程序,其中需要在正方形上方绘制一个网格。为此,我使用了
Graphics
类提供的
drawLine(…)
方法

一切都很好,只是画每条线需要很多时间(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);
    }
}
public void drawGrid(图g){
g、 setColor(新颜色(255、255、255、20));
int width=getWidth();
内部高度=(内部)(宽度*最终板厚比);
int step=像素大小*网格间距;
颜色明亮=新颜色(255、255、255、100);
颜色透明=新颜色(255、255、255、20);
对于(int ix=插图左+步;
ix<宽度;ix+=步长){
如果(((ix-插图左)/步骤)%10==0){
g、 设置颜色(明亮);
}
否则{
g、 setColor(透明);
}
g、 抽绳(ix,插图顶部,ix,高度+插图顶部);
}
对于(int iy=插图顶部+台阶;
iy<(插图顶部+高度);iy+=台阶){
如果((iy-insets.top)/步骤)%10==0){
g、 设置颜色(明亮);
}
否则{
g、 setColor(透明);
}
g、 抽绳(插图左,iy,宽度+插图左,iy);
}
}

您发布的代码很好,没有问题。
下面是使用您的方法(稍微简化)的组件的工作示例:

公共静态类MyGrid扩展了JComponent
{
私有整数步长=10;
公共MyGrid()
{
超级();
}
公共维度getPreferredSize()
{
返回新维度(500500);
}
受保护组件(图形g)
{
超级组分(g);
牵引格栅(g);
}
公共空心绘图网格(图形g)
{
int-width=getWidth();
intheight=getHeight();
颜色明亮=新颜色(255、255、255、200);
颜色透明=新颜色(255、255、255、100);
用于(int ix=步长;ix<宽度;ix+=步长)
{
如果((ix/步)%10==0)
{
g、 设置颜色(明亮);
}
其他的
{
g、 setColor(透明);
}
g、 抽绳(ix,0,ix,高度);
}
对于(int iy=步长;iy<高度;iy+=步长)
{
如果((iy/步)%10==0)
{
g、 设置颜色(明亮);
}
其他的
{
g、 setColor(透明);
}
g、 抽绳(0,iy,宽度,iy);
}
}
}
我想这段代码之外还有一些问题

附言,有点离题,但

我建议您计算绘画区域的可见部分(使用JComponent的
getVisibleRect()
方法或Graphics
g.getClip().getBounds()
方法),并仅使用该区域限制绘画


如果组件非常大(例如,组件的面积为10000x1000像素),那么这种小优化可以加快组件的绘制速度。

下面是我如何使用双缓冲解决问题的,正如@sureshKumar建议的那样。我只是在屏幕外的图像上画图,画图结束后只需调用
drawImage()
。这似乎奏效了

编辑:这似乎只有在您希望从
paintComponent(…)
方法外部调用绘制方法(在我的例子中是
drawGrid()
)时才有用

代码如下:

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);
    }
}
私有图形缓冲图形;
屏幕外的私人图像;
私有维度;
//其他属性未显示。。。
公共CentralPanel(){
//某些初始化…(未显示)
//我添加了这个侦听器,这样矩形的大小
//我的网格的大小随帧大小而变化
this.addComponentListener(新的ComponentListener(){
@凌驾
公共无效组件已恢复(组件事件e){
dim=getVisibleRect().getSize();
屏幕外=创建图像(尺寸宽度、尺寸高度);
bufferGraphics=屏幕外的.getGraphics();
重新油漆();
重新验证();
}
//未显示ComponentListener的其他方法
});
}
@凌驾
受保护组件(图形g){
超级组件(g);
g、 drawImage(屏幕外,0,0,空);
}
公共网格(){
int width=dim.width-insets.left-insets.right;
宽度-=(宽度%plateSize.getXSize());
内部高度=(内部)(宽度*最终板厚比);
高度-=(高度%plateSize.getYSize());
int step=像素大小*网格间距;
颜色明亮=新颜色(255、255、255、100);
颜色透明=新颜色(255、255、255、20);
对于(int ix=插图左+步;
ix<(宽度+插图左);ix+=步长){
如果(((ix-插图左)/步骤)%10==0){
bufferGraphics.setColor(明亮);
}
否则{
bufferGraphics.setColor(透明);
}
//我现在正在绘制缓冲区图形
//组件图形的设计
缓冲图形.抽绳(ix,插图顶部,ix,高度+插图顶部);
}
步骤*=最终板率;
对于(int iy=插图顶部+台阶;
iy<(插图顶部+高度);iy+=台阶){
如果((iy-insets.top)/步骤)%10==0){
bufferGraphics.setColor(明亮);
}
否则{
bufferGraphics.setColor(透明);
}
缓冲图形绘制线(插图左,iy,宽度+插图左,iy);
}
}
附言:如果这是对我的问题的编辑,请告诉我一个答案
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);
    }
}