框架窗口正在启动,但背景和前景图像未加载,窗口框架尺寸也非常小。 请帮我修复错误。
这是发布的代码
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);
}
}
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);
}
}
}
答案 0 :(得分: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);
}
}
}
答案 1 :(得分:4)
在您的代码的几个问题中,有两个突出:
您创建了一个新的Thread
,其Runnable
方法不执行任何操作并返回。“相反,在构造函数中提供您的实现:
//create a new thread and start the thread
thread = new Thread(this);
thread.start();
您已将标记为swing的问题标记为event dispatch thread,其对象应仅在<{3}}上构建和操作 。使用Runnable
的实例代替javax.Swing.Timer
,插图为here。
附录:您的绘图表面应为JComponent
,例如JPanel
。由于它本身不包含任何组件,因此您可以覆盖显示here的getPreferredSize()
和覆盖pack()
的{{1}}以获得正确的大小。
答案 2 :(得分:0)
这是因为你似乎在使用相对路径。作为测试,使用硬编码路径。一旦它工作,你可以改变它的背景。