6

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

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

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

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

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

设置首选大小确实有效果 - 但无论如何,对话框总是那个大小,这真的不是我想要的。

(如果我在滚动窗格上设置最大/首选大小属性,效果是一样的。)

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

4

4 回答 4

9

正如在调整滚动窗格大小中所讨论的,某些组件可以提供有关设置视口首选大小的有用信息。的setVisibleRowCount()方法JList特别方便,但甚至getViewport().setPreferredSize(…)可能就足够了。自然,sscce会有所帮助。

附录:作为一个具体示例,下面的对话框最初的大小为N -2 行。随着更多的添加,对话框会增长,直到数量达到N。此时滚动条开始“增长”。该示例使用 a 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();
            }
        });
    }
}
于 2011-04-22T21:10:39.160 回答
6

使面板实现可滚动是要走的路。另请参阅(除了已经提供的教程链接 Trashgod)Rob 的博客条目

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

然后:

1) 以对典型内容合理的方式实现 getPreferredScrollableViewportSize()(对于要显示的首选行数的 JList fi,即:visibleRowCount)
2)为那些“合理的条款”实现 setter/getter

该附加层(协调“合理条款”)允许所有协作组件尽最大努力提供强大的尺寸提示,而不会像 setXXSize 那样不友好地干扰(这是一个永远不会永远不会发生的事情,只需忘记那些方法存在;)

于 2011-04-23T09:54:37.300 回答
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; 
}
于 2011-06-10T17:39:19.200 回答
1

您必须从简单示例getSize()中的 JComponents计算JScrollPane

编辑:并调用 JDialog#pack()

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();
            }
        });
    }}
于 2011-04-22T19:58:56.780 回答