Как заставить размер изображения автоматически масштабироваться в соответствии с размером родительского JLabel в Netbeans GUI Builder?

ИСХОДНАЯ ИНФОРМАЦИЯ:- Мне нужно создать графический интерфейс Swing с помощью Netbeans GUI Builder. Первая подзадача — вывести изображение на весь фон.

Я следовал руководству, чтобы сделать это. В основном я создал JFrame, установил для его макета значение GridBagLayout, а затем добавил к нему прозрачный (сняв флажок с непрозрачного свойства) JPanel. (Вопрос 1)

После этого я добавил JLabel в JFrame, удалил его текст и добавил к нему изображение. (Вопрос 2)

ВОПРОСЫ:-

  1. Во-первых, когда я добавляю JPanel, она не показывает дескрипторы изменения размера. Я немного погуглил и нашел это руководство, в котором видно, что при создании JPanel автоматически отображаются маркеры изменения размера, которые можно перетаскивать для изменения размера.

    Но у меня нет (скриншот ниже) Итак, есть ли какое-то свойство или что-то, что можно настроить, чтобы я мог изменить его размер? Потому что моё намерение заключается в использовании этих прозрачных панелей для размещения компонентов (кнопок и т. д.) на заднем плане, поэтому они должны выходить за пределы всего экрана/окна/родителя JFrame. введите здесь описание изображения

  2. Во-вторых, поскольку изображение, которое я использую, имеет размер примерно 1024x768, поэтому оно кажется намного больше, чем его родительские компоненты. введите здесь описание изображения

    Поскольку я нуб, и я не уверен, нужно ли регулировать размер фонового изображения, каким-то образом измеряя ширину и высоту пикселя родителя, а затем преобразовывая фактический размер изображения в этот размер в какой-то программе, такой как Adobe Photoshop. Но я уверен, что должен быть более практичный способ сделать это.

    Я хочу, чтобы размер изображения автоматически изменялся в соответствии с размером родительского элемента, когда он первоначально размещается на родительском объекте JLabel. Как я могу это сделать? Подскажите, пожалуйста, самый простой способ, желательно в GUI Builder.

Я также хочу убедиться, что размер изображения, размер его родительского JLabel, размер JPanel будут подстраиваться под фрейм, когда я изменяю размер окна позже при использовании этого приложения, или если есть способ отключить изменение размера окна. окно полностью.


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                   
}

person Solace    schedule 27.04.2014    source источник
comment
Можете ли вы поделиться кодом, где вы добавили изображение в JLabel   -  person Braj    schedule 27.04.2014
comment
@Брадж Готово! Пожалуйста, смотрите обновление под вопросом.   -  person Solace    schedule 27.04.2014
comment
@ Зара, 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. зачем ты тратишь время?? Вы уже получили ответ вчера, когда задали вопрос (stackoverflow.com/a/23312532/131872). Почему я должен вообще отвечать на ваши вопросы, если вы даже не тратите время на то, чтобы прочитать ответ???   -  person camickr    schedule 27.04.2014
comment
@camickr Мне жаль, если вы так думаете, но, во-первых, этот вопрос сильно отличается от того. Во-вторых, я прочитал, принял и обработал ваш ответ. Пожалуйста, прочитайте мой вопрос еще раз, вы увидите, что я добавил изображение на JLabel (согласно вашему предложению) и пошел по этому пути, столкнулся с проблемами и разместил этот вопрос. Я не думаю, что это означает тратить время других.   -  person Solace    schedule 27.04.2014


Ответы (1)


"или если есть способ полностью отключить изменение размера окна."

Вы можете установить для свойства изменяемого размера фрейма значение false. Из построителя графического интерфейса пользователя NetBeans

  1. Выделите/выберите компонент рамы в представлении проекта или в окне навигатора.
  2. Перейдите в окно свойств справа, найдите свойство resizable и убедитесь, что оно не отмечено.

«Я также хочу убедиться, что размер изображения, размер его родительского JLabel, размер JPanel будут подстраиваться под фрейм, когда я изменяю размер окна»

Один из способов — нарисовать фон на фоновой панели вместо использования метки со значком. Вы можете увидеть пример этого здесь. Для GUI Builder самый простой способ (без необходимости редактировать автоматически сгенерированный код, который я не рекомендую, если вы не знаете, что делаете) — это использовать форму JPanel вместо формы JFrame. Нарисуйте форму JPanel, затем вы можете добавить эту форму JPanel к форме JFrame. Вы можете увидеть здесь простой способ добавить форму JPanel в форму JFrame.


