-1

I have this code and I'm trying to add a picture display as a wallpaper in the background. I used this stackoverflow post as a reference but it didn't work. My image is being added to the panel although not as a background. What possibly is the problem?

Side note, .setLocation() isn't updating the location of buttons either. Thanks in advance!

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import net.miginfocom.swing.MigLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.sql.*;
  
  
class APP extends JPanel
{
    JFrame frame = new JFrame();
    JPanel panel;
  
    class ImagePanel extends JComponent {
        Image image;
        public ImagePanel(Image image) {
            this.image = image;
        }
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, 100, 25, this);
        }
    }
  
    public APP(){
  
        JLabel picLabel = new JLabel();
  
  
        try {
            BufferedImage image = ImageIO.read(getClass().getResource("login_bg.jpg"));
            this.setContentPane(new ImagePanel(image));
            picLabel = new JLabel(new ImageIcon(image));
            //picLabel.setBounds(100, 25, 843, 568);
        } catch (IOException e){
            e.printStackTrace();
        }
 
  
        panel = new JPanel();                    // used to do padding like in HTML
        panel.setBorder(BorderFactory.createEmptyBorder(50, 350, 300, 350));
        panel.setLayout(null));
        panel.add(picLabel);
   
   
        frame.add(panel, BorderLayout.CENTER);
        frame.getContentPane();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Drone Delivery");
        frame.pack();
        frame.setVisible(true);
   
    }
   
}
thecow milk
  • 109
  • 11
  • 1
    *pastebin since it is 100+ lines* - the post a proper [mre]. We are not interested in your entire application. It should only take a couple of line to create a frame and a couple more to create a JLabel with an image or do custom painting of the image on a panel. Simplify the problem when attempting to problem solve.. – camickr Mar 13 '21 at 16:25
  • @camickr yes you right, I just updated the code to be more readable – thecow milk Mar 13 '21 at 16:31
  • The code should be posted here. We should be able to copy/paste/compile/test and see the problem described. – camickr Mar 13 '21 at 16:36
  • I will add the reduced code here but it will make the answer long. Here it is. – thecow milk Mar 13 '21 at 16:38
  • 2
    Still not an MRE. 1) the code won't compile. We don't have access to the `GhostText` class. MigLayout is a 3rd party layout and is irrelevant to the stated problem. 2) ActionListener code is irrelevant to the stated problem. As I stated in my first comment you need a JFrame, you custom component added to the frame as a background. And then a single components added to the background component. It always amazes me that people write the entire application before testing. Hint: 1) extend JPanel, not JComponent. 2) you will then need to set the layout manager of the background component. – camickr Mar 13 '21 at 17:07
  • [link]https://anonfiles.com/X6IaS241s7/project_zip well this is all the project.... I know I have the extra lines but it gives you access to other classes. – thecow milk Mar 13 '21 at 17:16
  • 1
    *you were the one who wanted the classes* - no. You were asked for an [mre]. Only code directly related to the problem is included in an "MRE". Everything else is irrelevant. I was giving you examples of code to remove to simplify the problem. – camickr Mar 13 '21 at 17:28
  • @camickr you are right, although im sorry, its first time I do an MRE, I edited the code again to the only base code with frame and panel(and of course the code that im trying to add the background photo). – thecow milk Mar 13 '21 at 17:39
  • One more tip when making an MRE involving images.. 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 Mar 13 '21 at 19:33
  • This question has been cross posted: https://coderanch.com/t/740323/java/image-added-panel-background#3441672 without trying to implement a single suggestion given in my answer. – camickr Mar 14 '21 at 14:29

3 Answers3

2

Still not an MRE, but a little better so I will make more suggestions:

  1. There is no main() method to invoke the code
  2. There is no need to add 5 components to the panel. One component will demonstrate the problem.
  3. In fact you still don't need the panel at all because you still haven't created a JFrame with a background image.

