Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.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 如何绘制另一个对象而不是重新绘制()JPanel_Java_Multithreading_Swing - Fatal编程技术网

Java 如何绘制另一个对象而不是重新绘制()JPanel

Java 如何绘制另一个对象而不是重新绘制()JPanel,java,multithreading,swing,Java,Multithreading,Swing,我有一个JFrame,其中我使用3个线程打印3个对象: 线程1)打印圆 线程2)打印正方形 线程3)打印三角形 问题是我需要一次又一次地打印新对象,而不仅仅是重新绘制它们。但是每个线程的run()函数都不能触及类的重写方法paintComponent(Graphics g)的Graphics g变量。我只能在run()函数中使用repaint() 这就是我所拥有的:(使用了repaint()方法) 这就是我想要的(没有paintimmediate()方法的方形边框): 您的渲染没有指示其绘图例

我有一个JFrame,其中我使用3个线程打印3个对象:
线程1)打印圆
线程2)打印正方形
线程3)打印三角形
问题是我需要一次又一次地打印新对象,而不仅仅是重新绘制它们。但是每个线程的run()函数都不能触及类的重写方法paintComponent(Graphics g)的Graphics g变量。我只能在run()函数中使用repaint()
这就是我所拥有的:(使用了repaint()方法)
这就是我想要的(没有paintimmediate()方法的方形边框):


您的渲染没有指示其绘图例程不是不透明的

当在某物上绘制时,如果可以直接设置背景像素,或者必须检查透明度并与现有像素值混合,则
setOpaque(…)
方法将提示渲染线程

请注意,您还必须在颜色中设置透明度。缺少这样的东西意味着您的混合支持可能会打开,但您绘制了不透明的颜色

此外,Swing不是多线程安全的。它使用私有线程进行光栅化和UI更新。任何“多线程”解决方案都需要将所有UI更新发送到此绘图线程。否则,您将无法获得所需的结果(因为该渲染线程集成到核心操作系统绘图例程中,并且是专门为支持AWT、Swing和其他技术而编写的)

这意味着即使是显示GUI框架这样的小事情也需要“调度”。如果您有需要在主Java线程和绘图线程之间协调的任务,请参阅SwingWorker,如果协调没有那么细粒度,请参阅SwingUtilites.invokeAndWait(…)/SwingUtilites.invokeLater(…)


是的,您可以尝试从主线程执行操作(就像您所做的那样)。有时它几乎可以正常工作,但通常它不能正常工作,并且随着时间的推移也不能继续正常工作。

您的渲染没有指示它的绘图例程不是不透明的

当在某物上绘制时,如果可以直接设置背景像素,或者必须检查透明度并与现有像素值混合,则
setOpaque(…)
方法将提示渲染线程

请注意,您还必须在颜色中设置透明度。缺少透明度意味着您的混合支持可能会打开,但您绘制了不透明的颜色

此外,Swing不是多线程安全的。它使用专用线程进行光栅化和UI更新。任何“多线程”解决方案都需要将所有UI更新发送到此绘图线程。否则,您将无法获得所需的结果(因为该渲染线程集成到核心操作系统绘图例程中,并专门为支持AWT、Swing和其他技术而编写

这意味着即使是显示GUI框架这样的小事情也需要“调度”。如果您有需要在主Java线程和绘图线程之间协调的任务,请参阅SwingWorker,如果协调没有那么细粒度,请参阅SwingUtilites.invokeAndWait(…)/SwingUtilites.invokeLater(…)


是的,您可以尝试从主线程执行操作(就像您所做的那样)。有时它几乎可以正常工作,但通常无法正常工作,并且随着时间的推移无法继续正常工作。

如果删除
super.paintComponent(g),会发生什么情况
?@Berger它可能会破坏油漆链…因此不建议这样做…为了更好地帮助我尽快发布有效的,我可以在代码的快速查看中看到以下内容:1)使用
setBounds()
=使用
null布局
()。2)与其自己创建线程,为什么不使用3 s?如果您想反复绘制线程,您可以:A)将它们保存到列表中,迭代列表并绘制其中的每个项目。B) 将它们绘制到
缓冲区图像
,然后显示该图像。。。使用哪一种取决于您的需要……如果不重新粉刷(…)
-ing面板,就没有安全的画法。以这种方式Swing是不安全的。如果删除
super.paintComponent(g)?@Berger它可能会破坏油漆链。。。因此,不建议这样做……为了更好地帮助您尽快发布有效的日志,我可以在代码的快速查看中看到以下内容:1)使用
setBounds()
=使用
null布局
()。2) 与其自己创建线程,为什么不使用3 s?如果您想反复绘制线程,您可以:A)将它们保存到列表中,迭代列表并绘制其中的每个项目。B) 将它们绘制到
缓冲区图像
,然后显示该图像。。。使用哪一种取决于您的需要……如果不重新粉刷(…)
-ing面板,就没有安全的画法。以这种方式挥杆是不安全的。
package tarefa03;

import java.awt.Graphics;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.Random;
import javax.swing.OverlayLayout;


public class FigurePlacer extends JPanel implements Runnable{
    final int width = 700;
    final int height = 700;
    int x_pos = 0;
    int y_pos = 0;
    int x_width = 50;
    int y_height = 50;
    String figure;

    public FigurePlacer(String str){
        figure = str;
        randomCoord();
        setOpaque(false);
        setBounds(0, 0, width, height);
        Thread th = new Thread (this);
        th.start();
    }

    private void randomCoord(){
        Random random = new Random();
        x_pos = random.nextInt(width);
        y_pos = random.nextInt(height);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        switch (figure){       
            case "circle":
            g2.setColor(Color.BLUE);
            g2.fillOval(x_pos, y_pos, x_width, y_height);
            break;

            case "square":     
            g2.setColor(Color.GREEN);
            g2.fillRect(x_pos, y_pos, x_width, y_height);
            break;

            case "triangle":
            g2.setColor(Color.ORANGE);
            int xpoints[] = {x_pos, x_pos+25, x_pos+50};
            int ypoints[] = {y_pos, y_pos+50, y_pos};
            g2.fillPolygon(xpoints,ypoints,3);
        }
    }

    @Override
    public void run(){
        while (true){
            randomCoord();
            this.paintImmediately(x_pos, y_pos, x_width, y_height);
            try{
                Thread.sleep (200);
            }
            catch (InterruptedException ex){}
        }
    }  

}