1

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

这是发布的代码

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

鱼.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);
        }
    }
}
4

3 回答 3

8

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

让我们从:

  • 不要覆盖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);
        }
    }
}
于 2012-09-28T22:39:52.207 回答
4

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

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

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

附录:您的绘图表面应JComponentJPanel. 由于它本身不包含任何组件,因此您可以按照此处getPreferredSize()所示和封闭的方式覆盖以获取正确的尺寸。pack()Window

于 2012-09-28T17:14:18.573 回答
0

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

于 2012-09-28T15:27:12.097 回答