【问题标题】:the images are not loading图像未加载
【发布时间】:2012-09-20 12:09:13
【问题描述】:

框架窗口正在启动,但背景和前景图像没有加载,并且窗口框架大小也非常小。 请帮我修复错误。

这里是贴出的代码

水族馆.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);
        }
    }
}

【问题讨论】:

  • 您应该将您的示例简化为仍能证明问题的最短示例。而且您可能应该避免使用线程来执行您正在做的事情。完成绘画后,只需在您的绘画方法中调用 invalidate() 即可。
  • 我在您的代码中发现了一些问题,因为您使用单个反斜杠来指定像 "src\fish1.gif""* 这样的路径,或者您提供两个像 ** 这样的反斜杠"src\\fish1.gif" 或单个正斜杠(两者中更好的),例如 "src/fish1.gif"
  • @Jagdeep : 你很受欢迎并保持微笑:-)

标签: java image swing frame paintcomponent


【解决方案1】:

我很抱歉这么说,但你的代码有很多问题......

让我们开始:

  • 不要覆盖顶级容器的任何paint 方法。首先,没有一个顶级容器是双缓冲的。
  • 使用轻量级组件而不是重型组件(使用JFrame 代替Frame,使用JPanel 代替Panel)...
  • 使用JPanel 作为您的绘画表面,而不是Frame,原因与上述相同...
  • 如上所述,您的线程代码什么也没做 (new Thread().start())。
  • 您没有绘制代码​​来将鱼实际绘制到屏幕上(是的,您的鱼有绘制代码​​,但没有调用它)。
  • 您的随机数生成器不工作。我让所有的鱼都在同一个地方游来游去……
  • 您的图像加载代码错误。请改用ImageIO
  • 不要直接存储矩形引用。问题是,如果调整窗口大小,鱼可以游泳的范围会发生变化,即使它们被包含在水族箱的范围内,水族箱的位置也可能发生变化。
  • 如前所述,您的图像路径不正确。您永远不会在任何路径中包含src。部署后,src 路径将不再存在。

这是我的看法...

水族馆

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

【讨论】:

  • @Jagdeep :简单来说,使用 Swing 而不是 AWT :-)
  • 非常感谢您以如此优美的方式解释它。我不介意是否有人发现我或我的工作中的错误,因为它总是有助于改进。我正在使用 awt 而不是 swing,因为我正在学习这一点。一旦它开始工作,我会将其更改为 Swings 并使用其他东西
  • @Jagdeep 请注意 AWT 不提供双缓冲,因此它可能会闪烁。
【解决方案2】:

在您的代码存在的几个问题中,有两个比较突出:

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

    //create a new thread and start the thread
    thread = new Thread(this);
    thread.start();
    
  • 您已标记您的问题,其对象应event dispatch thread 上构造和操作。使用javax.Swing.Timer 的实例代替Runnable,如图所示here

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

【讨论】:

    【解决方案3】:

    这是因为您似乎使用的是相对路径。作为测试,使用硬编码路径。一旦它工作,你可以改变它的上下文。

    【讨论】:

    • @trashgod :但是 OP 只提供一个反斜杠,OP 不需要提供两个反斜杠或一个正斜杠来指定路径吗?
    • @GagandeepBali:好收获!感谢您的澄清。
    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 2013-12-10
    • 2016-09-28
    • 2021-07-12
    • 2019-07-24
    • 2015-01-30
    • 2020-10-07
    • 1970-01-01
    相关资源
    最近更新 更多