Swing-setResizable(true)使JFrame标题栏变大而窗口大小变小 [英] Swing - setResizable(true) make JFrame title bar higher and window size smaller

查看:78
本文介绍了Swing-setResizable(true)使JFrame标题栏变大而窗口大小变小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

万一有人将其标记为重复项,我自己动手做:我们很久以前就有一个非常相关的问题:

In case someone marks it as duplicate, I will do it myself: we have a very relative question long before:

Java setResizable(false)会更改窗口大小(摆动)

没有一种解决方案适合我.这是我的SSCCE:

And none solution works for me. Here is my SSCCE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;

public class TitleHeightChange extends JFrame {
    private static final String lp = System.lineSeparator();
    public TitleHeightChange() {
        begin();
    }

    private void begin() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        UIManager.installLookAndFeel("Nimbus", NimbusLookAndFeel.class.getName());


        JFrame frame1 = new JFrame();
        frame1.setTitle("Frame1");
        frame1.setLayout(new BorderLayout());
        JTextArea area1 = new JTextArea();
        area1.setBorder(BorderFactory.createLineBorder(Color.darkGray,1));
        frame1.add(area1, BorderLayout.CENTER);

        frame1.addComponentListener(new ComponentListener() {

            @Override
            public void componentShown(ComponentEvent e) {
                // TODO Auto-generated method stub
                area1.setText("frame height: " + frame1.getBounds().height + lp
                        + "frame width: " + frame1.getBounds().width + lp
                        + "content pane height: " + frame1.getContentPane().getBounds().height + lp
                        + "content pane width: " + frame1.getContentPane().getBounds().width + lp
                        + "title bar height: " + (frame1.getBounds().height-frame1.getContentPane().getBounds().height) + lp
                        + "isResizable() value: false");
            }

            @Override
            public void componentResized(ComponentEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void componentMoved(ComponentEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void componentHidden(ComponentEvent e) {
                // TODO Auto-generated method stub

            }
        });
        frame1.setResizable(false);
        frame1.pack();
        frame1.setBounds(0, 0, 300, 300);
        frame1.setLocationRelativeTo(null);
        frame1.setVisible(true);

        JFrame frame2 = new JFrame();
        frame2.setTitle("Frame2");
        frame2.setLayout(new BorderLayout());
        JTextArea area2 = new JTextArea();
        area2.setBorder(BorderFactory.createLineBorder(Color.darkGray,1));
        frame2.add(area2, BorderLayout.CENTER);

        frame2.addComponentListener(new ComponentListener() {

            @Override
            public void componentShown(ComponentEvent e) {
                // TODO Auto-generated method stub
                area2.setText("frame height: " + frame2.getBounds().height + lp
                        + "frame width: " + frame2.getBounds().width + lp
                        + "content pane height: " + frame2.getContentPane().getBounds().height + lp
                        + "content pane width: " + frame2.getContentPane().getBounds().width + lp
                        + "title bar height: " + (frame2.getBounds().height-frame2.getContentPane().getBounds().height) + lp
                        + "isResizable() value: true");
            }

            @Override
            public void componentResized(ComponentEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void componentMoved(ComponentEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void componentHidden(ComponentEvent e) {
                // TODO Auto-generated method stub

            }
        });
        frame2.setResizable(true);
        frame2.pack();
        frame2.setBounds(0, 0, 300, 300);
        frame2.setLocationRelativeTo(null);
        frame2.setVisible(false);

        setLayout(new BorderLayout());
        JButton b = new JButton();
        b.setText("switch");
        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                if (frame1.isVisible()) {
                    frame1.setVisible(false);
                    frame2.setVisible(true);
                } else {
                    frame1.setVisible(true);
                    frame2.setVisible(false);
                }
            }
        });
        b.setBounds(0, 0, 100, 30);
        add(b, BorderLayout.CENTER);

        pack();
        setBounds(600, 700, 100, 30);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                TitleHeightChange frame = new TitleHeightChange();

            }

        });
    }
}

我注意到不仅窗口改变了大小,标题栏也改变了高度.此GIF可以更好地说明这一点:

I notice that not only the windows changes size, but the title bar also changes height. It is illustrated better with this GIF:

在此示例中,我们可以看到所需的所有数据.当框架无法调整大小时:

We can see all the data we need in this example. When the frame is not resizable:

frame height: 300
frame width: 300
content pane height: 274
content pane width: 294
title bar height: 26
isResizable() value: false

当框架可调整大小时:

frame height: 300
frame width: 300
content pane height: 264
content pane width: 284
title bar height: 36
isResizable() value: true

因此,当一个框架设置为不可调整大小时,其内容窗格将添加一个(5、5、5、5)插图,并保持JFrame的总大小,标题栏缩小了10个像素? ???这很荒谬.

So when a frame is set to be not resizable, its content pane will add an insets of (5, 5, 5, 5), and to maintain the total size of the JFrame, the title bar is shrinked 10 pixels???? This is absurd.

我在有和没有Nimbus L&F的情况下都进行了测试,这是无关紧要的.

I have tested with and without Nimbus L&F, it is irrelevant.

怎么可能和被容忍?

我找到的解决方案是,当我们在pack()之后的setBounds()处,在可调整大小的窗口中添加10个像素.但这很丑陋,并且不会阻止标题栏增加.

The solution I found, is when we setBounds() after pack(), add 10 pixels at the window which is resizable. But this is ugly, and it does not prevent the title bar to increase.

我们如何解决这个问题?

How can we solve this?

推荐答案

毕竟是外观&感觉问题......

After all it is a Look & Feel problem......

如果我们使用Java默认的Metal外观,并在创建两个框架之前设置setDefaultLookAndFeelDecorated(true),则Java默认外观的边框/插入&感觉样式将被绘制并可见,因此,两个JFrame具有相同的宽度和高度.

If we use Java default Metal look and feel, and set setDefaultLookAndFeelDecorated(true) before creating both frames, the border/insets of Java default look & feel style will be painted and visible, thus two JFrames have same width and height.

我曾与其他L& F一起玩过,发现javax.swing.plaf.nimbus.NimbusLookAndFeelcom.sun.java.swing.plaf.windows.WindowsLookAndFeelcom.sun.java.swing.plaf.motif.MotifLookAndFeel可能没有实现这种额外的拖动处理程序,可能是出于审美原因. (我真的怀疑为什么Java默认样式想要绘制此处理程序.我个人认为这不是难以理解的.我认为实现另一个L&F的ppl也希望避免使用它,因此他们提出了一个可用的但难看的解决方案.)

I have played with other L&F and find that javax.swing.plaf.nimbus.NimbusLookAndFeel, com.sun.java.swing.plaf.windows.WindowsLookAndFeel and com.sun.java.swing.plaf.motif.MotifLookAndFeel haven't implemented this extra dragging handler, maybe for aesthetic reasons. (I really doubt that why Java default style wanted to paint this handler. I personally don't think it's imprescindible. I think ppl implementing the other L&F also wanted to avoid it so they came up with a usable but ugly solution. )

此GIF向您显示默认的Metal L& F如何在两个框架中绘制尺寸调整的句柄":

This GIF shows you how the default Metal L&F paints the "handle" of resizing in both frames:

这篇关于Swing-setResizable(true)使JFrame标题栏变大而窗口大小变小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