Kod Źródłowy z podręcznika JAVA: nie działa i okienko się nie zamyka

0

Witam. Problem jest taki. Uczę się z podręcznika Horstmann,Cornell JAVA Wydanie IX. Kod źródłowy przepisany z podręcznika do Eclipse nie działa mi poprawnie i nie wiem, jaka jest przyczyna. Po uruchomieniu wyświetla się okienko, ale puste, nie pojawiają się w nim obrazy, które powinny (plik blue-ball.gif mam na dysku). Co więcej okienko nie reaguje na klikanie zamknięcia w prawym górnym rogu, ani nie chce się zamknąć z paska zadań. Zamyka się dopiero przy pomocy Menedżera zadań. Co jest źle? Wszystko jest wpisane w Eclipse tak, jak w podręczniku. Jest ktoś w stanie mi pomóc?

Kod źródłowy:


import java.awt.EventQueue;

import javax.swing.JFrame;

public class ImageTest
{

	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
			{
				public void run()
				{
					JFrame frame = new ImageFrame();
					frame.setTitle("Obraz");
					frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
					frame.setVisible(true);
				}
			});
	}

}

import javax.swing.JFrame;

class ImageFrame extends JFrame
{
	public ImageFrame()
	{
		add(new ImageComponent());
		pack();
	}
}

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JComponent;

class ImageComponent extends JComponent
{
	private static final int DEFAULT_WIDTH = 300;
	private static final int DEFAULT_HEIGHT = 200;
	
	private Image image;
	
	public ImageComponent()
	{
		image = new ImageIcon("blue-ball.gif").getImage();
	}
	public void paintComponent(Graphics g)
	{
		if(image == null) return;
		
		int imageWidth = image.getWidth(this);
		int imageHeight = image.getHeight(this);
		
		g.drawImage(image, 0, 0, null);
		
		for ( int i =0; i*imageWidth <= getWidth(); i++)
			for(int j=0; j*imageHeight <= getHeight(); j++)
				if(i+j>0) g.copyArea(0,0, imageWidth, imageHeight, i*imageWidth, j*imageHeight);
	}
	public Dimension getPreferredSize()
	{
		return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
	}
}
 
0

A jaki to numer działu/zadania?
Bo kiedyś przerabiałem tą książkę i mogę wkleić swoje rozwiązanie.

0

Rozdział 7 Grafika, Listing 7.6. to jest. To nawet nie zadanie, tylko kod przepisany z książki :)

1
public class ImageComponent extends JComponent {

    private static final int DEFAULT_WIDTH = 400;
    private static final int DEFAULT_HEIGHT = 300;
    private Image image;

    public ImageComponent() {
        URL urlImage = getClass().getResource("happy.gif");
        this.image = new ImageIcon(urlImage).getImage();
    }

    @Override
    public void paintComponent(Graphics graphics) {

        if (image == null) {
            System.out.println("Obrazu nie odnaleziono.");
        }

        int imageWidth = image.getWidth(this);
        int imageHeight = image.getHeight(this);

        graphics.drawImage(image, 0, 0, null);

        for (int i = 0; i < DEFAULT_WIDTH; i += imageWidth) {
            for (int j = 0; j < DEFAULT_HEIGHT; j += imageHeight) {
                if (i + j > 0) {
                    graphics.drawImage(image, i, j, null);
                }
            }
        }

        Graphics2D graphics2D = (Graphics2D) graphics;
        Rectangle2D rectangle2D = new Rectangle2D.Double(0, 0, imageWidth, imageHeight);
        graphics2D.draw(rectangle2D);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }
}
public class ImageFrame extends JFrame {

    public ImageFrame() {
        add(new ImageComponent());
        pack();
    }
}
public class ImageTest {
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                ImageFrame frame = new ImageFrame();
                frame.setTitle("Image");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

To jest moje rozwiązanie, które mam na dysku.
Jak ci już ktoś napisał w komentarzu sprawdź ścieżkę do pliku. U mnie plik happy.jpg jest w tym samym katalogu co klasa.

Aha i teraz widzę, że ten kod trochę nie pokrywa się trochę z tym co jest w książce. Możliwe, że w książce był jakiś błąd.

0

Tak, też tak mam, ścieżka ok ;x

0

A no to to by to wyjaśniało:D fakt, że Twój kod zaczął mi w konsoli wyświetlać błędy, ale to zaraz przejrzę, może coś namieszałam w nim

0

Dzięki za pomoc:)

3

Zaintrygowało mnie dlaczego, mimo instrukcji

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

nie można programu zakończyć klikaniem w "krzyżyk".
Rozwiązanie zagadki trochę mnie zaskoczyło. Otóż jeżeli brakuje pliku graficznego (blue-ball.gif), to

new ImageIcon("blue-ball.gif").getImage();

nie zwraca null`a, natomiast

 
new ImageIcon("blue-ball.gif").getImage().getWidth();

zwraca -1. W konsekwencji, w kodzie metody paintComponent pojawia się nieskończona pętla.

    public void paintComponent(Graphics g)
    {
        if(image == null) return;
 
        int imageWidth = image.getWidth(this);
        int imageHeight = image.getHeight(this);
 
        g.drawImage(image, 0, 0, null);
 
        for ( int i =0; i*imageWidth <= getWidth(); i++)
            for(int j=0; j*imageHeight <= getHeight(); j++)
                if(i+j>0) g.copyArea(0,0, imageWidth, imageHeight, i*imageWidth, j*imageHeight);
    }

Metoda paintComponent powinna się zaczynać tak:

    public void paintComponent(Graphics g)
    {
        int imageWidth = image.getWidth(this);
        if(imageWidth == -1)
        { 
             //ewentualny komunikat
             return;
        }
0

Dzięki!

1 użytkowników online, w tym zalogowanych: 0, gości: 1