简体   繁体   English

如何绘制另一个对象而不是repaint()JPanel

[英]How to paint another object instead of repaint() JPanel

I have a JFrame in which I print 3 objects using 3 threads: 我有一个JFrame,其中使用3个线程打印3个对象:
Thread-1) Prints Circles 线程-1)打印圆圈
Thread-2) Prints Squares 线程2)打印正方形
Thread-3) Prints Triangle 线程3)打印三角形
The problem is that I need to print new objects over and over again, and not just repaint them. 问题是我需要一遍又一遍地打印新对象,而不仅仅是重新粉刷它们。 But my run() function of each thread can't touch the Graphics g variable of the Overrideded method paintComponent(Graphics g) of the class. 但是我每个线程的run()函数都无法触及该类的Overrideded方法paintComponent(Graphics g)的Graphics g变量。 I can only use repaint() inside the run() function. 我只能在run()函数内使用repaint()。
This is what I have: ( repaint() method used ) https://prnt.sc/gnxz6iM 这就是我所拥有的:( 使用了repaint()方法https://prnt.sc/gnxz6iM
This is what I want( WITHOUT THOSE SQUARE BORDERS of the paintImmediatly() method ): https://prnt.sc/gny1qx 这就是我想要的( 没有paintImmediatly()方法的平方平方 ): https : //prnt.sc/gny1qx

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){}
        }
    }  

}

You don't have your rendering indicating that it's drawing routine is not opaque. 您没有渲染指示它的绘制例程不是不透明的。

When drawing over something, the setOpaque(...) method is a hint to the rendering thread if the background pixels can be directly set, or must be checked for transparency and blended with the existing pixel value. 绘制对象时,如果可以直接设置背景像素,或者必须检查其透明度并与现有像素值混合,则setOpaque(...)方法是对渲染线程的提示。

Note that you will also have to have a transparency set in the color. 请注意,您还必须在颜色中设置透明度。 Lack of such a thing means your blending support might be turned on, but you drew an opaque color. 缺少此类功能意味着您的混合支持可能已打开,但是您绘制了不透明的颜色。

Also, Swing is not multithreaded safe. 另外,Swing不是多线程安全的。 It uses a private threads to do rasterization and UI update. 它使用私有线程进行栅格化和UI更新。 Any "multi-threaded" solution needs to dispatch all the UI updates to this drawing thread. 任何“多线程”解决方案都需要将所有UI更新分派到此绘图线程。 Otherwise, you will not get the results you desire (as that rendering thread is integrated into core OS drawing routines, and written specifically to support AWT, Swing, and other technologies. 否则,您将无法获得所需的结果(因为该渲染线程已集成到核心OS绘图例程中,并且专门为支持AWT,Swing和其他技术而编写。

This means that even small things like presenting the GUI Frame need to be "dispatched". 这意味着即使是很小的事情,例如呈现GUI框架,也需要“分派”。 See SwingWorker if you have tasks that need to coordinate between the main Java thread and the drawing thread, and SwingUtilites.invokeAndWait(...) / SwingUtilites.invokeLater(...) if the coordination is not that fine grained. 如果您有需要在主Java线程和绘图线程之间进行协调的任务,请参见SwingWorker;如果协调不是那么精细,请参见SwingUtilites.invokeAndWait(...)/ SwingUtilites.invokeLater(...)。

Yes, you can attempt to do things (like you did) from the main thread. 是的,您可以尝试从主线程执行操作(就像您所做的一样)。 Sometimes it almost works, but generally it won't work properly, and won't continue to work properly over time. 有时它几乎可以工作,但是通常它不能正常工作,并且随着时间的推移将无法继续正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM