重绘用作背景的 JPanel 时,如何使其他组件保持在前面?

How to keep the other components in front when redrawing a JPanel used as a background?

我找遍了,我只能找到人们使用他们的自定义 JPannel 在另一个图像上绘制一个图像的情况,但我想做的是在 JPannel 上绘制一个组件,无论我做什么尝试在绘制下一帧时始终移动 JPannel。感觉必须有一种方法可以覆盖在前面绘制它并允许您在后面绘制它的方法,但我可以找到 none。

public class MovingBackgroundDemo {
private JToggleButton button = new JToggleButton("Button");
private JFrame frame = new JFrame();
private int framewidth =frame.getWidth();
private int frameheight =frame.getHeight();
public MovingBackgroundDemo() {

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.addComponentListener(new ComponentAdapter()
    {
        public void componentResized(ComponentEvent evt) {
            framewidth =frame.getWidth();
            frameheight =frame.getHeight();

            button.setBounds(framewidth/2 - framewidth/14 - framewidth/6,frameheight/6, framewidth/6, frameheight / 12);
        }
    });
    frame.add(button);
    frame.add(new AnimatingPanel());
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

private class AnimatingPanel extends JPanel {
    private static final int DIM_W = 350;
    private static final int DIM_H = 350;
    private static final int INCREMENT = 10;

    private BufferedImage backgroundImage;
    private Image runnerImage;

    private int dx1, dy1, dx2, dy2;
    private int srcx1, srcy1, srcx2, srcy2;
    private int IMAGE_WIDTH;

    public AnimatingPanel() {
        initImages();
        initImagePoints();
        Timer timer = new Timer(40, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                moveBackground();
                repaint();
            }
        });
        timer.start();

        FlowLayout layout = (FlowLayout)getLayout();
        layout.setHgap(0);
        layout.setVgap(0);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.drawImage(backgroundImage, dx1, dy1, dx2, dy2, srcx1, srcy1,
                srcx2, srcy2, this);
        g.drawImage(runnerImage, 0, 0, getWidth(), getHeight(), this);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(350, 350);
    }

    private void initImagePoints() {
        dx1 = 0;
        dy1 = 0;
        dx2 = DIM_W;
        dy2 = DIM_H;
        srcx1 = 0;
        srcy1 = 0;
        srcx2 = DIM_W;
        srcy2 = DIM_H;
    }

    private void initImages() {
        try {
            File icoen = new File("the picture");
            runnerImage = ImageIO.read(icoen);
            File icon = new File("the other one");
            backgroundImage = ImageIO.read(icon);
            IMAGE_WIDTH = backgroundImage.getWidth();
            System.out.println(IMAGE_WIDTH);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void moveBackground() {
        if (srcx1 > IMAGE_WIDTH) {
            srcx1 = 0 - DIM_W;
            srcx2 = 0;
        } else {
            srcx1 += INCREMENT;
            srcx2 += INCREMENT;
        }
    }
}

public static void main(String[] args) {

            new MovingBackgroundDemo();
}
}

有什么建议吗?

这个:

frame.add(button);
frame.add(new AnimatingPanel());

应该是:

JPanel animationPanel = new AnimatingPanel();
animationPanel.add(button);
frame.add(animationPanel);

第一个代码试图将两个组件(按钮和面板)添加到框架中完全相同的布局位置。这行不通(正确地,或者在某些情况下,根本行不通)。