当JFrame未修饰时,GridBagLayout组件会发生变化

时间:2016-04-15 00:56:56

标签: java swing jframe components gridbaglayout

我正在使用GridBagLayout(3x1)来显示我正在制作的程序的登录屏幕。布局及其中的所有内容看起来都很好,以及在JFrame装饰时的假设。无论JFrame是否全屏,一切都会完美调整。

应该是什么样的: What it should look like

问题出在我frame.setUndecorated(true)时。这似乎无缘无故地调整了一些组件的大小。
我检查了所有组件的大小,没有任何变化,只是组件的布局。
我只是想让它看起来它在全屏时的方式相同,因为此应用程序大多数时间都处于全屏状态。为什么要调整大小,我该如何预防呢?提前谢谢。


问题图片: Problem

这是(简明)代码:

package main;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Main {

    public static void main(String[] args) throws Exception {
        JFrame frame = new JFrame();
        frame.getContentPane().add(new MainView());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setSize(900, 900);
        frame.setExtendedState(Frame.MAXIMIZED_BOTH);

        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////
        frame.setUndecorated(true); // Problem is here
        ////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////

        frame.setVisible(true);
    }

}

@SuppressWarnings("serial")
class MainView extends JPanel implements MouseListener {

    private ScalableImage backgroundImage;

    private final JPanel loginPanel;
    private final GridBagConstraints spgbc = new GridBagConstraints();
    private final JLabel loginLabel;
    private final JTextField loginField;
    private final JButton loginButton;

    private final JButton adminButton;

    private final GridBagConstraints gbc;

    private static final double[] colweights = { 1, .5, .05 };
    private static final double[] rowweights = { 1, .5, 0 };

    public MainView() {
        super();

        gbc = new GridBagConstraints();

        setOpaque(false);

        loginPanel = new JPanel();

        loginLabel = new JLabel("<html>&nbsp&nbsp Login to Volunteer Account</html>");

        loginField = new JTextField("Enter ID Here...");
        loginField.setToolTipText("Enter volunteer ID");
        loginField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                loginButton.doClick();
            }
        });

        loginButton = new JButton("Enter");

        adminButton = new JButton("Admin");
        adminButton.setPreferredSize(new Dimension(200, 200));
        adminButton.setToolTipText("Click here if you're an admin");

        layoutView();

        addMouseListener(this);

        revalidate();
    }

    public void layoutView() {
        setLayout(new GridBagLayout());

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weighty = rowweights[0];
        gbc.weightx = colweights[0];
        gbc.fill = GridBagConstraints.BOTH;
        gbc.anchor = GridBagConstraints.CENTER;
        this.add(new JComponent() {
        }, gbc);

        layoutLoginPanel();

        gbc.gridx = 1;
        gbc.weighty = rowweights[1];
        gbc.weightx = colweights[1];
        gbc.gridwidth = 1;
        gbc.gridheight = 3;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.CENTER;
        this.add(loginPanel, gbc);

        gbc.gridx = 2;
        gbc.weighty = rowweights[2];
        gbc.weightx = colweights[2];
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.SOUTHEAST;
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.ipadx = 100;
        gbc.ipady = 100;
        this.add(adminButton, gbc);

        gbc.insets = new Insets(0, 0, 0, 0);
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 3;
        gbc.gridheight = 1;
        gbc.ipadx = 0;
        gbc.ipady = 0;

        Image img = new ImageIcon(
                "C:/Users/akars/Documents/Eclipse Projects/FreeGeek Volunteering/resources/images/freegeek_frontdesk.jpg")
                        .getImage();
        backgroundImage = new ScalableImage(img, false);
        backgroundImage.setOpaque(true);
        this.add(backgroundImage, gbc);

    }

    private void layoutLoginPanel() {
        loginPanel.setLayout(new GridBagLayout());

        spgbc.weightx = 1;
        spgbc.weighty = 0;
        spgbc.gridx = 0;
        spgbc.fill = GridBagConstraints.HORIZONTAL;
        spgbc.insets = new Insets(8, 8, 8, 8);

        spgbc.gridy = 0;
        loginPanel.add(loginLabel, spgbc);

        spgbc.gridy = 1;
        loginPanel.add(loginField, spgbc);

        spgbc.gridy = 2;
        spgbc.fill = GridBagConstraints.NONE;
        spgbc.anchor = GridBagConstraints.EAST;
        spgbc.ipady = 20;
        spgbc.ipadx = 20;
        loginPanel.add(loginButton, spgbc);

        loginPanel.setBorder(BorderFactory.createLineBorder(getDarkerColor(loginPanel.getBackground(), 100), 3, true));
        loginPanel.setOpaque(true);
    }

    public Color getDarkerColor(Color col, int num) {
        return new Color(col.getRed() - num, col.getGreen() - num, col.getBlue() - num);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        MainView.this.grabFocus();
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }
}

class ScalableImage extends JPanel {

    private Image master;
    private boolean toFit;
    private Image scaled;

    public ScalableImage(Image master) {
        this(master, true);
    }

    public ScalableImage(Image master, boolean toFit) {
        this.master = master;
        setToFit(toFit);
    }

    @Override
    public Dimension getPreferredSize() {
        return master == null ? super.getPreferredSize() : new Dimension(master.getWidth(this), master.getHeight(this));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Image toDraw = null;
        if (scaled != null) {
            toDraw = scaled;
        } else if (master != null) {
            toDraw = master;
        }

        if (toDraw != null) {
            int x = (getWidth() - toDraw.getWidth(this)) / 2;
            int y = (getHeight() - toDraw.getHeight(this)) / 2;
            g.drawImage(toDraw, x, y, this);
        }
    }

