Определение размера заголовка и границы JFrame в разных графических средах - PullRequest
1 голос
/ 20 апреля 2019

Я пытаюсь визуализировать BufferedImages определенных предопределенных размеров на JPanel, содержащейся в JFrame. Я могу строго определить размер JPanel, но, похоже, что установка размера JFrame устанавливает общую внешнюю область, включая заголовок и границы, и они имеют разные значения в разных графических средах. Установка слишком большого размера оставляет пустое пространство между внешними краями JPanel и внутренними краями JFrame, а установка слишком малого размера приводит к тому, что изображение вообще не будет отображаться.

Есть ли способ определить во время выполнения, сколько дополнительного пространства дополняет размер JFrame, чтобы ничего не произошло? Или есть способ изменить размер JFrame на основе его внутренних границ, а не внешних границ?

Когда размер JPanel равен размеру дисплея, а для extendedState в JFrame задано значение JFrame. MAXIMIZED_BOTH, а для undecorated установлено значение true, проблем нет, но я также хотел бы поддерживать режим оконного отображения, который одинаков для разных графические среды, где я сталкиваюсь с этой проблемой.

Первоначально я пытался использовать константы для заполнения размера JFrame на компьютере, на котором я тестировал код, который работал хорошо, пока я не попытался использовать его на другом компьютере. Запуск одного и того же кода на другом компьютере с другим монитором (хотя и с одинаковым разрешением) привел к появлению лишних пробелов между границами, поэтому кажется, что константы не являются ответом.

Было бы полезно узнать, как Swing определяет размеры этих областей, но до сих пор я не нашел объяснения этому.

1 Ответ

3 голосов
/ 20 апреля 2019

Переопределите JPanel getPreferredSize(), чтобы соответствовать размеру изображения, которое оно содержит, добавьте его в JFrame, а затем вызовите pack() в JFrame после добавления всех компонентов. Пусть Java правильно все изменит для вас.

например.,

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class ImagePanel extends JPanel {
    public static final String IMG_URL_PATH = "https://upload.wikimedia.org/"
            + "wikipedia/commons/thumb/1/1a/" 
            + "WomanFactory1940s.jpg/773px-WomanFactory1940s.jpg";
    private BufferedImage image;

    public ImagePanel(BufferedImage image) {
        this.image = image;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        // if the image isn't null, draw it in the JPanel
        if (image != null) {
            g.drawImage(image, 0, 0, this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        // if either the image is null or the panel's preferred size
        // has been set, then must use the super's value
        if (isPreferredSizeSet() || image == null) {
            return super.getPreferredSize();
        } else {
            // otherwise use the image's size for the panel's pref'd size
            int width = image.getWidth();
            int height = image.getHeight();
            return new Dimension(width, height);
        }
    }

    private static void createAndShowGui(BufferedImage img) {
        ImagePanel mainPanel = new ImagePanel(img);

        JFrame frame = new JFrame("Image Panel Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // first add all components to the JFrame
        frame.getContentPane().add(mainPanel);

        // pack the JFrame to allow it to size all its components and itself
        frame.pack();

        // call this *after* packing only if you want the size fixed
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);

        // then display it
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        try {
            URL imageUrl = new URL(IMG_URL_PATH);
            final BufferedImage img = ImageIO.read(imageUrl);
            SwingUtilities.invokeLater(() -> createAndShowGui(img));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Второй вариант (как указывает camickr) - просто отобразить изображение как ImageIcon в JLabel, который является компонентом, который автоматически устанавливает свой предпочтительный размер в соответствии с размером удерживаемой пиктограммы. Это полезно, если вы не собираетесь использовать изображение в качестве фона для анимации или не хотите иметь изображение с изменяемым размером. Например:

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class ImageDisplay {
    public static final String IMG_URL_PATH = "https://upload.wikimedia.org/"
            + "wikipedia/commons/thumb/1/1a/" 
            + "WomanFactory1940s.jpg/773px-WomanFactory1940s.jpg";

    private static void createAndShowGui() {
        BufferedImage img = null;

        try {
            URL imageUrl = new URL(IMG_URL_PATH);
            img = ImageIO.read(imageUrl);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }
        Icon icon = new ImageIcon(img);
        JLabel label = new JLabel(icon);

        JFrame frame = new JFrame("Image Display");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(label);
        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...