Изображения не загружаются
Окно рамки запускается, но фон и изображения переднего плана не загружаются, а размер рамки окна также очень и очень мал. Пожалуйста, помогите мне исправить ошибку.
вот код размещен
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);
}
}
}
3 ответа
Мне жаль это говорить, но в вашем коде просто так много не так...
Давайте начнем с:
- НЕ переопределять ни один из
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);
}
}
}
Среди нескольких проблем с вашим кодом выделяются две:
Вы создаете новый
Thread
чьяRunnable
"метод ничего не делает и возвращает." Вместо этого укажите вашу реализацию в конструкторе://create a new thread and start the thread thread = new Thread(this); thread.start();
Вы пометили свой вопрос колебанием, чьи объекты должны создаваться и обрабатываться только в потоке отправки событий. Вместо
Runnable
, используйте экземплярjavax.Swing.Timer
, проиллюстрировано здесь.
Приложение: Ваша поверхность для рисования должна быть JComponent
такие как JPanel
, Поскольку он не содержит компонентов, вы можете переопределить getPreferredSize()
как показано здесь и pack()
вмещающий Window
чтобы получить правильный размер.
Это потому, что вы, кажется, используете относительный путь. В качестве теста используйте жестко заданный путь. Как только он заработает, вы можете изменить его в своем контексте.