Как позволить JPanel заполнить весь JFrame (в развернутом состоянии) с включенным «Украшением Windows»?

Полное изображение моего окна

Видна серая рамка JFrame

Проблема:

Я хочу, чтобы мое приложение по умолчанию работало в полноэкранном режиме (в развернутом виде) (но максимальное разрешение по умолчанию варьируется от ноутбука к ноутбуку). Я использую фоновое изображение, которое масштабируется в соответствии с размером и шириной компьютера пользователя на JPanel. Но с украшениями и функциями изменения размера «ВКЛ» JPanel не полностью заполняет JFrame.

Я хотел, чтобы мое приложение:

  1. Разрешить пользователю изменять его размер в соответствии с использованием, а изображение масштабироваться вместе с ним.
  2. В развернутом виде (по умолчанию: setExtendedState(JFrame.MAXIMIZED_BOTH);) изображение покрывает весь JFrame (Примечание: подходит любое решение, которое работает на всех устройствах с использованием или без использования JFrame.)
  3. Мои компоненты, если это возможно, тоже будут изменены.

Я использую NetBeans, JFrame находится в «абсолютном макете». Пробовал с JPanel как на абсолютном макете, так и BorderLayout (не работает), пробовал pack() (тоже не работает), jPanel1.setSize(WIDTH,HEIGHT) с размерами экрана тоже не работает. Установка макета JPanels на NULL также не решает проблему :(

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

Пользовательский код создания в JPanel : new Panel.PanelScale();

Единственное, что я нашел работающим, — это явное растяжение JPanel над JFrame на некоторую дополнительную высоту (в NetBeans), но это привело к тому, что окно моего приложения не было в центре экрана, а сместилось вправо.

Растягивание Jpanel поверх JFrame на большую высоту

Но когда я пытаюсь сделать это, используя

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

для JPanel это не работает.

Также я мог бы сделать это с помощью JLabel, но я хочу, чтобы мое изображение покрывало JFrame всю площадь при работе в максимальном или измененном виде на любом устройстве (ноутбук большего или меньшего размера, например разрешение 1920x1080, 1280x720 и т. д.)

Буду признателен, если будет предоставлено какое-либо решение, даже какое-то альтернативное с JPanel или без него. Даже если приложение может работать в полноэкранном режиме на любом устройстве с изображением, покрывающим его полностью, я буду удовлетворен, функцией изменения размера на данный момент можно пожертвовать.

Ожидается

Кроме того, мне не нужно поддерживать соотношение сторон моего фонового изображения. У меня нет проблем, если изображение пикселируется при изменении его размера на меньшие / большие экраны, пока оно не будет совместимо на любом устройстве.

kingrishabdugar 02.01.2023 05:23

Что не так с использованием BorderLayout (по умолчанию для JFrame)?

MadProgrammer 02.01.2023 07:21
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вместо использования JPanel.setSize() установите для LayoutManager JFrame значение null. Каждый раз, когда размер окна изменяется, изменяйте размер JPanel с помощью метода JPanel.setBounds(0,0,windowWidth,windowHeight). Возможно, вам придется вызвать метод repaint(), чтобы перерисовать компоненты на экране.

// 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

Результат кода таков:

Если вы удалите последние две строки кода, вы заметите, что размер не изменился.

Это решение сработало как по волшебству. По крайней мере, для моей полноэкранной проблемы. Большое спасибо, однако я не могу проголосовать из-за отсутствия репутации. Также можете ли вы помочь мне в том, как я могу изменить размер моего изображения, а не просто масштабировать его, не заботясь о соотношении сторон? супер.paintComponent(г); Graphics2D gd = (Graphics2D)g.create(); gd.drawImage(iconbg, 0, 0, getWidth(), getHeight(), this); gd.dispose();

kingrishabdugar 02.01.2023 06:58
Ответ принят как подходящий

BorderLayout (который установлен по умолчанию для JFrame) автоматически сделает именно то, что вы хотите, вам просто нужно изменить размер / положение фона в соответствии с вашими потребностями.

null («абсолютные») макеты на самом деле не очень хорошая идея.

Начните с изучения Как использовать BorderLayout . Я бы также рекомендовал посмотреть Работа с изображениями и JavaDocs for Graphics2D, которые предоставят вам необходимую информацию о том, как изменить размер изображения в соответствии с вашими потребностями.

Запускаемый пример...

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

    }
}

@kingrishabdugar Хотя мое решение работает, это лучше. Я проглядел код и упустил ключевую деталь при написании ответа. Однако высказывание «нулевые макеты на самом деле не очень хорошая идея» субъективно. Они могут быть не лучшим решением, но в некоторых случаях они обеспечивают лучшее использование для разработчика. Это всегда зависит от вашей цели.

null 02.01.2023 08:05

@null Как вы говорите "субъективно", но в 99% случаев, когда вы думаете, что вам нужен макет null, вы ошибаетесь - в остальное время просто пишите новый менеджер макетов 🤣

MadProgrammer 02.01.2023 08:09

Не знаю, почему после применения Border Layout все кнопки и метки сдвинуты в стороны, а изображение находится в центре. Раньше я использовал абсолютный макет, может быть, мне нужно научиться правильно настраивать кнопки и текстовые поля с помощью рамки. прежде чем я смогу это реализовать. Однако для простого JFrame только с изображением это работает очень хорошо, как вы показали в примере Runnable. Еще раз Большое спасибо! На данный момент ответ @null работает достаточно хорошо.

kingrishabdugar 02.01.2023 08:10

@kingrishabdugar Я просто использую BorderLayout для панели фонового изображения. Вы можете применить другой менеджер компоновки для панели фонового изображения и добавить к ней свои компоненты — вы можете использовать составные макеты (используя отдельные контейнеры) для более сложных макетов. «Абсолютные» или null макеты не учитывают многие сложности, связанные с графическим интерфейсом, и различия во многих разных системах. «На данный момент ответ @null работает довольно хорошо» - правда? Попробуйте изменить размер окна вручную

MadProgrammer 02.01.2023 08:14

Ок, понял. Спасибо !! Это будет достаточно эффективно в использовании.

kingrishabdugar 02.01.2023 08:18

@MadProgrammer действительно очень благодарен вам, ваше решение сработало действительно потрясающе! Много благодарности

kingrishabdugar 03.01.2023 03:46

Другие вопросы по теме