如何使两个线程绘制同一图形

时间:2019-05-10 12:16:24

标签: java multithreading swing

我正在尝试绘制随机形状。我想一直看到所有这些形状。我正在使用paintComponent方法。

@Override
protected void paintComponent(Graphics g) {
    //super.paintComponent(g);
    g.setColor(sv.color);
    switch (sv.shape){
        case 1:
            g.drawOval((int)(sv.x*sv.xPro), (int)(sv.y*sv.yPro), (int)(sv.radius*2*sv.sqrt), (int)(sv.radius*2*sv.sqrt));
            list.add(new GraphicObject(1,sv.x,sv.y,sv.radius,sv.color));
            break;
        case 2:
            g.drawRect((int)(sv.x*sv.xPro), (int)(sv.y*sv.yPro), (int)(sv.radius*2*sv.sqrt), (int)(sv.radius*2*sv.sqrt));
            list.add(new GraphicObject(2,sv.x,sv.y,sv.radius,sv.color));
            break;
        case 3:
            g.drawPolygon(new int [] {(int)(sv.x*sv.xPro),(int)(sv.x*sv.xPro)+(int)(sv.radius*2*sv.sqrt),(int)(sv.x*sv.xPro)+(int)(sv.radius*2*sv.sqrt)},new int [] {(int)(sv.y*sv.yPro)+(int)(sv.radius*sv.sqrt),(int)(sv.y*sv.yPro),(int)(sv.y*sv.yPro)+(int)(sv.radius*2*sv.sqrt)},3);
            list.add(new GraphicObject(3,sv.x,sv.y,sv.radius,sv.color));
            break;
        case 4:
            g.drawOval((int)(sv.x*sv.xPro), (int)(sv.y*sv.yPro), (int)(sv.LenA*sv.xPro), (int)(sv.LenB*sv.yPro));
            list.add(new GraphicObject(4,sv.x,sv.y,sv.LenA, sv.LenB,sv.color));
            break;
        case 5:
            g.drawRect((int)(sv.x*sv.xPro), (int)(sv.y*sv.yPro), (int)(sv.LenA*sv.xPro), (int)(sv.LenB*sv.yPro));
            list.add(new GraphicObject(5,sv.x,sv.y,sv.LenA, sv.LenB,sv.color));
            break;
    }
}

所有用于绘制形状的变量都在单独的类中声明,因此所有线程都可以访问这些变量。第一个线程是为所有变量设置随机值,并在循环中重新绘制。还将所有绘制的形状保存到arrayList。

Thread thread1 = new Thread(
        () -> {
            try{
                while(true) {
                    PREF_W = getWidth();
                    PREF_H = getHeight();
                    sv.x = (int)(Math.random() * (((PREF_W - 2*(sv.radiusMax)) - 0) + 1)) + 0;
                    sv.y = (int)(Math.random() * (((PREF_H - 2*(sv.radiusMax)) - 0) + 1)) + 0;
                    sv.red = (int)(Math.random() * ((255 - 0) + 1)) + 0;
                    sv.green = (int)(Math.random() * ((255 - 0) + 1)) + 0;
                    sv.blue = (int)(Math.random() * ((255 - 0) + 1)) + 0;
                    sv.color = new Color(sv.red,sv.green,sv.blue);
                    sv.radius = (int) (Math.random() * ((sv.radiusMax-sv.radiusMin) + 1)) + sv.radiusMin;
                    sv.shape = (int)(Math.random() * ((5 - 1) + 1)) + 1;
                    sv.LenA = (int) (Math.random() * ((sv.radius*2-sv.radius/2) + 1)) + sv.radius/2;
                    sv.LenB = (int) (Math.random() * ((sv.radius*2-sv.radius/2) + 1)) + sv.radius/2;
                    if(sv.shape < 4){
                        list.add(new GraphicObject(sv.shape,sv.x,sv.y,sv.radius,sv.color));
                    }else {
                        list.add(new GraphicObject(4,sv.x,sv.y,sv.LenA, sv.LenB,sv.color));
                    }
                    Thread.sleep(700);
                    panel.mainPanel.repaint();
                }
            }catch(Exception e){
                System.out.println(e);
            }

        }
);

我希望第二个线程侦听窗口大小调整和子图绘制,并绘制所有保存的已调整大小的形状。该线程正在读取每个列表元素,调整其大小并重新绘制。

    Thread thread2 = new Thread(
        () -> {
            this.addComponentListener(
                    new ComponentAdapter(){
                        @Override
                        public synchronized void componentResized(ComponentEvent e) {
                            for (GraphicObject item : list) {
                                sv.x = item.x;
                                sv.y = item.y;
                                sv.red = item.color.getRed();
                                sv.green = item.color.getGreen();
                                sv.blue = item.color.getBlue();
                                sv.radius = item.radius;
                                sv.shape = item.shape;
                                sv.LenA = item.LenA;
                                sv.LenB = item.LenB;
                                sv.xPro = (double)getWidth()/1024;
                                sv.yPro = (double)getHeight()/768;
                                sv.sq = Math.pow((double)sv.xPro,2.0)+Math.pow((double)sv.yPro,2.0);
                                sv.sqrt = Math.sqrt(sv.sq);
                                sv.color = item.color;
                                sv.shape = item.shape;
                                panel.mainPanel.repaint();

                            }

                        }
                    }
            );
        }
);

第一个线程正在按预期工作,它正在循环绘制随机形状。问题出在第二条线上-当我拖动窗口角以调整大小时,所有先前绘制的形状都消失了,并且未绘制来自arraylist的形状。当我停止调整窗口大小时,第一个线程开始在空白窗口上绘制下一个随机形状。 怎么了?如何使这两个线程绘制相同的图纸?

0 个答案:

没有答案