SetDefaultLookAndFeelDecorated affects JFrame resize behavior

This is my code:

import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class Test{ public static void main(String[] args){ SwingUtilities.invokeLater(new Runnable(){ @Override public void run() { JFrame.setDefaultLookAndFeelDecorated(true); JFrame frame = new JFrame(); JPanel jp = new JPanel(); jp.setMinimumSize(new Dimension(200, 200)); jp.setPreferredSize(new Dimension(200, 200)); //frame.getContentPane().setMinimumSize(new Dimension(200, 200)); //frame.getContentPane().setPreferredSize(new Dimension(200, 200)); frame.getContentPane().add(jp); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } }); } } 

He behaves exactly the way I want. The user can resize the JFrame , but it will always be large enough to hold the 200px x 200px JPanel . But when I delete:

JFrame.setDefaultLookAndFeelDecorated(true);

user can resize JFrame to any size.

Why does the default look and feel affect resize? How can I make it work without setDefaultLookAndFeelDecorated(true) ? I know that I can set the minimum frame size manually ( JFrame#setMinimumSize(new Dimension dim) ), and I will if there is no more sensible solution.

I am using jdk 1.7 for windows 7.

+4
source share
2 answers

This one is used to be a bug, the page talks about working around, for example:

  • override setSize() and verify that the new size is less than desired
  • inside paint(Graphics g) of JFrame check the height and width and "recreate" the frame to a new minimum size

however, the person claims to be fixed because the original example issued for the error suggestion missed the call to setMinimumSize(...) , this is necessary because the JFrame does not provide a minimum size

Here is a snippet that shows that person’s code:

 import java.awt.Dimension; import javax.swing.*; public class JavaApplication118 { private final Dimension m_dim = new Dimension(200, 150); public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new JavaApplication118().createAndShowUI(); } }); } private void createAndShowUI() { // JFrame.setDefaultLookAndFeelDecorated(true); final JFrame frame = new JFrame("Test") { @Override public Dimension getMinimumSize() { return m_dim; } }; frame.setMinimumSize(m_dim); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); initComponents(frame); // frame.setResizable(false); frame.pack(); frame.setVisible(true); } private void initComponents(JFrame frame) { JPanel jp = new JPanel(); jp.setMinimumSize(new Dimension(200, 200)); jp.setPreferredSize(new Dimension(400, 400));//for testing frame.getContentPane().add(jp); } } 

EDIT

Rollback cancels getMinimumSize() , although this seems redundant after calling setMinimumSize(..) , I saved it as such as I found the fragment (I deleted the overridden getPreferredSize() JFrame method that included this fragment).

+4
source

Why does the appearance and appearance of the face affect the resizing?

Since then the window size is under full control of LAF when dragging: mouseHandler set to (fi), MetalRootPaneUI does not resize the window below the minimum returned by LayoutManager. Without setting a minimum frame, you can still reduce its size programmatically.

The only way (unfortunately) to always ensure the minimum window size is to manually set it. Unfortunately, as this involves tracking the dynamic changes of this minimum and, if necessary, updating.

Snippet for playback using (un / comment the defaultDecoration and adjust the frame frame)

 JFrame.setDefaultLookAndFeelDecorated(true); JPanel panel = new JPanel() { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLACK); Dimension m = getMinimumSize(); // visualize the min g.drawRect(0, 0, m.width - 1, m.height -1); } }; // BEWARE: for demonstration only, NEVER do in production code panel.setMinimumSize(new Dimension(400, 400)); panel.setPreferredSize(panel.getMinimumSize()); final JXFrame frame = new JXFrame("", true); Action action = new AbstractAction("resize") { @Override public void actionPerformed(ActionEvent e) { frame.setSize(300, 300); LOG.info("succeeded? " + frame.getSize()); } }; panel.add(new JButton(action)); frame.add(panel); frame.pack(); // set minimum is required to enforce the minimum frame.setMinimumSize(frame.getMinimumSize()); 

Update

Looking back at the source of Window, it turns out that you can have a dynamic minimum-respect respect with automatic magic effect, overriding isMinimumSizeSet ​​and returning true sub-standard:

 final JXFrame frame = new JXFrame("", true) { @Override public boolean isMinimumSizeSet() { return true; } }; ... // no longer needed // frame.setMinimumSize(frame.getMinimumSize()); 

not tested for side effects though

+2
source

Source: https://habr.com/ru/post/1437061/


All Articles