图像不加载

框架窗口正在启动,但背景和前景图像不加载,窗口框架的大小也非常小。 请帮我解决这个错误。

这里是张贴的代码

Aquarium.java

import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.util.Vector; public class Aquarium extends Frame implements Runnable { Image aquariumImage,memoryImage; BufferedImage bImage; Graphics memoryGraphics; Image [] fishImages=new Image[2]; MediaTracker tracker; int numberFishes=12; Vector<Fish> fishes=new Vector<Fish>(); Thread thread; boolean runOk=true; int sleepTime=110; Fish fish; Aquarium() { //set the title and assign tracker object setTitle("The Aquarium "); tracker=new MediaTracker(this); //add images to the tracker object to trace it fishImages[0]=Toolkit.getDefaultToolkit().getImage("src\fish1.gif"); tracker.addImage(fishImages[0], 0); System.out.println("fish 1 size "+Toolkit.getDefaultToolkit().getImage("src\fish1.gif").getWidth(null)); fishImages[1]=Toolkit.getDefaultToolkit().getImage("src\fish2.gif"); tracker.addImage(fishImages[1], 0); aquariumImage =Toolkit.getDefaultToolkit().getImage("src\bubbles.gif"); tracker.addImage(aquariumImage,0); setResizable(true); setVisible(true); //assign memory to the graphics and anotherImage object int dx=getSize().width; int dy=getSize().height; System.out.println("x value is "+dx+ " dy value is "+ dy); bImage=new BufferedImage(dx, dy,BufferedImage.TYPE_INT_ARGB); try { memoryGraphics=bImage.getGraphics(); } catch(Exception exc) { System.out.println(exc.getCause()); System.out.println(exc.getStackTrace()); } //create a new thread and start the thread thread=new Thread(); thread.start(); try { tracker.waitForID(0); } catch (Exception ex) { System.out.println(ex.getMessage()); } setSize(aquariumImage.getWidth(this),aquariumImage.getHeight(this)); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { System.exit(0); runOk=false; } }); } public static void main(String ar[]) { new Aquarium(); } @Override public void run() { //draw 4 edges of rectangle Rectangle edges=new Rectangle(0+getInsets().left,0+getInsets().top, getSize().width-(getInsets().left+getInsets().right), getSize().height-(getInsets().top+getInsets().bottom)); //add fishes to the fishes vector for (int loopIndex=0; loopIndex<numberFishes;loopIndex++) { fishes.add(new Fish(fishImages[0],fishImages[1],edges,this)); try { Thread.sleep(20); } catch (Exception e) { System.out.println(e.getMessage()); } } while(runOk) { for(int loopIndex=0; loopIndex < numberFishes; loopIndex++) { fish=(Fish)fishes.elementAt(loopIndex); fish.swim(); } try { Thread.sleep(sleepTime); } catch (Exception e) { System.out.println(e.getMessage()); } repaint(); } } public void update(Graphics g) { memoryGraphics.drawImage(aquariumImage, 0, 0, this); for(int loopIndex=0;loopIndex<numberFishes;loopIndex++) { ((Fish)fishes.elementAt(loopIndex)).drawFishImage(memoryGraphics); } g.drawImage(bImage, 0, 0, this); } } 

fish.java

 import java.awt.*; import java.util.Random; public class Fish { Component tank; Image image1,image2; Point location,velocity; Rectangle edges; Random random; public Fish(Image image1,Image image2, Rectangle edges,Component tank) { random = new Random(System.currentTimeMillis()); this.tank=tank; this.image1=image1; this.image2=image2; this.edges=edges; this.location=new Point(100+ (Math.abs(random.nextInt())%300), 100+Math.abs(random.nextInt())%100)); this.velocity=new Point(random.nextInt()%8,random.nextInt()%8); } public void swim() { //determine the optimum velocity to make the fish swim if(random.nextInt()%7<=1) { velocity.x += random.nextInt() % 4 ; velocity.x = Math.min(velocity.x, 8); velocity.x = Math.max(velocity.x, -8); velocity.y += random.nextInt() % 4; velocity.y = Math.min(velocity.y, 8); velocity.y = Math.max(velocity.y, -8); } //add the velocity to the location of the fish to make it move location.x += velocity.x; location.y += velocity.y; if(location.x < edges.x) { location.x=edges.x; velocity.x = -velocity.x; } if((location.x + image1.getWidth(tank)) > (edges.x + edges.width)) { location.x = edges.x + edges.width - image1.getWidth(tank); velocity.x = -velocity.x; } if(location.y < edges.y) { location.y = edges.y; velocity.y = -velocity.y; } if((location.y + image1.getHeight(tank)) > (edges.y + edges.height)) { location.y = edges.y + edges.height - image1.getHeight(tank); velocity.y = -velocity.y; } } public void drawFishImage(Graphics g) { if(velocity.x < 0) { g.drawImage(image1,location.x,location.y,tank); } else { g.drawImage(image2, location.x, location.y, tank); } } } 

我很抱歉地说这个,但是你的代码有太多错误…

让我们从开始:

  • 请勿覆盖顶层容器的任何paint方法。 首先,没有一个顶级容器是双缓冲的。
  • 使用轻量级组件而不是重量级组件(使用JFrame而不是Frame ,使用JPanel而不是Panel )…
  • 使用JPanel作为您的绘画表面而不是Frame ,出于与上述相同的原因…
  • 如前所述,你是线程代码什么都不做( new Thread().start() )。
  • 你没有油漆代码,实际上在屏幕上画鱼(是的,你的鱼有油漆代码,但没有人称它)。
  • 你的随机数发生器不工作。 我把所有的鱼都在同一个地方游完了
  • 你是图片加载代码是错误的。 改用ImageIO
  • 不要直接存储矩形参考。 问题是,如果窗口被resize,鱼的游泳范围将会改变,即使它们被容纳在水族箱的边界内,水族箱的位置也可能发生变化。
  • 如图所示,图像path不正确。 你从不在任何path中包含src 。 一旦部署, srcpath将不再存在。

这是我的…

Fishies

水族馆

 public class Aquarium extends JPanel { public static final int NUMNBER_OF_FISHIES = 12; private BufferedImage masterFish; private Vector<Fish> fishes = new Vector<Fish>(NUMNBER_OF_FISHIES); private int sleepTime = 110; public Aquarium() { //set the title and assign tracker object try { masterFish = ImageIO.read(getClass().getResource("/gnome_panel_fish.png")); } catch (IOException iOException) { iOException.printStackTrace(); } // This is a little cheat which means you only ever need one fish image // Basically it will flip the master along it's horizontal axies ;) BufferedImage flippedMaster = new BufferedImage(masterFish.getWidth(), masterFish.getHeight(), masterFish.getType()); Graphics2D g2d = flippedMaster.createGraphics(); g2d.setTransform(AffineTransform.getScaleInstance(-1, 1)); g2d.drawImage(masterFish, -masterFish.getWidth(), 0, this); g2d.dispose(); for (int index = 0; index < NUMNBER_OF_FISHIES; index++) { fishes.add(new Fish(masterFish, flippedMaster, this)); } Thread background = new Thread(new Background()); background.setDaemon(true); background.start(); } public static void main(String ar[]) { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException classNotFoundException) { } catch (InstantiationException instantiationException) { } catch (IllegalAccessException illegalAccessException) { } catch (UnsupportedLookAndFeelException unsupportedLookAndFeelException) { } JFrame frame = new JFrame("The Aquarium "); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new Aquarium()); frame.setSize(400, 400); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); for (Fish fish : fishes) { fish.drawFishImage(g); } } protected class Background implements Runnable { @Override public void run() { while (true) { for (Fish fish : fishes) { fish.swim(); } try { Thread.sleep(sleepTime); } catch (Exception e) { System.out.println(e.getMessage()); } repaint(); } } } } 

 public class Fish { private Component tank; private Image image1, image2; private Point location, velocity; private Random random; public Fish(Image image1, Image image2, Component tank) { random = new Random(); this.tank = tank; this.image1 = image1; this.image2 = image2; this.location = new Point( 100 + (Math.abs(random.nextInt()) % 300), 100 + Math.abs(random.nextInt()) % 100); this.velocity = new Point(random.nextInt() % 8, random.nextInt() % 8); System.out.println(location); } public void swim() { Rectangle edges = tank.getBounds(); //determine the optimum velocity to make the fish swim if (random.nextInt() % 7 <= 1) { velocity.x += random.nextInt() % 4; velocity.x = Math.min(velocity.x, 8); velocity.x = Math.max(velocity.x, -8); velocity.y += random.nextInt() % 4; velocity.y = Math.min(velocity.y, 8); velocity.y = Math.max(velocity.y, -8); } //add the velocity to the location of the fish to make it move location.x += velocity.x; location.y += velocity.y; if (location.x < edges.x) { location.x = edges.x; velocity.x = -velocity.x; } if ((location.x + image1.getWidth(tank)) > (edges.x + edges.width)) { location.x = edges.x + edges.width - image1.getWidth(tank); velocity.x = -velocity.x; } if (location.y < edges.y) { location.y = edges.y; velocity.y = -velocity.y; } if ((location.y + image1.getHeight(tank)) > (edges.y + edges.height)) { location.y = edges.y + edges.height - image1.getHeight(tank); velocity.y = -velocity.y; } } public void drawFishImage(Graphics g) { if (velocity.x < 0) { g.drawImage(image1, location.x, location.y, tank); } else { g.drawImage(image2, location.x, location.y, tank); } } } 

在你的代码的几个问题中,有两个脱颖而出:

  • 您创build一个新的ThreadRunnable “方法什么都不做,并返回”。 相反,在构造函数中提供你的实现:

     //create a new thread and start the thread thread = new Thread(this); thread.start(); 
  • 你已经标记了你的问题摆动 ,其对象只能在事件派发线程上构造和操作。 使用javax.Swing.Timer一个实例来代替Runnablejavax.Swing.Timer所示。

附录:您的绘图表面应该是JComponent比如JPanel 。 由于它本身不包含任何组件,因此可以覆盖getPreferredSize() (如下所示getPreferredSize()pack()封闭Window以获得正确的大小。

这是因为你似乎在使用相对path。 作为一个testing,使用硬编码path。 一旦工作,你可以改变你的上下文。