    @Override
    public void invalidate() {
        generateScaledInstance();
        super.invalidate();
    }

    private boolean isToFit() {
        return toFit;
    }

    private void setToFit(boolean value) {
        if (value != toFit) {
            toFit = value;
            invalidate();
        }
    }

    private void generateScaledInstance() {
        scaled = null;
        if (isToFit()) {
            scaled = getScaledInstanceToFit(master, getSize());
        } else {
            scaled = getScaledInstanceToFill(master, getSize());
        }
    }

    private BufferedImage toBufferedImage(Image master) {
        Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this));
        BufferedImage image = createCompatibleImage(masterSize);
        Graphics2D g2d = image.createGraphics();
        g2d.drawImage(master, 0, 0, this);
        g2d.dispose();
        return image;
    }

    private Image getScaledInstanceToFit(Image master, Dimension size) {
        Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this));
        return getScaledInstance(toBufferedImage(master), getScaleFactorToFit(masterSize, size),
                RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
    }

    private Image getScaledInstanceToFill(Image master, Dimension size) {
        Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this));
        return getScaledInstance(toBufferedImage(master), getScaleFactorToFill(masterSize, size),
                RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
    }

    public Dimension getSizeToFit(Dimension original, Dimension toFit) {
        double factor = getScaleFactorToFit(original, toFit);
        Dimension size = new Dimension(original);
        size.width *= factor;
        size.height *= factor;
        return size;
    }

    public Dimension getSizeToFill(Dimension original, Dimension toFit) {
        double factor = getScaleFactorToFill(original, toFit);
        Dimension size = new Dimension(original);
        size.width *= factor;
        size.height *= factor;
        return size;
    }

    private double getScaleFactor(int iMasterSize, int iTargetSize) {
        return (double) iTargetSize / (double) iMasterSize;
    }

    private double getScaleFactorToFit(Dimension original, Dimension toFit) {
        double dScale = 1d;
        if (original != null && toFit != null) {
            double dScaleWidth = getScaleFactor(original.width, toFit.width);
            double dScaleHeight = getScaleFactor(original.height, toFit.height);
            dScale = Math.min(dScaleHeight, dScaleWidth);
        }
        return dScale;
    }

    private double getScaleFactorToFill(Dimension masterSize, Dimension targetSize) {
        double dScaleWidth = getScaleFactor(masterSize.width, targetSize.width);
        double dScaleHeight = getScaleFactor(masterSize.height, targetSize.height);

        return Math.max(dScaleHeight, dScaleWidth);
    }

    private BufferedImage createCompatibleImage(Dimension size) {
        return createCompatibleImage(size.width, size.height);
    }

    private BufferedImage createCompatibleImage(int width, int height) {
        GraphicsConfiguration gc = getGraphicsConfiguration();
        if (gc == null) {
            gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        }

        BufferedImage image = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        image.coerceData(true);
        return image;
    }

    private BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) {
        BufferedImage imgScale = img;
        int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
        int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);

        if (dScaleFactor <= 1.0d) {
            imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);
        } else {
            imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);
        }

        return imgScale;
    }

    private BufferedImage getScaledDownInstance(BufferedImage img, int targetWidth, int targetHeight, Object hint,
            boolean higherQuality) {

        int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB
                : BufferedImage.TYPE_INT_ARGB;

        BufferedImage ret = img;

        if (targetHeight > 0 || targetWidth > 0) {
            int w, h;
            if (higherQuality) {
                // Use multi-step technique: start with original size, then
                // scale down in multiple passes with drawImage()
                // until the target size is reached
                w = img.getWidth();
                h = img.getHeight();
            } else {
                // Use one-step technique: scale directly from original
                // size to target size with a single drawImage() call
                w = targetWidth;
                h = targetHeight;
            }

            do {
                if (higherQuality && w > targetWidth) {
                    w /= 2;
                    if (w < targetWidth) {
                        w = targetWidth;
                    }
                }
                if (higherQuality && h > targetHeight) {
                    h /= 2;
                    if (h < targetHeight) {
                        h = targetHeight;
                    }
                }

                BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
                Graphics2D g2 = tmp.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
                g2.drawImage(ret, 0, 0, w, h, null);
                g2.dispose();

                ret = tmp;
            } while (w != targetWidth || h != targetHeight);
        } else {
            ret = new BufferedImage(1, 1, type);
        }

        return ret;
    }

    private BufferedImage getScaledUpInstance(BufferedImage img, int targetWidth, int targetHeight, Object hint,
            boolean higherQuality) {

        int type = BufferedImage.TYPE_INT_ARGB;

        BufferedImage ret = img;
        int w, h;
        if (higherQuality) {
            w = img.getWidth();
            h = img.getHeight();
        } else {
            w = targetWidth;
            h = targetHeight;
        }

        do {
            if (higherQuality && w < targetWidth) {
                w *= 2;
                if (w > targetWidth) {
                    w = targetWidth;
                }
            }

            if (higherQuality && h < targetHeight) {
                h *= 2;
                if (h > targetHeight) {
                    h = targetHeight;
                }
            }

            BufferedImage tmp = new BufferedImage(w, h, type);
            Graphics2D g2 = tmp.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            g2.drawImage(ret, 0, 0, w, h, null);
            g2.dispose();

            ret = tmp;
            tmp = null;
        } while (w != targetWidth || h != targetHeight);
        return ret;
    }
}


0 个答案:

没有答案