3

I'm having a major problem with this school assignment; lucky I started it early for once. We've been asked to make a children's math game using a JApplet. So far so good. I have managed to create a JPanel, which is then added to the JApplet and holds all the drawings (the JPanel contents are continually being redrawn). However, whenever I try to add a Swing component such as a JLabel to the JApplet content pane, it does not show or show signs of ever existing. I am completely new to JApplets so please don't be too harsh if it's obvious.

Below is the code:

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JApplet;
import javax.swing.JPanel;
import javax.swing.Timer;

public class CountingSheep extends JApplet
{

    final int BOARDWIDTH = 800;
    final int BOARDHEIGHT = 500;
    final int SCREENWIDTH = 800;
    final int SCREENHEIGHT = 800;
    Dimension boardDim = new Dimension(BOARDWIDTH, BOARDHEIGHT);
    Dimension screenDim = new Dimension(SCREENWIDTH, SCREENHEIGHT);
    Graphics bufferGraphics;
    Image offScreen;
    Image backgroundImage;
    Image[] sheepImage = new Image[2];
    JPanel gameBoard = new JPanel(true);
    List<Sheep> sheepArray = new ArrayList<>();
    Timer myTimer;

    public void init()
    {
        loadImages();
        initScreen();
        initBufferGraphics();
        initBoard();
        initTimer();
        sheepArray.add(new Sheep(sheepImage));
        myTimer.start();
    }

    private void loadImages()
    {
        sheepImage[0] = getImage(getDocumentBase(), "sheep.png");
        sheepImage[1] = getImage(getDocumentBase(), "sheep2.png");
        backgroundImage = getImage(getDocumentBase(), "bg.jpg");
    }

    private void initScreen()
    {
        setSize(800, 600);
        setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
    }

    private void initBoard()
    {
        gameBoard.setPreferredSize(new Dimension(BOARDWIDTH, BOARDHEIGHT));
        getContentPane().add(gameBoard);
    }

    private void initBufferGraphics()
    {
        offScreen = createImage(BOARDWIDTH, BOARDHEIGHT);
        bufferGraphics = offScreen.getGraphics();
    }

    private void initTimer()
    {
        myTimer = new Timer(80, new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                timerTick(e);
            }
        });
    }

    private void timerTick(ActionEvent e)
    {
        repaint();
    }

    public void paint(Graphics g)
    {
        bufferGraphics.clearRect(0, 0, BOARDWIDTH, BOARDHEIGHT);
        bufferGraphics.drawImage(backgroundImage, 0, 0, null);
        drawSheepHerd();
        moveSheepHerd();
        gameBoard.getGraphics().drawImage(offScreen, 0, 0, this);
    }

    public void drawSheepHerd()
    {
        for (Sheep s : sheepArray)
        {
            s.draw(bufferGraphics);
        }
    }

    public void moveSheepHerd()
    {
        for (Sheep s : sheepArray)
        {
            s.move();
        }
    }
}

Thanks in advance, hope you guys can figure it out because I'm stumped.

A.M.K
  • 16,727
  • 4
  • 32
  • 64
JohnW
  • 345
  • 1
  • 7
  • 15
  • Quite possibly this is due to the applet's contentPane using BorderLayout by default, and you adding both components to the BorderLayout.CENTER position, but where do you add the JLabel as I don't see that in your code? – Hovercraft Full Of Eels Jun 09 '12 at 12:23
  • And 1+ for starting your project early. ;-). That's so rare to see. – Hovercraft Full Of Eels Jun 09 '12 at 12:24
  • Also, don't draw directly on the JApplet itself in its paint method, but rather, draw in a JComponent or derivative such as JPanel, in their paintComponent method. This will give you double buffering by default. – Hovercraft Full Of Eels Jun 09 '12 at 12:25
  • @HovercraftFullOfEels the label code isn't there atm, but it was simply declaring and instantiating the label, then adding it to the content pane in the exact same way I did the JPanel. I will try using a flowlayout! I've added a setLayout() in the initScreen method, has not fixed it. – JohnW Jun 09 '12 at 12:30
  • You will need to set the layout of the contentPane. In fact if this were my project, I'd create my own ContentPane class that extends JPanel and that does my drawing, and that draws in the paintComponent method. – Hovercraft Full Of Eels Jun 09 '12 at 12:32
  • @HovercraftFullOfEels Alrighty, let me have a go, thanks for the guidance! :D – JohnW Jun 09 '12 at 12:35
  • 1
    `setSize(800, 600);` Set the applet size in HTML. – Andrew Thompson Jun 09 '12 at 13:28

1 Answers1

3

To summarize some of my recommendations:

  • Create your own ContentPane class that extends JPanel, that overrides paintComponent(...) and that draws your background image and shows the animation.
  • Call setContentPane(...) on the JApplet in the init method, passing in an object of this class.
  • Experiment with different layouts and positionings for the ContentPane.
  • Make sure that the very first line of the paintComponent(Graphics g) method is: super.paintComponent(g) so that your drawing will be reset each time it paints.
  • JPanels are opaque by default, and you should leave it as such since contentPanes must be opaque. If you add components on top of the contentPane and want to see the image behind the added components, you may have to make them non-opaque.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373