Basic issues with the code:

  1. Your logic is attempting to replace the default content pane, with your custom class that paints an image. As I suggested in a "hint" above, if you want a background image then a) the component should extend JPanel, and b) you need to set the layout manager to BorderLayouut in the constructor of the class. Now you will be able to add child components to the panel.

  2. You have two instance of a JFrame. Your class extends JFrame and in the constructor you create a new instance of the JFrame. Don't extend JFrame.

  3. Your ImagePanel needs to be added to the "frame" created in the constructor.

So the first part of your solution is to simply get this logic working. That is all you need is the JFrame with your ImagePanel added as the content pane of the frame.

Then you move on to the next step.

My image is being added to the panel although not as a background.

Actually it is not added as a background for the reasons given above. What you see is the "JLabel" containing the ImageIcon. Get rid of the label.

//frame.getContentPane().setLayout(new FlowLayout());

The above statement is not needed. You should have already set the layout manager of the "ImagePanel" in the constructor of the class if you followed my hint from above.

frame.add(panel, BorderLayout.CENTER);

Try that and see what happens. You panel will cover the image.

Now try:

    frame.add(panel, BorderLayout.PAGE_START);

and you should see the components at the top of the frame.

You can also add:

panel.setOpaque(false);

and you will see the image below the components.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • I updated the code to a MRE as you requested(i hope i did this time) and second, setting `BorederLayout` would be nice but it won't lay out components as I want so I made the `setLayout(null);` tried your suggestions(changed the code, extended JPanel instead of JFrame, commented some lines) and what I got in my frame are only my text fields(which I didn't include in the code above but this is another topic) and the image still wasn't buffered into frame – thecow milk Mar 14 '21 at 13:59
  • I give up. There is no need for the App class to extend anything. There is no need for the JLabel. There is no need for the JPanel. You completely missed the advice on just getting the background image to display BEFORE moving on the next step of adding components to the background image. If you want more help from me then: 1) delete this question 2) start over by posting a new question on "how to display a background image" and include the [mre] that only does that one thing. – camickr Mar 14 '21 at 14:33
  • how to delete question when there are already answers? If you are a mod please do so – thecow milk Mar 14 '21 at 14:45
1

Theres multipple things wrong with your code, and many bad habits.

  1. setLocation() only has permanent effects once you disable the the Layoutmanager. With panel.add(create_btn); you would need a panel with a LayoutManager that does not do any layouting on the Components. I don't know MigLayout, but as LayoutManagers usually do, they lay out the Components. So whenever any change makes MigLayout to layout the panel's Components, any previous manual changes via setSize/setLocation/setBounds etc are lost.

  2. You re-use the variable "create_btn", you you actually do not add the first one to any panel, thus it will not appear. Best practice:

  • Do not re-use variables
  • Initialize as many components as possible in the field with final. This excludes any Components where initialisation throws Exceptions; however they still should be initialized ASAP and made final if possible
  1. It looks like you're mixing up the Class APP and the standalone frame you create(frame = new JFrame();). You add the image to the APP, but you never display the frame APP. Instead, inside, you create a second Frame "frame", do NOT add any pictures/labels to it, and then display it. So no wonder the image does not get displayed, as it is in the Frame "APP" that never gets displayed.

/UPDATE: If you want to position the items all by yourself, simply add the line panel.setLayout(null);

JayC667
  • 2,418
  • 2
  • 17
  • 31
  • I will make my code to be better but picture actually shows in the frame, just not as a background. I will fix the suggestions and will update – thecow milk Mar 13 '21 at 16:24
  • Check my update regarding setLayout(null) – JayC667 Mar 13 '21 at 16:30
  • I made as many changes as possible but I couldn't do that in the end. When setting the Manager Layout to null it just makes the frame so small and it won't add the panel components. thanks answer, I appreciate that – thecow milk Mar 13 '21 at 18:24
  • It actually does, but you have to set frame size and all component positions/bounds manually – JayC667 Mar 16 '21 at 16:21
1

I suggest you to use JLabel. This component can have a layout and components, and a background image (by using setIcon(ImageIcon icon)) too.

Programmer
  • 803
  • 1
  • 6
  • 13