Java 在具有不断重新绘制的JPanel的JApplet中使用组件

Java 在具有不断重新绘制的JPanel的JApplet中使用组件,java,swing,applet,japplet,Java,Swing,Applet,Japplet,我对这项学校作业有个大问题;幸运的是我早一点就开始了。我们被要求使用JApplet制作一个儿童数学游戏。到现在为止,一直都还不错。我已经设法创建了一个JPanel,然后将其添加到JApplet,并保存所有的图形(JPanel的内容不断被重新绘制)。但是,每当我尝试将Swing组件(如JLabel添加到JApplet内容窗格中时,它都不会显示或显示任何存在的迹象。我是全新的JApplets,所以如果是显而易见的,请不要太苛刻 代码如下: import java.awt.Dimension; imp

我对这项学校作业有个大问题;幸运的是我早一点就开始了。我们被要求使用
JApplet
制作一个儿童数学游戏。到现在为止,一直都还不错。我已经设法创建了一个
JPanel
,然后将其添加到
JApplet
,并保存所有的图形(JPanel的内容不断被重新绘制)。但是,每当我尝试将Swing组件(如
JLabel
添加到
JApplet
内容窗格中时,它都不会显示或显示任何存在的迹象。我是全新的
JApplet
s,所以如果是显而易见的,请不要太苛刻

代码如下:

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();
        }
    }
}
导入java.awt.Dimension;
导入java.awt.FlowLayout;
导入java.awt.Graphics;
导入java.awt.Image;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JApplet;
导入javax.swing.JPanel;
导入javax.swing.Timer;
公共类计数表扩展了JApplet
{
最终内板宽度=800;
最终内板高度=500;
最终int屏幕宽度=800;
最终int屏幕高度=800;
尺寸boardDim=新尺寸(板宽、板高);
尺寸屏幕尺寸=新尺寸(屏幕宽度、屏幕高度);
图形缓冲图形;
屏幕外图像;
图像背景图像;
Image[]sheepImage=新图像[2];
JPanel gameBoard=新JPanel(真);
List sheepArray=new ArrayList();
计时器myTimer;
公共void init()
{
loadImages();
initScreen();
initBufferGraphics();
initBoard();
initTimer();
添加(新绵羊(绵羊年龄));
myTimer.start();
}
私有void loadImages()
{
sheepImage[0]=getImage(getDocumentBase(),“sheep.png”);
sheepImage[1]=getImage(getDocumentBase(),“sheep2.png”);
backgroundImage=getImage(getDocumentBase(),“bg.jpg”);
}
私有void initScreen()
{
设置大小(800600);
setLayout(新的FlowLayout(FlowLayout.LEFT,0,0));
}
私人董事会()
{
gameBoard.setPreferredSize(新尺寸(板宽、板高));
getContentPane().add(游戏板);
}
私有void initBufferGraphics()
{
屏幕外=createImage(板宽、板高);
bufferGraphics=屏幕外的.getGraphics();
}
私有void initTimer()
{
myTimer=新计时器(80,新ActionListener()
{
已执行的公共无效操作(操作事件e)
{
timerTick(e);
}
});
}
私有void timerTick(ActionEvent e)
{
重新油漆();
}
公共空间涂料(图g)
{
clearRect(0,0,BOARDWIDTH,BOARDHEIGHT);
bufferGraphics.drawImage(backgroundImage,0,0,null);
drawshepherd();
moveshepherd();
gameBoard.getGraphics().drawImage(屏幕外,0,0,此);
}
公共空间drawshepherd()
{
供(羊s:sheepArray)
{
s、 绘制(图形);
}
}
公共空间移动牧羊人()
{
供(羊s:sheepArray)
{
s、 move();
}
}
}

提前谢谢,希望你们能理解,因为我很难办。

总结一下我的一些建议:

  • 创建自己的ContentPane类,该类扩展JPanel,覆盖
    paintComponent(…)
    ,并绘制背景图像和显示动画
  • 在init方法中对JApplet调用setContentPane(…),传入此类的对象
  • 尝试ContentPane的不同布局和位置
  • 确保
    paintComponent(Graphics g)
    方法的第一行是:
    super.paintComponent(g)
    ,以便每次绘制时都会重置图形
  • 默认情况下,JPanel是不透明的,您应该将其保留为不透明的,因为contentPanes必须是不透明的。如果在contentPane顶部添加组件,并希望看到添加组件后面的图像,则可能必须使其不不透明

这很可能是由于小程序的contentPane默认使用BorderLayout,并且您将这两个组件都添加到BorderLayout.CENTER位置,但是您在哪里添加JLabel,因为我在您的代码中没有看到这一点?以及提前启动项目的1+;-)。这是很少见的。另外,不要在JApplet的绘制方法中直接绘制JApplet本身,而是在其绘制组件方法中绘制JComponent或衍生工具,如JPanel。默认情况下,这将为您提供双缓冲。@HovercraftFullOfEels标签代码不在atm中,但它只是声明和实例化标签,然后以与JPanel完全相同的方式将其添加到内容窗格中。我将尝试使用flowlayout!我在initScreen方法中添加了一个setLayout(),但没有修复它。
setSize(800600)以HTML格式设置小程序大小。