出现在JPanel的视觉假象(Visual Artifacts appearing on JPane

2019-07-03 15:54发布

我想创建2周程序JPanel使用BorderLayout 。 中心面板为矩形的随机抽取,而南面板是按钮。

我正在上的左上角的按钮的怪异图像JFrame每当我将鼠标光标移到北方或南方按钮。 我做了一些研究和发现,这可能是具有透明背景的原因。 我试着用super.paintComponent(g)的面板,但早期消失绘制矩形的其余部分。 我需要留在矩形JPanel而不是在左上角的怪异图像。

我不知道我做错了,希望有人能帮助或就如何解决这个问题的一些线索。

    public class TwoBRandomRec extends JFrame{

    private static final long serialVersionUID = 1L;

    public static void main(String[] args) {
        TwoBRandomRec rec = new TwoBRandomRec();

        rec.setSize(500,500);
        rec.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        rec.setVisible(true);
    }

    public TwoBRandomRec() {
        //Create the buttons
        JButton north = new JButton("North");
        JButton south = new JButton("South");
        DrawPanel drawPanel = new DrawPanel(500,500);

        JPanel southP = new JPanel();
        southP.add(south);
        southP.add(north);

        this.add(drawPanel, BorderLayout.CENTER);
        this.add(southP, BorderLayout.SOUTH);

        this.setTitle("TwoButtonRandomRec");
        this.pack();        
    }

    public class DrawPanel extends JPanel {

        private static final long serialVersionUID = 1L;

        private Random rand = new Random();
        private int x,y,xSize,ySize;
        private int height,width;

        public DrawPanel(int w,int h) {
            width = w;
            height = h;
        }
        public void RandomX(){
             x=rand.nextInt(width-1);
             xSize=rand.nextInt(width-x);
         }

         public void RandomY(){
             y=rand.nextInt(height-1);
             ySize=rand.nextInt(height-y);
         }

         public Color RandomColour(){
             rand.nextInt(height);
             return new Color(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255));
         }

        @Override
        protected void paintComponent(Graphics g) {
            RandomX();
            RandomY();

            g.setColor(RandomColour());
            g.fillRect(x, y, xSize, ySize);
            try {
                Thread.sleep(50);

            } catch (InterruptedException e) {  
            }

            repaint();
        }
    }
}

Answer 1:

你不是叫super.paintComponent

protected void paintComponent(Graphics g) {
    super.paintComponent(g); // <-- Insert me here and watch problem go away
    RandomX();
    RandomY();

    g.setColor(RandomColour());
    g.fillRect(x, y, xSize, ySize);
    try {
        Thread.sleep(50); // <-- This is an INCREDIBLY bad idea, NEVER, EVER do this

    } catch (InterruptedException e) {  
    }

    repaint(); // <-- This is a bad idea, watch CPU max out...
}

你有责任呼吁super.paintComponent ,以确保油漆链是否正确之类的东西不透明度和清理图形上下文发生的坚持。

Graphics对象通过单个重绘通分量之间共享,不履行正确的涂料链将导致,以及,像您的问题

从来没有从任何反正更新的UI paint方法(包括调用repaint ),这只是导致您的paint被召回的方法,一遍又一遍又一遍......直到你的CPU达到100%和程序挂起。

永远不要做任何耗时或内块操作paint方法(或UI通常情况下),这将使它看起来像计划为挂起,并打乱了用户(您想zombi成群不好:P)。 以这种方式阻止阻止从美国东部时间响应绘制请求......

我建议有一个读通过:

  • 执行自定义绘制
  • 2D图形
  • 绘画在AWT和Swing
  • 并发在Swing


文章来源: Visual Artifacts appearing on JPanel