2

BACKGROUND:- I am required to make a Swing GUI using Netbeans GUI Builder. The first sub-task is to display an image in the entire background.

I have followed a tutorial to get that done. I have basically made a JFrame, set its layout to GridBagLayout and then added a transparent (by unchecking the opaque property) JPanel to it. (Question 1)

After that I added a JLabel to the JFrame, Removed its text and added an image to it. (Question 2)

QUESTIONS:-

  1. First, when I add the JPanel, it does not show its resize handles. I Googled a bit and found this tutorial, in which it can be seen that when they create a JPanel, it automatically shows its resize handles, which can be dragged to resize it.

    But mine doesn't (screenshot below) So is there some property or something which can be adjusted so that I can resize it? Because my intention is to use this transparent panels to contain components (buttons etc.) on the background, so it should elapse the entire screen/window/JFrame parent. enter image description here

  2. Second, since the image I am using has some 1024x768 dimensions, so it appears to be way bigger than its parent components. enter image description here

    Since I am a noob and I am not sure if the size of the background image needs to be adjusted by somehow measuring the pixel width and pixel height of the parent and then converting the actual image's size to that size in some program like Adobe Photoshop. But I am sure there must a more practical way to do that.

    I want the image to automatically resize itself according to the size of the parent when it is initially placed on on its parent JLabel. How can I do that? Please tell me the easiest way, preferably in the GUI Builder.

I also want to ensure that the image size, its parent JLabel's size, JPanel's size will all adjust to the frame when the I change the size of the window later when using this application, or if there is a way to disable the sizing of the window completely.


EDIT1 @Braj

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.dev_nna.dbp;


public class JFrameParent extends javax.swing.JFrame {

