2011-04-22 114 views
4

简短版本:我需要做一些棘手的事情来让JDialog的setMaximumSize()工作吗?设置一个JDialog的最大尺寸?

完整版本:我有一个JDialog(布局管理器:BorderLayout的),其中包含与提交按钮底部的滚动面板和一个JPanel。

滚动窗格包含一个在系统中其他地方动态构建的JPanel。

我想要的是让对话框围绕JPanel动态调整自己的大小,直到达到一定的大小,然后开始生长滚动条。这或多或少是默认情况下发生的,除了最大尺寸似乎是我的显示器的尺寸。

以为这是什么.setMaximumSize()方法继承java.awt.Component中没有,但设置它似乎并没有产生任何影响。

设置首选大小确实有效果 - 但随后的对话框始终是大小不管是什么,这真的是不是我想要的。

(和影响是相同的,如果我设置滚动窗格中的最大/首选大小属性。)

我错过了什么巨大明显?是否有一些我不知道的古怪的JDialog/BorderLayout/MaximumSize交互?

+1

是如何形成的 “一定规模” 确定的?我的答案在下面假设它由面板的内容控制。 setMaximunSize(dont-dont-dont!)的原因是没有效果的是BorderLayout不尊重最大尺寸提示 – kleopatra 2011-04-23 10:03:45

+0

“一定大小”基本上“足够大以容纳所有内容,除非它高于大约一半屏幕高度“。这回答了我的另一个问题:我从来没有使用setMaximumSize()方法,并且有些惊讶,他们没有工作。但是 - BorderLayout。很高兴知道。 (现在我要回去忘记它们存在。) – 2011-04-26 17:01:08

回答

5

使面板imlement滚动是方式。又见(除了已经提供的教程链接Trashgod)罗布的博客文章

http://tips4java.wordpress.com/2009/12/20/scrollable-panel/

则:在典型的内容方面合理

1)实施getPreferredScrollableViewportSize()(对于一个JList f.i.多数民众赞成行的首选号码显示,又名:visibleRowCount的)
2)实施制定者/吸气对于那些“合理的条件”

该附加层(coordiates“合理的条件”),允许所有协作组件尽最大努力拿出健壮大小提示,而不作为setXXSize不友好干扰(这是一个无无从未有史以来,简单地忘记这些方法存在;)

+0

AHA!实现可滚动确实做了这个把戏。出于某种原因,我认为setMaximumSize()会和getPreferredScrollableViewportSize()做同样的事情。 (为什么我会这么想?)非常感谢! – 2011-04-26 16:59:13

1

你必须从JComponents计算getSize()JScrollPane只是简单的例子

编辑:和调用的JDialog#包()

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
public class PackDialog { 
    private JDialog dlg; 
    private JScrollPane scrollPane; 
    private JPanel panel; 
    private JButton btn; 

    public PackDialog() { 
     btn = new JButton(); 
     btn.setPreferredSize(new Dimension(300, 30)); 
     btn.addActionListener(new java.awt.event.ActionListener() { 

      @Override 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       btnActionPerformed(evt); 
      } 

      private void btnActionPerformed(ActionEvent evt) { 
       int h = panel.getHeight(); 
       h += btn.getHeight(); 
       int w = panel.getWidth(); 
       dlg.setPreferredSize(new Dimension(w, h)); 
       dlg.pack(); 
      } 
     }); 
     panel = new JPanel(); 
     panel.setPreferredSize(new Dimension(300, 600)); 
     panel.setLayout(new BorderLayout(10, 10)); 
     panel.add(btn, BorderLayout.SOUTH); 
     scrollPane = new JScrollPane(panel); 
     dlg = new JDialog(); 
     dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
     dlg.setPreferredSize(new Dimension(400, 300)); 
     dlg.add(scrollPane); 
     dlg.pack(); 
     dlg.setVisible(true); 
    } 

    public static void main(String[] a_args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       PackDialog pd = new PackDialog(); 
      } 
     }); 
    }} 
+0

我不是你的贬低选民,但我遇到了这个例子的麻烦。每次按下按钮时,它都会缩小对话框。 – trashgod 2011-04-22 21:13:07

+0

@ trashgod是的,这是正确的outPut,也许它是一点点加密,但我仍然认为不可能为'BorderLayout.CENTER'设置MinSize或MaxSize,否则如果我将'JScrollPane'放置到另一个possitions/place NOTRH ,SOUTH(等),然后从'AbsoluteLaoyut'输出结果很糟糕: – mKorbel 2011-04-22 21:32:48

+0

只是细节:如果我将'JScrollPane'添加到'TopLaoutContainer',我不需要声明一些LayoutManager,它总是被占用'BorderLayout.CENTER' ,那么对于另一个JComponent(不使用任何LayoutManager)只有FlowLayout – mKorbel 2011-04-22 21:59:28

9

正如Sizing a Scroll Pane讨论的,一些组件可以提供有关设置的有用信息视口的首选大小。 JListsetVisibleRowCount()方法特别方便,但即使是getViewport().setPreferredSize(…)也可以。当然,sscce会有所帮助。

附录:作为具体的例子,下面的对话框被初始尺寸以具有Ñ -2行。随着越来越多的被添加,该对话框增长,直到数量达到Ñ。那时滚动条开始“增长”。该示例使用JList,但任何Scrollable组件都应该是可适应的。

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import javax.swing.AbstractAction; 
import javax.swing.DefaultListModel; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 

/** @see http://stackoverflow.com/questions/5759131 */ 
public class ListDialog { 

    private static final int N = 12; 
    private JDialog dlg = new JDialog(); 
    private DefaultListModel model = new DefaultListModel(); 
    private JList list = new JList(model); 
    private JScrollPane sp = new JScrollPane(list); 
    private int count; 

    public ListDialog() { 
     JPanel panel = new JPanel(); 
     panel.add(new JButton(new AbstractAction("Add") { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       append(); 
       if (count <= N) { 
        list.setVisibleRowCount(count); 
        dlg.pack(); 
       } 
      } 
     })); 
     for (int i = 0; i < N - 2; i++) { 
      this.append(); 
     } 
     list.setVisibleRowCount(N - 2); 
     dlg.add(sp, BorderLayout.CENTER); 
     dlg.add(panel, BorderLayout.SOUTH); 
     dlg.pack(); 
     dlg.setLocationRelativeTo(null); 
     dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
     dlg.setVisible(true); 
    } 

    private void append() { 
     model.addElement("String " + String.valueOf(++count)); 
     list.ensureIndexIsVisible(count - 1); 
    } 

    public static void main(String[] a_args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ListDialog pd = new ListDialog(); 
      } 
     }); 
    } 
} 
+0

显示相应的“删除”按钮[此处](http://stackoverflow.com/a/11708672/230513)。 – trashgod 2012-07-29 11:02:56

2

到定尺寸从而导致的JDialog的pack()的方法依赖于调用getPreferredSize()来确定要使用的大小。

如果您继承了JDialog,则可以通过继承此方法来强制执行最大大小。

例子:

@Override 
public Dimension getPreferredSize() {  
    int maxWidth=500;  
    int maxHeight=300;  
    Dimension dim=super.getPreferredSize();  
    if (dim.width>maxWidth) dim.width=maxWidth;  
    if (dim.height>maxHeight) dim.height=maxHeight;  
    return dim; 
}