2011-05-10 40 views
3

我在我的自定义JComponent中覆盖了getPreferredSize()和getMinimumSize()。虽然getPreferredSize()按预期工作,但getMinimumSize()会被忽略,因为我可以调整JFrame的大小直到我的自定义组件消失。为什么?如何避免它?Java自定义JComponent:为什么getMinimumSize()被忽略?

这是一个完整的可运行程序,显示了我的观点。我究竟做错了什么?

Main.java

package swing.minimumsize; 

    import javax.swing.JFrame; 

    @SuppressWarnings("serial") 
    public class Main extends JFrame { 

     public Main() { 
      setTitle("Custom Component Test"); 
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     } 

     public void display() { 
      add(new CustomComponent()); 
      pack(); 
      setVisible(true); 
     } 

     /** 
     * @param args 
     */ 
     public static void main(String[] args) { 
      Main main = new Main(); 
      main.display(); 
     } 

    } 

CustomComponent.java

package swing.minimumsize; 

    import java.awt.Color; 
    import java.awt.Dimension; 
    import java.awt.Graphics; 

    import javax.swing.JComponent; 

    @SuppressWarnings("serial") 
    public class CustomComponent extends JComponent { 

     @Override 
     public Dimension getMinimumSize() { 
      return new Dimension(100, 100); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      int margin = 10; 
      Dimension dim = getSize(); 
      super.paintComponent(g); 
      g.setColor(Color.red); 
      g.fillRect(margin, margin, dim.width-margin*2, dim.height-margin*2); 
     } 

    } 
+2

JFrame的默认布局是BorderLayout,默认位置是CENTER。 – trashgod 2011-05-10 03:24:02

+1

另外,请考虑使用'setBorder(BorderFactory.create ...)'。 – trashgod 2011-05-10 03:56:29

回答

4

..getMinimumSize(),因为我能,而不是被忽略调整JFrame的大小直到我的自定义组件消失。为什么?如何避免它?

查看第一条评论。

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 

public class Main extends JFrame { 

    public Main() { 
     setTitle("Custom Component Test"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    public void display() { 
     add(new CustomComponent()); 
     pack(); 
     // enforces the minimum size of both frame and component 
     setMinimumSize(getSize()); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     Main main = new Main(); 
     main.display(); 
    } 
} 

class CustomComponent extends JComponent { 

    CustomComponent() { 
     setBackground(Color.YELLOW); 
    } 

    @Override 
    public Dimension getMinimumSize() { 
     return new Dimension(100, 100); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(200, 200); 
    } 

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

     // paint the BG. 
     g.setColor(getBackground()); 
     g.fillRect(0,0,getWidth(),getHeight()); 

     int margin = 10; 
     Dimension dim = getSize(); 

     g.setColor(Color.red); 
     g.fillRect(margin, margin, dim.width-margin*2, dim.height-margin*2); 
    } 
} 
+0

我接受这个答案,因为它解决了实际问题。不过,我还要感谢气垫船Full Of Eels解释为什么我的代码没有按预期工作。 – stivlo 2011-05-10 04:17:36

4

什么被忽略或听取将取决于持有JComponent的容器的布局。由于您将您的comopnent添加到JFrame BorderLayout.CENTER,因此setMinimumSize将被忽略是有意义的。

+1

基于@camickr的建议,添加'this.setLayout(new BoxLayout(this.getContentPane(),BoxLayout.X_AXIS))'并水平缩小将使最小尺寸更容易看清。 – trashgod 2011-05-10 03:42:14

+0

为什么它有道理? – stivlo 2011-05-10 03:46:35

+0

@stivlo:因为BorderLayout不使用包含组件的minimumSize来确定组件的大小。 – 2011-05-10 03:48:27

2

首选,最小和最大尺寸只是布局管理器布置组件时可以使用或忽略的“建议”。

编辑:

除了安德鲁的建议,你可以尝试使用,尊重的最小尺寸布局管理器:

Container contentPane = getContentPane(); 
    contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.X_AXIS)); 
    add(new CustomComponent()); 
    pack(); 
    setMinimumSize(getMinimumSize()); 
    setVisible(true); 
相关问题