2

I've looked all over and I can only find cases of people using their custom JPannel to draw an image over another image but what I'm trying to do is draw a component over the JPannel and no matter what I try it always moves the JPannel when it draws the next frame. It feels like ther must be a way to override the meathod that draws it on front and allows you to draw it in the very back but there was none that i could find.

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();
}
}

Any tips?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
clivet268
  • 43
  • 1
  • 5
  • 1) For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). In this case, the code needed to have the import statements added, and images hot-linked (see point 2). 2) One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). E.G. The code in [this answer](https://stackoverflow.com/a/10862262/418556) hot links to an image embedded in [this question](https://stackoverflow.com/q/10861852/418556). – Andrew Thompson Jun 23 '21 at 21:09
  • Don't attempt to set the size of the button. The button should always be sized to display the text completely. Your current code will truncate the text of the button. Also, don't use the ComponentListener to set the location of the button. Use an appropriate layout manager. The default FlowLayout, will just center the button at the top of the panel. You could also use a GridBagLyaout to center the button both horizontally and vertically. – camickr Jun 23 '21 at 21:12

1 Answers1

4

This:

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

Should be:

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

The first code is trying to add the two components (button and panel) to the same exact layout position in the frame. That won't work (properly, or in some cases, at all).

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433