ОБНОВЛЕНИЕ

Таким образом, ваш класс формы JPanel в конечном итоге будет выглядеть примерно так:

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);
            }
        });
    }
}
person Paul Samsotha    schedule 27.04.2014
comment
Огромное спасибо. Я просто попробую сделать это вторым способом из конструктора графического интерфейса, и я надеюсь, что у меня это получится. Не могли бы вы уточнить, означает ли «рисовать в форме JPanel» просто нарисовать изображение в форме JPanel? И будет ли изображение масштабироваться, чтобы соответствовать размеру JPanel? Это большая проблема. Изображение становится намного больше, чем родитель. - person Solace; 27.04.2014
comment
Да, если вы посмотрите ответ, который я связал, вы увидите в методе createBackgroundPanel, где я создаю JPanel, в методе drawImage я передаю ему getWidth() и getHeight(). Это приведет к изменению размера изображения в соответствии с размером панели по мере ее растяжения. - person Paul Samsotha; 27.04.2014
comment
Вы предложили два решения: первое заключалось в том, чтобы манипулировать автоматически сгенерированным кодом (и вы сказали, что не рекомендуете это), поэтому я решил воспользоваться вариантом построения графического интерфейса. Итак, я начал с создания формы JPanel. Затем добавил к нему Jlabel, а затем добавил изображение в JLabel. Я ожидал, что изображение отрегулирует свой размер, но не повезло. Изображение по-прежнему имеет исходный размер, то есть слишком велико. - person Solace; 27.04.2014
comment
Нет, вам нужно раскрасить изображение, используя пользовательскую раскраску. Вот для чего нужен метод paintComponent. Вам не нужна метка или значок изображения. См. мое ОБНОВЛЕНИЕ. Он покажет вам, как должен выглядеть ваш класс формы jpanel. Вам нужно получить BufferedImage, а затем нарисовать его методом paintComponent. Измените путь (к вашему изображению) в моем коде на путь, который есть в вашем коде. - person Paul Samsotha; 27.04.2014
comment
и переопределить getPreferredSize для JPanel - person mKorbel; 27.04.2014
comment
@peeskillet Хорошо, я просто попытаюсь немного прочитать о том, что делают методы в вашем коде. Тогда я буду использовать их в моем. Пожалуйста, подтвердите мне, что это будет служить цели, т.е. (1) компоненты (JPanel и изображение на нем) должны изменить размер себя так, чтобы они прошли весь родительский контейнер (JFrame, к которому я добавлю этот JPanel)? - person Solace; 27.04.2014
comment
Да, это будет. Кроме того, когда вы добавляете форму панели к фрейму фрейма, вам нужно убедиться, что вы установили макет фрейма на BorderLayout и просто добавили панель к фрейму в центр. Вы можете установить макет в инструменте компоновщика, щелкнув правой кнопкой мыши кадр в навигаторе и выбрав Set Layout, затем выберите BorderLayout - person Paul Samsotha; 27.04.2014
comment
@Большое Вам спасибо. Я просто собираюсь попробовать. - person Solace; 27.04.2014
comment
@Zarah Я внес небольшую поправку в приведенный выше код. Вы также захотите переопределить getPreferredSize() формы панели для начального размера, который вы хотите, чтобы рамка отображалась. Автоматически сгенерированный код упакует фрейм, и если вы не переопределите этот метод, ваш фрейм не будет иметь нужного размера. - person Paul Samsotha; 27.04.2014
comment
@peeskillet Спасибо. Я собираюсь попробовать это. - person Solace; 27.04.2014
comment
Я только что создал JPanel и есть вызов метода initComponents() в JPanel constructor, а затем его определение/реализация в сгенерированном коде. Безопасно ли его удалять? Потому что его нет в приведенном примере кода? - person Solace; 27.04.2014
comment
@Zarah Вы можете просто использовать эту панель для добавления своих компонентов, поскольку она будет занимать весь кадр. В противном случае вы не можете удалить реализацию метода. Однако вы можете удалить вызов из конструктора - person Paul Samsotha; 27.04.2014
comment
@peeskillet Я получаю исключение IllegalArgumentException: input==null в этой строке: image = ImageIO.read(getClass().getResource("/gui/resources/blue-and-white-hd.jpg")); - person Solace; 27.04.2014
comment
@Zarah Это означает, что твой путь неверен. Посмотрите на путь в коде, который вы разместили. Я думаю, это тот путь, который вам нужен. Как выглядит файловая структура вашего проекта? - person Paul Samsotha; 27.04.2014
comment
@peeskillet Я попытался изменить путь и думаю, что на этот раз это правильно. Сборка прошла успешно. Но ничего не отображал. Скорее вообще ничего не делал. Я сделал объект класса PanelForm и вызвал для него setVisible(true) из main() - person Solace; 27.04.2014
comment
@Zarah Вы не можете запустить класс панелей без рамки для его удержания. Вы можете сделать это в методе main. См. main в моем ОБНОВЛЕНИИ. Я изменил его. - person Paul Samsotha; 27.04.2014
comment
@peeskillet Я думаю, мне нужно поместить JPanel в JFrame, чтобы он отображался, используя метод, на который вы ссылались, в одном из ваших ответов. Я просто попробую это. - person Solace; 27.04.2014
comment
@Zarah Да, это будет лучший подход. Не забудьте установить макет кадра на BorderLayout. Прочтите мои комментарии, чтобы узнать, как это сделать. Если вы не используете BorderLayout, размер изображения не изменится. - person Paul Samsotha; 27.04.2014
comment
давайте продолжим это обсуждение в чате - person Solace; 27.04.2014
comment
@ Зара, зачем ты тратишь время людей?? Вы уже получили ответ вчера, когда задали вопрос (stackoverflow.com/a/23312532/131872). Почему я должен вообще отвечать на ваши вопросы, если вы даже не тратите время на то, чтобы прочитать ответ??? - person camickr; 27.04.2014
comment
@camickr Я нашел время, чтобы прочитать ваш ответ, и действительно сделал то, что вы предложили! В своем ответе вы дали три варианта. Первый показался мне проще, поэтому я и начал работу. И если вы читали мой вопрос с самого начала, то именно этим я и занимался (поскольку я принял ваше предложение), и вот тут-то и возникли эти проблемы. Я разместил этот вопрос об этих проблемах. Я чрезвычайно благодарен всем, кто отвечает, и я не хочу и не собираюсь тратить ничье время! - person Solace; 27.04.2014
comment
@Zarah, первое казалось проще, поэтому я и начал работу, да, первое было самым простым, исходя из заданного вами вопроса. Но вторые два предложения напрямую решают вашу проблему динамического изменения размера изображения. Так что я не только ответил на ваш первоначальный вопрос, я предвидел будущий вопрос. Значит, у вас уже был ответ ДО того, как вы задали этот вопрос. Поэтому, как только вы осознали дополнительное требование, вы должны были вернуться к предложению из этого ответа. Вы НЕ нашли время, чтобы понять все 3 предложения. - person camickr; 27.04.2014
comment
@camickr Потому что я действительно не был в этом уверен. Я не знал, означает ли динамическое изменение размера изменение размера при размещении на родительском компоненте или когда пользователь меняет размер экрана. Я просто хотел, чтобы это было просто, поэтому я хотел, чтобы JLabel работал, когда я разместил этот вопрос. - person Solace; 27.04.2014
comment
@Зара, Because I was really not sure of it. и so I wanted the JLabel thingy to work - точно. Так ты хоть пробовал StretchIcon перед тем, как запостить этот вопрос??? Это всего лишь одна строка изменения вашего существующего кода, в котором используется JLabel со значком. Идея состоит в том, чтобы сначала попробовать это предложение. Если это работает, отлично. Если нет, то вы задаете уточняющий вопрос. Вы не предполагаете, что это не сработает, не попробовав. Опять же, не пытаясь изменить код одной строкой, вы тратите время каждого человека, который остановился, чтобы прочитать этот вопрос!!! - person camickr; 27.04.2014
comment
@camickr Хорошо, я только что открыл страницу, на которую ссылается StretchIcon, и она выглядит хорошо, я не знаю, почему вчера она показалась мне сложной, мой плохой! Я извиняюсь, и я позабочусь о том, чтобы это больше не повторилось. - person Solace; 27.04.2014