Java 设置JDialog的最大大小?

Java 设置JDialog的最大大小?,java,swing,jdialog,Java,Swing,Jdialog,简短的版本:我需要做一些棘手的事情来让JDialog的setMaximumSize()工作吗 完整版本:我有一个JDialog(布局管理器:BorderLayout),它包含一个滚动窗格,底部有一个带有提交按钮的JPanel 滚动窗格包含一个JPanel,该JPanel在系统的其他地方动态构建 我想要的是对话框围绕JPanel动态地调整自己的大小,直到达到一定的大小,然后开始增长滚动条。这或多或少是默认情况下的情况,但最大大小似乎是我的显示器的大小 我认为这就是继承自java.awt.Compo

简短的版本:我需要做一些棘手的事情来让JDialog的setMaximumSize()工作吗

完整版本:我有一个JDialog(布局管理器:BorderLayout),它包含一个滚动窗格,底部有一个带有提交按钮的JPanel

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

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

我认为这就是继承自java.awt.Component的.setMaximumSize()方法所做的,但是设置它似乎没有任何效果

设置首选大小确实会产生效果,但无论发生什么情况,对话框始终是该大小,这确实不是我想要的

(如果在滚动窗格上设置最大/首选大小属性,效果相同。)


我是否错过了一些非常明显的东西?是否有一些古怪的JDialog/BorderLayout/MaximumSize交互我不知道?

您必须从
JScrollPane
中的JComponents计算
getSize()
,这只是一个简单的例子

编辑:并调用JDialog#pack()

如中所述,某些组件可以提供有关设置视口首选大小的有用信息。
JList
setVisibleRowCount()
方法特别方便,但即使是
getViewport().setPreferredSize(…)
也可能足够了。当然,一个新的计划会有所帮助

附录:作为一个具体的例子,下面的对话框最初的大小为N-2行。当添加更多内容时,对话框将一直增长,直到数字达到N。此时,滚动条开始“增长”。该示例使用了
JList
,但任何组件都应该是可适应的

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();
            }
        });
    }
}
导入java.awt.BorderLayout;
导入java.awt.EventQueue;
导入java.awt.event.ActionEvent;
导入javax.swing.AbstractAction;
导入javax.swing.DefaultListModel;
导入javax.swing.JButton;
导入javax.swing.JDialog;
导入javax.swing.JList;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
/**@见http://stackoverflow.com/questions/5759131 */
公共类列表对话框{
专用静态最终整数N=12;
私有JDialog dlg=newjdialog();
私有DefaultListModel=new DefaultListModel();
专用JList列表=新JList(型号);
私有JScrollPane sp=新JScrollPane(列表);
私人整数计数;
公共列表对话框(){
JPanel面板=新的JPanel();
panel.add(新的JButton(新的抽象操作(“add”){
@凌驾
已执行的公共无效操作(操作事件e){
附加();

如果(count使面板元素可滚动是一种方法。另请参阅Rob的博客(除了已经提供的教程链接Trashgod)

然后:

1) 以对典型内容合理的方式实现getPreferredScrollableViewportSize()(对于JList f.i.来说,这是要显示的首选行数,也称为:visibleRowCount)
2) 为这些“合理条款”实施setter/getter

这一附加层(协调“合理条款”)允许所有协作组件尽其所能提出健壮的大小提示,而不会像setXXSize那样产生不友好的干扰(这是一个禁忌,永远不要忘记那些方法的存在;)

包()导致调整JDialog大小的方法依赖于对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; 
}

我不是你的反对票,但我在这个例子中遇到了问题。每次按下按钮时,对话框似乎都会缩小。@垃圾上帝是的,这是正确的输出,可能有点加密,但我仍然认为不可能为
BorderLayout.CENTER
设置MinSize或MaxSize,否则如果我放置
JScr,它肯定会工作ollPane
到另一个positions/place NOTRH,SOUTH(等),然后从
绝对laoyut
输出很糟糕,只是细节:我不需要声明一些布局管理器如果我要将
JScrollPane
添加到
TopLaoutContainer
,它总是占用
BorderLayout.CENTER
,然后是另一个JComponent(没有使用任何LayoutManager)只是FlowLayoutAh,我现在明白了;不知何故,我错过了
dlg.pack()
。如何确定“特定大小”呢?我下面的答案假设它由面板的内容控制。设置MaximunSize(不要!)没有效果的原因是BorderLayout不尊重最大大小大小“特定大小”基本上是“大到足以容纳所有内容,除非它比屏幕高度的一半高。”这回答了我的另一个问题:我以前从未使用过setMaximumSize()方法,并且对它们不起作用感到有点吃惊。但是-BorderLayout。很高兴知道(现在我又忘了它们的存在)啊哈!实现scrollable正好做到了这一点。出于某种原因,我认为setMaximumSize()会做与getPreferredScrollableViewportSize()相同的事情。(我为什么这么认为?)非常感谢!显示了相应的
删除
按钮。
@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; 
}