Положение JFrame изменяется при настройке фона - PullRequest
0 голосов
/ 20 октября 2018

Я учусь использовать макеты в JSwing, и у меня возникли некоторые проблемы при настройке фонового изображения моего JFRame.

Я использую пользовательский класс, который переопределяет paintComponent, чтобы использоватьImageIcon:

import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class ImagePanel extends JPanel {

    private Image image = null;

    public ImagePanel(String filename) {
        this.image = new ImageIcon(filename).getImage();
    }

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

Это мой основной класс:

public ClientGUI() throws IOException {
        instance = this;

        this.setPreferredSize(new Dimension(400, 400));
        this.setResizable(false);
        this.setTitle("ScanIt");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setLayout(new FlowLayout(FlowLayout.CENTER)); 

        ImagePanel panel = new ImagePanel("C:\\barcode_background.jpg");

        BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.Y_AXIS);

        panel.setLayout(boxLayout);

        panel.add(Box.createVerticalStrut(30));

        JLabel lblLogo = new JLabel("Scan-It");
        lblLogo.setOpaque(true);
        lblLogo.setFont(new Font("Tahoma", Font.BOLD, 48));
        panel.add(lblLogo);

        panel.add(Box.createVerticalStrut(50));

        JLabel lblEnter = new JLabel("הכנס ברקוד");
        lblEnter.setOpaque(true);
        lblEnter.setFont(new Font("Tahoma", Font.BOLD, 24));
        panel.add(lblEnter);

        textField = new JTextField(20);
        panel.add(textField);

        JButton btnSearch = new JButton("חפש מוצר");
        btnSearch.addActionListener(new SearchButtonListener());
        panel.add(btnSearch);

        panel.add(Box.createVerticalStrut(30));

        JButton btnAdmin = new JButton("הוסף מוצר");
        btnAdmin.addActionListener(new AdminButtonListener());
        panel.add(btnAdmin);

        this.add(panel, BorderLayout.CENTER);

        this.pack();
        this.setVisible(true);

    }

По какой-то причине размер ImagePanel не совпадает с размером JFrame (как показано здесь: http://prntscr.com/l8d98i). Когда я устанавливаю размер ImagePanel равным размеру JFrame, размер всех моих компонентов изменяется. Почему это так? Как показано здесь: http://prntscr.com/l8d9ka

panel.setPreferredSize(this.getPreferredSize());

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

По какой-то причине размер ImagePanel не совпадает с размером JFrame

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

ВсеКомпоненты Swing отвечают за определение своего собственного размера.Таким образом, вы ДОЛЖНЫ добавить все компоненты в фрейм, а затем использовать:

frame.pack();
frame.setVisible( true );

Это вызовет менеджер компоновки, и теперь размер фрейма будет зависеть от предпочтительного размера компонентов.

Так что проблема с вашим пользовательским компонентом.Вам нужно реализовать метод getPreferredSize(), чтобы вернуть размер вашего изображения.Тогда метод pack () фрейма будет работать правильно.Прочитайте раздел из учебника по Swing по Custom Painting для получения дополнительной информации и рабочих примеров.

this.setPreferredSize(new Dimension(400, 400));

Вы НЕ должны вручную устанавливать предпочтительный размер.Как упоминалось выше, метод pack () вычисляет предпочтительный размер.

panel.setPreferredSize(this.getPreferredSize());

Это также не решение.Рамка содержит строку заголовка и границы, поэтому размер панели НЕ будет соответствовать размеру рамки.Опять же, пусть размер изображения определяет предпочтительный размер кадра.

Если вам нужно, чтобы изображение было определенного размера, используйте Image.getScaledInstance(...) для масштабирования изображения.

Когда я устанавливаю размер ImagePanel равным размеру JFrame, размер всех моих компонентов изменяется.

Фактически, только размеры JTextField изменяются.По какой-то странной причине «максимальная высота» JTextField не ограничена.Для JLabel и JButton максимальная высота является предпочтительной высотой.

Как упоминалось в T67, BoxLayout изменяет размеры компонентов до максимального размера.Хотя, если вы последуете моим советам сверху, вам не нужно об этом беспокоиться.Это будет проблемой только в будущих приложениях, когда размер рамки будет изменен.

Я использую пользовательский класс, который переопределяет paintComponent для использования ImageIcon

Почему высоздать ImageIcon, но не использовать его?Не используйте ImageIcon (...), просто чтобы прочитать изображение.

Вместо этого используйте ImageIO.read(...), чтобы прочитать изображение и избавиться от ImageIcon.Это правильный способ прочитать изображение, и вы получите сообщение об ошибке, если изображение не найдено, что помогает при отладке.

0 голосов
/ 20 октября 2018

Когда BoxLayout размещает компоненты сверху вниз, он пытается определить размер каждого компонента на предпочтительной высоте компонента.Если вертикальное пространство макета не соответствует сумме предпочтительных высот, BoxLayout пытается изменить размеры компонентов, чтобы заполнить пространство.Компоненты либо растут, либо уменьшаются, чтобы заполнить пространство, при этом BoxLayout учитывает минимальный и максимальный размеры каждого из компонентов.Любое дополнительное пространство появляется в нижней части контейнера.

Источник: https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html

Вы можете указать максимальные и минимальные размеры компонентов, используя setMaximumSize() и setMinimumSize().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...