Car on Track scrollable pane

Hello, this is my first java program. I am attempting to get a racecar gif to show up on my scrollable pane racetrack gif. Here is my code. The track shows up in the scrollable pane but the car does not. Any direction would be greatly appreciated.

It looks like I need to add something to the paintcomponent of ScrollablePicture. When I add a circle like this it draws it:


    protected void paintComponent(Graphics g) {
      super.paintComponent(g);  
      img = getToolkit().createImage("00Flames0.gif");
      g.fillOval(10, 10, 10, 10);
    }


When I go to change the oval to a draw image, it draws nothing?


    protected void paintComponent(Graphics g) {
      super.paintComponent(g);  
      img = getToolkit().createImage("00Flames0.gif");
/*      g.fillOval(10, 10, 10, 10);*/
      g.drawImage(img, 10, 10, this);
    }


Thank you,
Dale


package CarOnTrack;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Canvas;
import javax.swing.JLabel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.border.*;
import java.awt.image.*;
import java.net.*;
import javax.imageio.*;


public class CarOnTrack extends JPanel {  
    private JPanel mainPanel;
    private JLabel imageLabel;
  
  public CarOnTrack (){	
    //Make sure we have nice window decorations.
    JFrame.setDefaultLookAndFeelDecorated(true);

    //Create and set up the window.
    JFrame frame = new JFrame("CarOnTrack");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
        
    JPanel panel = (JPanel)frame.getContentPane();
    
    ScrollDemo trackscrollable = new ScrollDemo();
    
    mainPanel = new JPanel();
    Icon myIcon = new ImageIcon("00Flames0.gif");
    imageLabel = new JLabel(myIcon);
    mainPanel.add(imageLabel);
    mainPanel.setVisible(true);
    trackscrollable.add(mainPanel,1,1);
    
    panel.add(trackscrollable);
    frame.setBounds(0,0,500,300);  
    frame.setVisible(true);
  }

  public static void main(String[] args) 
  {   
	  System.out.println("BEGIN PROGRAM");
	  CarOnTrack cot = new CarOnTrack();
	  System.out.println("END PROGRAM");      
  }
}
package CarOnTrack;

import java.awt.*;
import java.awt.event.*;
import javax.swing.border.*;
import javax.swing.*;

public class ScrollDemo extends JPanel {
    private ScrollablePicture picture;
    private ScrollablePicture picture2;
    Image trackgif;
        
    public ScrollDemo() {
        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));

        //Get the image to use.
        ImageIcon trackgif = createImageIcon("Daytona.gif");
    	 
        //Set up the scroll pane.
        picture = new ScrollablePicture(trackgif, 1);
        JScrollPane pictureScrollPane = new javax.swing.JScrollPane(picture);
        pictureScrollPane.setPreferredSize(new Dimension(200, 100));
        pictureScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));
        
        add(pictureScrollPane);
        setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
    }
		
    /** Returns an ImageIcon, or null if the path was invalid. */
    protected static ImageIcon createImageIcon(String path) {
        java.net.URL imgURL = ScrollDemo.class.getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }

     public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
            }
        });
    }
}
package CarOnTrack;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ScrollablePicture extends JLabel
                               implements Scrollable,
                                          MouseMotionListener {

    private int maxUnitIncrement = 1;
    private boolean missingPicture = false;

    public ScrollablePicture(ImageIcon i, int m) {
        super(i);
        if (i == null) {
            missingPicture = true;
            setText("No picture found.");
            setHorizontalAlignment(CENTER);
            setOpaque(true);
            setBackground(Color.white);
        }
        maxUnitIncrement = m;

        //Let the user scroll by dragging to outside the window.
        setAutoscrolls(true); //enable synthetic drag events
        addMouseMotionListener(this); //handle mouse drags
    }

    //Methods required by the MouseMotionListener interface:
    public void mouseMoved(MouseEvent e) { }
    public void mouseDragged(MouseEvent e) {
        //The user is dragging us, so scroll!
        Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
        scrollRectToVisible(r);
    }

    public Dimension getPreferredSize() {
        if (missingPicture) {
            return new Dimension(320, 480);
        } else {
            return super.getPreferredSize();
        }
    }

    public Dimension getPreferredScrollableViewportSize() {
        return getPreferredSize();
    }

    public int getScrollableUnitIncrement(Rectangle visibleRect,
                                          int orientation,
                                          int direction) {
        //Get the current position.
        int currentPosition = 0;
        if (orientation == SwingConstants.HORIZONTAL) {
            currentPosition = visibleRect.x;
        } else {
            currentPosition = visibleRect.y;
        }

        //Return the number of pixels between currentPosition
        //and the nearest tick mark in the indicated direction.
        if (direction < 0) {
            int newPosition = currentPosition -
                             (currentPosition / maxUnitIncrement)
                              * maxUnitIncrement;
            return (newPosition == 0) ? maxUnitIncrement : newPosition;
        } else {
            return ((currentPosition / maxUnitIncrement) + 1)
                   * maxUnitIncrement
                   - currentPosition;
        }
    }

    public int getScrollableBlockIncrement(Rectangle visibleRect,
                                           int orientation,
                                           int direction) {
        if (orientation == SwingConstants.HORIZONTAL) {
            return visibleRect.width - maxUnitIncrement;
        } else {
            return visibleRect.height - maxUnitIncrement;
        }
    }

    public boolean getScrollableTracksViewportWidth() {
        return false;
    }

    public boolean getScrollableTracksViewportHeight() {
        return false;
    }

    public void setMaxUnitIncrement(int pixels) {
        maxUnitIncrement = pixels;
    }
}

