2017-06-01 122 views
1

,以防有人将其标记为重复的,我会做我自己:我们有一个非常相对的问题很久以前:摇摆 - 的setResizable(真)使JFrame的标题栏高和窗口大小小

Java setResizable(false) changes the window size (swing)

没有解决方案适用于我。这是我的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更好:

enter image description here

我们可以看到,我们需要在这个例子中的数据。当帧是不可调整大小:

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像素?这是荒谬的。

我已经测试过,没有Nimbus L & F,这是无关紧要的。

这怎么可能和容忍?

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

我们该如何解决?

回答

0

毕竟这是一个外观&感觉问题......

如果我们使用Java默认Metal外观和感觉,并创建两个帧之前设定setDefaultLookAndFeelDecorated(true),边框/ Java默认的插图看&感觉风格将被绘制和可见,因此两个JFrames具有相同的宽度和高度。

我已经打了另一个L & F和发现javax.swing.plaf.nimbus.NimbusLookAndFeelcom.sun.java.swing.plaf.windows.WindowsLookAndFeelcom.sun.java.swing.plaf.motif.MotifLookAndFeel还没有实施这种额外的拖动处理程序,也许对美学的原因。 (我真的怀疑为什么Java默认样式想要绘制这个处理程序,我个人认为它不可信,我认为实施其他Ll也想避免它,所以他们提出了一个可用但很难看的解决方案。)

这个GIF显示了默认金属大号& f怎样描绘了在两个框架调整的“处理”: enter image description here