    /**
     * Creates new form JFrameParent
     */
    public JFrameParent() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new java.awt.GridBagLayout());

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );

        getContentPane().add(jPanel1, new java.awt.GridBagConstraints());

        jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/dev_nna/dbp/scheduler/resources/Abstract-white-and-blue-backgrounds.jpg"))); // NOI18N
        jLabel1.setText("jLabel1");
        getContentPane().add(jLabel1, new java.awt.GridBagConstraints());

        pack();
    }// </editor-fold>                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(JFrameParent.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(JFrameParent.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(JFrameParent.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(JFrameParent.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new JFrameParent().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration                   
}
Solace
  • 8,612
  • 22
  • 95
  • 183
  • Can you share the code where you have added an image to `JLabel` – Braj Apr 27 '14 at 11:05
  • @Braj Done! Please see the update under the question. – Solace Apr 27 '14 at 11:21
  • @Zarah, `I want the image to automatically resize itself according to the size of the parent when it is initially placed on on its parent JLabel.` why are you wasting peoples time?? You already got the answer yesterday when you asked a question (http://stackoverflow.com/a/23312532/131872). Why should I even bother to answer your questions when you don't take the time to even read the answer??? – camickr Apr 27 '14 at 15:25
  • @camickr I am sorry if you think so, but, First, this question is very much different from that one. Second, I had read, accepted and worked your answer. Please read my question again, you'll see that I had added the image on the JLabel(as per your suggestion) and was going that way, faced problems, and posted this question. I don't think that means wasting time of others. – Solace Apr 27 '14 at 15:46

1 Answers1

2

" or if there is a way to disable the sizing of the window completely."

You can set the resizable property of the frame to false. From NetBeans GUI Builder

  1. Highlight/select the frame component from the design view, or from the navigator window.
  2. Go to the properties window on the right and look for the property resizable and make sure it's unchecked

"I also want to ensure that the image size, its parent JLabel's size, JPanel's size will all adjust to the frame when the I change the size of the window"

One way is to paint the background onto the background panel, instead of using a label with an icon. You can see an example of that here. For the GUI Builder, the easiest way (without having to edit the auto-generated code, which I don't recommend, if you don't know what you are doing) is to use a JPanel form instead of a JFrame form. Paint on the JPanel form, then you can add that JPanel form to the JFrame form. You can see here for an easy way to add the JPanel form to the JFrame form.


UPDATE

So your JPanel form class will ultimately look something like this

public class PanelForm extends javax.swing.JPanel {
    private BufferedImage image;

    public PanelForm() {
        try {
            image = ImageIO.read(getClass().getResource("/path/to/image/png"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }  
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
    }

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

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new PanelForm());     //  <--- add it here
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Thank you so very much. I'll just try to do it in the second way from the GUI builder, and I hope I succeed in that. Can you please clarify if '"paint" on the JPanel form' means just draw the image on the JPanel form? And will the image scale itself to match the JPanel's size? That is a major problem. The image becomes much bigger than the parent. – Solace Apr 27 '14 at 11:42
  • Yes, if you look in the answer I linked, you will see in the `createBackgroundPanel` method where I create the `JPanel`, in the `drawImage` method, I pass to it `getWidth()` and `getHeight()`. That will make the image resize to the size of the panel as it is being stretched. – Paul Samsotha Apr 27 '14 at 11:46
  • You suggested two solutions: First one was to manipulate the auto-generated code (and you said you wouldn't recommend that), so I decided to take up the GUI builder option. So I started by creating a JPanel form. Then added a Jlabel to it and then added an image to the JLabel. I expected the image to adjust its size but no such luck. The image is still its original size, that is way too big. – Solace Apr 27 '14 at 12:11
  • No, you need to paint the image, using custom painting. That's what the `paintComponent` method is for. You don't need the label or the image icon. See my **UPDATE**. It'll show you how your jpanel form class should somewhat look like. You need to obtain a `BufferedImage`, then paint it in the `paintComponent` method. Change the path (to your image) in my code with the path that is in your code. – Paul Samsotha Apr 27 '14 at 12:13
  • 1
    and by override getPreferredSize for JPanel – mKorbel Apr 27 '14 at 12:26
  • @peeskillet OK, I'll just try to read up a bit on what the methods are doing in your code. Then I'll use them in mine. Please confirm me that it will serve the purpose i.e. (1) the components (JPanel, and the image on it) should resize themselves such that they will elapse the entire parent container (the JFrame to which I'll add this JPanel) ? – Solace Apr 27 '14 at 12:27
  • Yes it will. Also when you do add the panel form to the frame frame, you need to make sure you set the layout of the frame to `BorderLayout` and just add the panel to frame to the center. You can set the layout in the builder tool by right-clicking on the frame in the navigator and select `Set Layout` then select `BorderLayout` – Paul Samsotha Apr 27 '14 at 12:29
  • @Thank you very much. I am just going to try it. – Solace Apr 27 '14 at 12:39
  • 1
    @Zarah I have made one slight adjustment to the code above. You will also want to override `getPreferredSize()` of the panel form, for the initial size of you want the frame to appear. The auto-generated code will pack the frame, and it you don't override that method, your frame will not appear the size you want. – Paul Samsotha Apr 27 '14 at 12:44
  • @peeskillet Thank you. I am going to try it. – Solace Apr 27 '14 at 12:46
  • I have just created the `JPanel` and there is a call to a method `initComponents()` in the `JPanel constructor`, and then its definition/implementation in the generated code. Is it safe to remove it? Because it is not present in the sample code provided? – Solace Apr 27 '14 at 13:02
  • 1
    @Zarah You can just use that panel to add your components, since it _is_ going to take up the entire frame. Other wise, you cannot remove method implementation. You can however remove the call from the constructor – Paul Samsotha Apr 27 '14 at 13:04
  • @peeskillet I am getting an "IllegalArgumentException: input==null" at this line: `image = ImageIO.read(getClass().getResource("/gui/resources/blue-and-white-hd.jpg"));` – Solace Apr 27 '14 at 13:46
  • @Zarah It means your path is wrong. Look at the path in the code you posted. I think that's the path you want. What does your project file structure look like? – Paul Samsotha Apr 27 '14 at 13:56
  • @peeskillet I tried changing the path and I think it is correct this time.. The build was successful. But it did not display anything. Rather it did not do anything at all. I did make an object of the PanelForm class and call the setVisible(true) on it from the main() – Solace Apr 27 '14 at 14:29
  • @Zarah You cannot run a panel class without a frame to hold it. You can do that in the `main` method. See the `main` in my **UPDATE**. I modified it. – Paul Samsotha Apr 27 '14 at 14:37
  • @peeskillet I think I have to put the JPanel on the JFrame in order to make it displayed, using the method you had linked to, in one of your answers. I'll just try that. – Solace Apr 27 '14 at 14:38
  • @Zarah Yes that will be the better approach. Remember to set the layout of the frame to `BorderLayout`. Read over my comments to see how to do that. If you don't use the `BorderLayout`, the image won't resize – Paul Samsotha Apr 27 '14 at 14:45
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/51537/discussion-between-zarah-and-peeskillet) – Solace Apr 27 '14 at 14:49
  • @Zarah, why are you wasting peoples time?? You already got the answer yesterday when you asked a question (http://stackoverflow.com/a/23312532/131872). Why should I even bother to answer your questions when you don't take the time to even read the answer??? – camickr Apr 27 '14 at 15:24
  • @camickr I did take out time to read your answer and indeed did what you had suggested! In your answer, you gave three options. The first one seemed simpler, so that was where I started work. And if you read my question from the start, that's exactly what I was doing (as I had taken your suggestion), and that's where these problems arose. I posted this question about those problems. I am extremely thankful to everybody who answers, and I do not want or mean to waste anybody's time! – Solace Apr 27 '14 at 15:32
  • @Zarah, The first one seemed simpler, so that was where I started work yes the first was the simplest based on the question you asked. But the second two suggestions directly address your issue of dynamically resizing the image. So not only did I answer your initial question, I anticipated a future question. So you already had the answer BEFORE you asked this question. So once you realized the additional requirement you should have revisited the suggestsion from that answer. You did NOT take the time to understand all 3 suggestions. – camickr Apr 27 '14 at 15:47
  • @camickr Because I was really not sure of it. I did not know if by dynamic resizing meant resizing when placed on a parent component or when the user changes the size of the screen. I just wanted it to be simple, so I wanted the JLabel thingy to work, when I posted this question. – Solace Apr 27 '14 at 15:53
  • @Zarah, `Because I was really not sure of it.` and `so I wanted the JLabel thingy to work` - exactly. So did you even try the `StretchIcon` before you posted this question??? It is only a one line change to your existing code that used a JLabel with an Icon. The idea is to try the suggestion first. If it works, great. If not, then you ask a follow up question. You don't assume it won't work without trying it. Again, by not trying a one line code change you are wasting the time of every person that stopped to read this question!!! – camickr Apr 27 '14 at 15:57
  • @camickr OK, I just opened the page linked to by StretchIcon and it looks good, I don't know why I found it complex yesterday, my bad! I apologise, and I will make sure it does not happen again. – Solace Apr 27 '14 at 17:06