【问题标题】:Fill horizontal but scroll vertical水平填充但垂直滚动
【发布时间】:2013-11-28 12:51:30
【问题描述】:

我的JFrame 看起来像这样:

当它调整大小时,它会使JComboBoxes适应JFrame的大小,如下所示:

这就是我想要的。但是当我添加JScrollPane 时,JComboBoxes 不再适应:

任何想法如何使 JComboBoxes 仍然用添加的JScrollPane 填充水平?(使JScrollPane 只影响垂直滚动)

public class FillHorizonScrollVertical extends JFrame {

    private boolean withScroller = true;
    private JPanel content;

    public FillHorizonScrollVertical() {

        // FILL = BOTH for JFrame
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 1;
        c.weighty = 1;
        this.setLayout(new GridBagLayout());

        // GridLayout = All content gets the same size
        content = new JPanel(new GridLayout());

        // ADD TO THE FRAME
        JScrollPane scroller = new JScrollPane(content);
        if (withScroller)
            this.add(scroller, c);
        else
            this.add(content, c);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        // ADDING THE BOXES AFTER SETTING VISIBLE
        addBoxes();
        this.pack();
    }

    /**
     * Create JComboBoxes and adding them to the JPanel
     */
    private void addBoxes() {

        // CREATE JCOMBOBOXES
        JComboBox cb1 = new JComboBox();
        cb1.addItem("");
        cb1.addItem("aaaaaaaaaaaaaaaaaa");

        JComboBox cb2 = new JComboBox();
        cb2.addItem("");

        JComboBox cb3 = new JComboBox();
        cb3.addItem("");

        content.add(cb1);
        content.add(cb2);
        content.add(cb3);
    }

    public static void main(String[] args) {
        new FillHorizonScrollVertical();
    }
}

【问题讨论】:

  • WRF 你的问题我认为你不能这样做。如果存在垂直滚动条,它将垂直滚动。
  • 如果是这样:JScrollPane 扩展了 JComponent。难道不能以某种方式@override setHorizo​​ntalScrollBar() 吗?..
  • 不添加 JComboBoxes(addBoxes()),而是替换为:JTextArea area = new JTextArea(); area.setPreferredSize(新维度(200, 200));内容。添加(区域);。这将使 JFrame 填充水平并垂直滚动。但不要设法用​​ JComboBoxes 做同样的事情。
  • 您的用例完全模棱两可。如果您希望组合框适应调整大小的窗口,使用JScrollPane 有什么意义?
  • 如问题中所述,我希望 JScrollPane 仅滚动垂直而不滚动水平。即:填充水平而不是垂直。

标签: java swing layout jscrollpane gridbaglayout


【解决方案1】:

您可以在JScrollPane上设置滚动策略

JScrollPane scroller = new JScrollPane(content, 
    ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

您可能还想查看Scrollable 界面,它允许微调滚动行为。

【讨论】:

  • 这不会使内容宽度适应 JFrame 大小。
【解决方案2】:

通过添加解决:

cb1.setPreferredSize(new Dimension(0, 30));
cb2.setPreferredSize(new Dimension(0, 30));
cb3.setPreferredSize(new Dimension(0, 30));

【讨论】:

  • 感谢您指出这一点。我的问题是 JComboBox 的preferedWidth 太宽了。这迫使我重新设置似乎非常不推荐的宽度。据我了解:正确使用的布局管理器是不更改 PreferredSize 的解决方案。不幸的是,我看不到任何布局管理器来帮助我解决我遇到的问题。
【解决方案3】:

您使用Scrollable 接口,它允许您标记它应该跟踪视口的宽度或高度。在这种情况下,您要跟踪宽度,这将强制视图始终与视口大小相同...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Rectangle;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ScrollableExample {

    public static void main(String[] args) {
        new ScrollableExample();
    }

    public ScrollableExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(new TestPane()));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements Scrollable {

        public TestPane() {
            setLayout(new GridLayout());
            JComboBox cb1 = new JComboBox();
            cb1.addItem("");
            cb1.addItem("aaaaaaaaaaaaaaaaaa");

            JComboBox cb2 = new JComboBox();
            cb2.addItem("");

            JComboBox cb3 = new JComboBox();
            cb3.addItem("");

            add(cb1);
            add(cb2);
            add(cb3);
        }

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

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return getPreferredSize();
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 32;
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 32;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            return true;
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            return false;
        }

    }

}

查看How to use scroll panes了解更多详情

【讨论】:

  • +1,您也可以尝试使用Scrollable Panel,它有一个简单的API,可以让您控制滚动行为。您似乎想使用 FIT 作为宽度提示。
猜你喜欢
  • 2016-05-28
  • 1970-01-01
  • 2014-05-05
  • 2021-11-13
  • 2014-01-09
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
  • 1970-01-01
相关资源
最近更新 更多