视觉工件出现在JPanel上 [英] Visual Artifacts appearing on JPanel

查看:137
本文介绍了视觉工件出现在JPanel上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用BorderLayout用2 JPanel创建一个程序.中间面板用于随机绘制矩形,而南部面板用于按钮.

I am trying to create a program with 2 JPanel using BorderLayout. The center panel is for random drawing of rectangle while the south panel is for the buttons.

每当我将鼠标光标悬停在北"或南"按钮上时,都会得到JFrame左上角按钮的怪异图像.我进行了一些研究,发现这可能是透明背景的原因.我尝试在面板上使用super.paintComponent(g),但是前面绘制的其余矩形消失了.我需要将矩形保留在JPanel中,而不是左上角的怪异图像.

I am getting a weird image of the button on the top left corner of the JFrame whenever I hover the mouse cursor over the North or South button. I did some research and found out that this could be the reason for having a transparent background. I tried using super.paintComponent(g) for the panel but the rest of the rectangles drawn earlier disappear. I need the rectangles to stay in the JPanel but not the weird image on the top left.

我不知道我在做什么错,希望有人可以提供帮助或提供一些有关如何解决此问题的线索.

I don't know what I am doing wrong, hopefully someone can help or give some clue on how to solve this problem.

    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();
        }
    }
}

推荐答案

您没有呼叫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以确保正确维护油漆链,并且发生不透明和清除图形上下文之类的事情.

You are obligated to call super.paintComponent to ensure that the paint chain is upheld correctly and things like opacity and cleaning up of the graphics context takes place.

Graphics对象通过一次重绘过程在组件之间共享,如果不遵守正确的绘制链,则会导致像您这样的问题

The Graphics object is shared between components through a single repaint pass, failure to honor the correct paint chain will result in, well, problems like yours

无论如何都不要从任何paint方法(包括调用repaint)更新UI,这只会导致您的paint方法被反复调用,直到CPU命中100 %,程序挂起.

Never update the UI in anyway from any paint method (this includes calling repaint), this is just causing your paint method to be recalled, over and over and over...until you CPU hits 100% and program hangs.

永远不要在paint方法(或通常是UI)中进行任何耗时的操作或阻止操作,这会使程序看起来像挂起,并使用户感到沮丧(您认为僵尸部落很糟糕:P ).以这种方式进行阻止可以防止EDT对绘画请求做出响应...

Never, EVER do any time consuming or block operations within the paint methods (or the UI generally), this will make it look like the program as hung and make the users upset (you think zombi hordes are bad :P). Blocking in this way prevents the EDT from responding to paint requests...

我建议您通读以下内容:

I'd recommend having a read through:

  • Performing Custom Painting
  • 2D Graphics
  • Painting in AWT and Swing
  • Concurrency in Swing

这篇关于视觉工件出现在JPanel上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