1

Full image of my window

The grey border of JFrame visible

Problem:

I want my application to run on full screen (maximized) by default (but the maximum resolution varies by default from laptop to laptop). I am using a background image which scales according to size and width of user's computer on a JPanel. But with the decorations and the resize features "ON" JPanel isn't completely filling the JFrame.

I wanted my application to:

  1. Allow user to resize it as per use and the image to scale along with it
  2. In the maximized view (by default: setExtendedState(JFrame.MAXIMIZED_BOTH);) the image covers the entire JFrame (Note: Happy with any solution that works on all devices with or without using the JFrame.)
  3. My components if possible get resized too

I am using NetBeans, JFrame is in "absolute layout". I tried with JPanel both on absolute layout as well as BorderLayout (not working), tried pack() (also not working), jPanel1.setSize(WIDTH,HEIGHT) with the dimensions of the screen is also not working. Setting JPanels layout to NULL is also not resolving the issue :(

Sign_Up.java (JFrame)

public class Sign_Up extends javax.swing.JFrame {

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    double width = screenSize.getWidth();
    double height = screenSize.getHeight();

    /**
     * Creates new form Sign_Up
     */
    public Sign_Up() {
        initComponents();
        Seticon();
        btnSave.setEnabled(false);//save button
        setExtendedState(JFrame.MAXIMIZED_BOTH);
        //setSize(1920,1080);
        setLocationRelativeTo(null);//makes aligned at center of screen
        //jPanel1.setSize((int)width, (int)height);
        //pack();
    }

PanelScale.java

public class PanelScale extends JPanel {
    Image iconbg;

    public PanelScale() {
        iconbg = new ImageIcon(getClass( ).getResource("/images/largesignup.png")).getImage( );
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D gd = (Graphics2D)g.create();
        gd.drawImage(iconbg, 0, 0, getWidth(), getHeight(), this);
        gd.dispose();
    }
}

Custom Creation Code in JPanel : new Panel.PanelScale();

The only thing that I found working was explicitly stretching the JPanel over the JFrame to some extra height (in NetBeans) but that resulted in my application window not at the center of the screen but shifted to the right.

Stretching the Jpanel Over JFrame to some more height

But when I try to do that using

setsize(new Dimension(width, height+40));

for the JPanel, it doesn't work.

Also I could have done this using JLabel but I want my image to cover the JFrame to full area while working in maximized or resized view on any device (larger or smaller Laptop like 1920x1080 resolution, 1280x720, etc.)

I would be grateful if any solution is provided, even some alternative way with or without JPanel. Even if the application is able to work on Full Screen on any device with the image covering it full I will be satisfied, resizing feature can be sacrificed for the time being

Expected

Abra
  • 19,142
  • 7
  • 29
  • 41
  • Also I don't need to maintain my background image's aspect ratio.. I have no issue if the image is pixelated while resizing it to smaller/larger screens until it is compatible on any device . – kingrishabdugar Jan 02 '23 at 04:23
  • What's wrong with using `BorderLayout` (which is default for `JFrame`)? – MadProgrammer Jan 02 '23 at 06:21

2 Answers2

2

BorderLayout (which is set by default for JFrame) will do exactly what you want automatically, you just then need to resize/position the background based on your needs.

null ("absolute") layouts really aren't a good idea.

Start by taking a look at How to Use BorderLayout. I would also recommend looking at Working with Images and the JavaDocs for Graphics2D which will provide you with the information you need on how to resize the image to your needs

Runnable example...

enter image description here

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new BackgroundPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class BackgroundPane extends JPanel {

        private BufferedImage backgroundImage;

        public BackgroundPane() throws IOException {
            backgroundImage = ImageIO.read(getClass().getResource("/images/Mando01.jpeg"));
        }

        @Override
        public Dimension getPreferredSize() {
            if (backgroundImage == null) {
                return new Dimension(400, 400);
            }
            return new Dimension(backgroundImage.getWidth(), backgroundImage.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (backgroundImage == null) {
                return;
            }
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.drawImage(backgroundImage, 0, 0, getWidth(), getHeight(), this);
            g2d.dispose();
        }

    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 1
    @kingrishabdugar While my solution works, this one is better. I had overlooked the code and missed a key detail when writing my response. However, saying "null layouts really aren't a good idea" is subjective. They might not be the best solution, but there are some instances in which they provide better usage for the developer. It always depends on your purpose. – null Jan 02 '23 at 07:05
  • 1
    @null As you say "subjective", but in 99% of cases when you think you need a `null` layout, you're wrong - the rest of the time, just write a new layout manager – MadProgrammer Jan 02 '23 at 07:09
  • Don't know why after applying Border Layout the buttons and labels are all pushed to the sides and the image is at the center.I was using the Absolute layout before, maybe I must learn how to adjust the buttons , textfields properly using border layout before I can implement it . However for a plain JFrame with only an Image this works quite well as you have shown in the Runnable Example. Again Thanks a lot ! For now @null 's answer works quite well for the time being – kingrishabdugar Jan 02 '23 at 07:10
  • 1
    @kingrishabdugar I'm just using `BorderLayout` for the background image pane. You could apply a different layout manager for the background image pane and add you components to it - you can make use compound layouts (using seperate containers) for more complex layouts. "Absolute" or `null` layouts don't take into account many of the complexities associated GUIs and differences in many different systems. *"For now @null 's answer works quite well for the time being"* - really? Try resizing the window manually – MadProgrammer Jan 02 '23 at 07:14
  • Ohh Ok I got it. Thank you !! This will be quite efficient to use. – kingrishabdugar Jan 02 '23 at 07:18
  • @MadProgrammer really really thankful to you, Your solution worked really awesome ! Lots of Gratitude – kingrishabdugar Jan 03 '23 at 02:46
0

Instead of using JPanel.setSize(), set the LayoutManager of the JFrame to null. Every time the window size is changed, resize the JPanel with the method JPanel.setBounds(0,0,windowWidth,windowHeight). You may have to call the repaint() method to redraw the components on the screen.

// Create a window with a size of 300x200
JFrame frame = new JFrame("Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(300, 200);
frame.setLayout(null);
JPanel panel = new JPanel();
panel.setBounds(0, 0, 300, 200);
panel.setBackground(Color.BLACK);
frame.add(panel);
frame.setVisible(true);
// Resize the window to 600x400
frame.setSize(600, 400);
panel.setBounds(0, 0, 600, 400); // Update panel size
panel.repaint(); // Repaint the components

The result of the code is this: Window with Black Background

If you remove the last two lines of the code, you'll notice that the size does not change.

Window Partially Filled with a Black Background

null
  • 66
  • 9
  • This solution worked like magic. Atleast for my full screen issue. Thanks a lot, However I am unable to upvote due to lack of reputation. Also can you help me about how can I resize my image instead of just scaling it without caring about the aspect ratio ? super.paintComponent(g); Graphics2D gd = (Graphics2D)g.create(); gd.drawImage(iconbg, 0, 0, getWidth(), getHeight(), this); gd.dispose(); – kingrishabdugar Jan 02 '23 at 05:58