First of all, if this is your first program then you don’t want to do anything much more complicated than printing Hello World, etc.

Second, in your paintComponent, which is likely to be called tens to hundreds of times per second in a normal game, you’re invoking createImage, creating a completely new image by reading it from the disk. Needless to say this operation is extremely demanding from the computer, and the drawImage method is designed not to hold up the computer in case the drawn image has not yet been entirely loaded.

So what you need to do is load your image EXACTLY ONCE from the disk into memory, then reuse that very same image each time you draw.

Thanks, actually I did do the Hello World first, so this is my second program.

Ok, I am now loading the image outside of the paintComponent and it still does not show up on the scrollpane.

This is the paintComponent of the scrollpane now. The filloval and drawstring work fine but the drawimage does not?


    public void paintComponent(Graphics g) {
      super.paintComponent(g);  
      
      if (img != null) {
        g.drawImage(img, 20, 20, null);
      }  
      else
      {	  
    	System.out.println("no img found");      
      }
      g.fillOval(10, 10, 10, 10);
      g.drawString("Wheres my GIF!", 20, 120);
      
    }

So is your image null or is it not?

It is not null.

well I don’t know the solution but you could print out gif’s height and width (using image’s get methodes) to make sure you have right image and nothing happened to it while loading. Also try with BufferedImage. Try removing the image file, do you get expected error?
If you still can’t figure it out, if I were you I would write a separete small example where I would just load image and display it on screen. If that works, then display it in JPanel (via overriding paintComponent()), … and so on adding complexity towards your goal.

Kova gives good advice: make it work in a simple case, so you fully understand what is going on. Then extend your code step by step into something more complex, testing for each step that it works as expected.

Perhaps you load the image by means of a non-blocking call, which was the case with getToolKit().createImage() (as far as I know). This means the system won’t wait for the image to load, but just draw so much of the image as has already been loaded. Now, if you do not yet have a main loop running, i.e. you don’t redraw continuously, then the first call to drawImage may very well not draw anything at all since the picture has not yet been loaded. You may want to make sure this is not the problem (by continuously rendering or using a blocking method to load the image so you’re sure the image is fully loaded when the drawImage method is invoked.

By the way, ‘non-blocking’ means the operation will be carried out in the background while other things are proceeding, whereas blocking means the system will wait for the completion of the task before proceeding.

These things are just POSSIBLE explanations, they could very well be wrong, because I didn’t bother to read all the code.