本文介绍了为什么油漆()/的paintComponent()从来没有所谓的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的两天,我曾尝试了解的Java如何处理图形,但在这一点悲惨地失败了。我的主要问题是理解究竟如何以及何时paint()方法(或较新的paintComponent())是/被调用。

在以下code我,看创建东西的时候,该的paintComponent()不会被调用,除非我手动添加调用它自己或调用JFrame.paintAll()/ JFrame.paintComponents()

我希望这将修复它我的问题从来没有被调用(甚至在重绘())改名为paint()方法来的paintComponent(),但没有运气。

 包jpanelpaint;进口java.awt中的*。
进口javax.imageio中的*。
进口的javax.swing *。
进口java.io. *;
进口的java.util.ArrayList;公共类ImageLoadTest扩展JComponent的{
 ArrayList的<图像>清单; 公共ImageLoadTest(){
  名单=新的ArrayList<图像>();  尝试{//创建图像(4一副扑克牌)
   对于(字符串名称:createImageFileNames(4)){
    通信System.err.println(名);
    list.add(ImageIO.read(新文件(名称)));
   }
  }赶上(IOException异常五){}
 }    保护无效paintComponent(图形G){
     INT yOffset = 0;
  通信System.err.println(ImageLoadTest.paintComponent());
     对于(图片IMG:名单){
      g.drawImage(IMG,0,yOffset,NULL);
      yOffset + = 20;
     }
    } 公共静态无效的主要(字符串ARGS [])抛出InterruptedException的{
  JFrame的帧=新的JFrame(空的JFrame);
  frame.setSize(新尺寸(1000,500));
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  frame.setVisible(真);  视频下载(1000);
  frame.setTitle(加载图像);
  ImageLoadTest ILT =新ImageLoadTest();
  frame.add(ILT);
  //更新屏幕
  //不起作用。只有工作,如果我叫frame.paintAll(frame.getGraphics())
  ilt.repaint();
  frame.repaint();  视频下载(1000);
  frame.setTitle(设置背景);
  ilt.setBackground(Color.BLACK);
  //更新屏幕 - 不工作,即使我打电话paintAll ..
  ilt.repaint();
  frame.repaint();            //必须调用其中之一得到任何东西显示
// ilt.paintComponent(frame.getGraphics()); //作品
  frame.paintComponents(frame.getGraphics()); //作品
 } //私有帮助功能 私有String [] createImageFileNames(诠释计数){
  的String [] =文件名新的String [统计]
  的for(int i = 0; I<计数;我++)
   文件名[我] =卡+文件分割符+(I + 1)+.BMP;
  返回的文件名;
 }
}


解决方案

这些都是与原来的code,导致它不工作存在的主要问题:


  1. 一个加载()操作后,没有要求的validate()

  2. 未设置组件的preferred大小。

  3. 没有要求super.paintComponent方法()重写时(本作的
    的setBackground()调用无法正常工作)

  4. 我需要从JPanel中为了继承它得到画。无论是组件还是JComponent的是足够了的setBackground()调用工作,即使固定点3时。

做完上面的,它真的没有,因为我记起了给超级构造函数在一开始的问题,如果在调用该方法的paintComponent或油漆,似乎都只要工作。

该信息是从什么@jitter,@tackline组装和@camickr写道,这么大的荣誉!

P.S。不知道是否回答自己的问题被认为是不好的形式,但因为我所需要的信息是从几个答案组装,我想最好的办法是upmodding其他答案,写一个总结是这样的。

For the last two days I have tried to understand how Java handles graphics, but have failed miserably at just that. My main problem is understanding exactly how and when paint() (or the newer paintComponent() ) is/should be called.

In the following code I made to see when things are created, the paintComponent() is never called, unless I manually add a call to it myself or calls to JFrame.paintAll()/JFrame.paintComponents().

I renamed the paint() method to paintComponent() in hoping that would fix my problem of it never being called (even at repaint()), but no luck.

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;
 }
}
解决方案

These were the main problems with the original code that caused it not to work:

  1. not calling validate() after an add() operation
  2. not setting the preferred size of the component.
  3. not calling super.paintComponent() when overriding it (this made thesetBackground() call not work)
  4. I needed to inherit from JPanel in order for it to get painted. Neither Component nor JComponent was sufficient for the setBackground() call to work, even when fixing point 3.

Having done the above, it really didn't matter if calling the method paintComponent or paint, both seemed to work as long as I remembered to call the super constructor at the start.

This info was assembled from what @jitter, @tackline, and @camickr wrote, so big kudos!

P.S. No idea if answering your own question is considered bad form, but since the information I needed was assembled from several answers, I thought the best way was upmodding the other answers and writing a sum up like this.

这篇关于为什么油漆()/的paintComponent()从来没有所谓的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 13:17