当前位置: 首页 > 面试题库 >

为什么从未调用paint()/ paintComponent()?

方德宇
2023-03-14
问题内容

在过去的两天里,我试图 理解
Java如何处理图形,但是在此方面却惨败。我的主要问题是确切了解如何/何时调用paint()(或较新的paintComponent())。

在下面的代码中,我将看到何时创建事物,除非我自己手动添加对它的调用或JFrame.paintAll()/
JFrame.paintComponents()的调用,否则永远不会调用paintComponent()。

我将paint()方法重命名为paintComponent(),希望能够解决我的问题,它永远不会被调用(即使在repaint()上),但是没有运气。

package jpanelpaint;

import java.awt.*;
import javax.imageio.*;
import javax.swing.*;
import java.io.*;
import java.util.ArrayList;

public class ImageLoadTest extends JComponent {
 ArrayList<Image> list;

 public ImageLoadTest() {
  list = new ArrayList<Image>();

  try { //create the images (a deck of 4 cards)
   for(String name : createImageFileNames(4)){
    System.err.println(name);
    list.add(ImageIO.read(new File(name)));
   }
  } catch (IOException e) {  }
 }

    protected void paintComponent(Graphics g) {
     int yOffset=0;
  System.err.println("ImageLoadTest.paintComponent()");
     for(Image img : list) {
      g.drawImage(img, 0, yOffset,  null);
      yOffset+=20;
     }
    }

 public static void main(String args[]) throws InterruptedException {
  JFrame frame = new JFrame("Empty JFrame");
  frame.setSize(new Dimension(1000, 500));
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  frame.setVisible(true);

  Thread.sleep(1000);
  frame.setTitle("Loading images");
  ImageLoadTest ilt = new ImageLoadTest();
  frame.add(ilt);
  //update the screen
  //DOESN'T WORK. only works if I call frame.paintAll(frame.getGraphics()) 
  ilt.repaint();
  frame.repaint();

  Thread.sleep(1000);
  frame.setTitle("Setting background");
  ilt.setBackground(Color.BLACK);
  //update the screen - DOESN'T WORK even if I call paintAll ..
  ilt.repaint();
  frame.repaint();

            //have to call one of these to get anything to display  
//  ilt.paintComponent(frame.getGraphics()); //works
  frame.paintComponents(frame.getGraphics()); //works
 }

 //PRIVATE HELPER FUNCTIONS

 private String[] createImageFileNames(int count){
  String[] fileNames = new String[count];
  for(int i=0; i < count; i++)
   fileNames[i] = "Cards" + File.separator + (i+1) + ".bmp";  
  return fileNames;
 }
}

问题答案:

这些是原始代码导致其无法正常工作的主要问题:

  1. 在add()操作之后没有调用validate()
  2. 没有设置组件的首选大小。
  3. 覆盖它时未调用super.paintComponent()(这使setBackground()调用不起作用)
  4. 我需要从JPanel继承,以便对其进行绘制。Component和JComponent都不足以使setBackground()调用正常工作,即使在修复第3点时也是如此。

完成上述操作后,只要我记得在开始时就调用了超级构造函数,那么调用方法paintComponent或paint实际上都没关系。

这个信息是由@ jitter,@ tackline和@camickr编写的,真是太赞了!

PS不知道如果回答您自己的问题被认为是不好的形式,但是由于我所需的信息是由多个答案组成的,因此我认为最好的方法是修改其他答案并写出这样的总结。



 类似资料:
  • 问题内容: 我正在我的应用程序上执行以下操作,但是我无法获取routeChangeSuccess事件。 如下所示的非常简单的html也会失败 但是,当我单击链接时,我看到视图正在更新,但是从未触发$ routeChangeSucces事件。 有什么我想念的吗? *我遇到的 *另一个问题 是,可以挂接一个事件以知道视图已准备好,这样我就可以开始一些其他处理,例如document.ready()。 p

  • 我有一个JPA@Entity类,它现在已经使用@Prepersisted很长一段时间了。今天,我想在需要实体ID的地方添加一些功能。这个ID是在持久化过程中由数据库中的HIBERNATE_SEQUENCE生成的。它通常设置在em.persist(实体)之后。

  • 我不知道为什么我的GETendpoint被调用,但我的POSTendpoint不工作。当我调用时,它成功地返回 但是当我打电话的时候 我一直得到这样的回应: 这是我的密码

  • 我有一个SQS队列,用作Lambda函数的事件源。由于DB连接限制,我将Lambda函数的最大并发设置为5。 在正常情况下,一切正常,但是当我们需要进行更改时,我们故意禁用SQS触发器。消息按预期开始在SQS队列中备份。 当触发器被重新启用时,5个Lambda函数被实例化,并开始处理队列中的消息,但是我也看到CloudWatch告诉我Lambda被限制了。 有人能解释一下为什么会这样吗?我希望可用

  • 问题内容: 我偶然发现了一个问题,可以总结如下: 当我手动创建线程(即通过实例化)时,将适当地调用它。但是,当我与一起使用时,处理程序将被忽略。我错过了什么? 我期望:消息“未捕获的异常…”的三倍 我得到:消息一次(由手动创建的线程触发)。 在Windows 7和Mac OS X 10.5上用Java 1.6复制。 问题答案: 因为异常不会被捕获。 您的ThreadFactory生成的线程没有直接

  • 问题内容: 我通过扩展和实现和创建了自己的Android帐户身份验证器。其中的某些方法由调用,而其他方法则没有。 这很好用: 当我打电话给我时,问题就发生了。AccountManager不会调用我在中定义的方法。它调用其他一些默认方法,该方法仅在启动之前检查是否存在。 这是行不通的。它没有调用我的方法: AuthenticatorService 我创建了服务并定义了。否则不应该工作。 编辑: 我在