代码之家  ›  专栏  ›  技术社区  ›  Velth

JScrollPane内JPanel上的JTextArea未正确调整大小

  •  9
  • Velth  · 技术社区  · 11 年前

    我想实现以下目标:

    +------------------Other container(s)-----------------+
    |        +------JScrollPane (vertical)-------+        |
    |        | JTextField                        |        |
    |        | Box.createRigidArea (vertical)    |        | 
    |        | JTextArea                         |        |
    |        | { etc.. any other J-component }   |        |
    |        |                                   |        |
    |        |                                   |        |
    |        |                                   |        |
    |        |                                   |        |
    |        +-----------------------------------+        |
    +-----------------------------------------------------+
    

    我能得到的最接近的是以下(伪)代码:

    JPanel container = new JPanel(new BorderLayout());
    JPanel innerContainer = new JPanel();
    innerContainer.setLayout(new BoxLayout(_innerContainer, BoxLayout.Y_AXIS));
    JScrollPane scrollPane = new JScrollPane(innerContainer);
    container.add(scrollPane, BorderLayout.NORTH);
    

    每当我想添加组件时,它们都会添加到内部容器中:

    innerContainer.add(new JTextField());
    innerContainer.add(Box.createRigidArea(new Dimension(0, 10)));
    innerContainer.add(new JTextArea());
    innerContainer.add(Box.createRigidArea(new Dimension(0, 10)));
    innerContainer.add(new JLabel());
    

    我面临以下问题:

    我让布局管理器负责所有UI元素的大小。因此,我最好不要使用任何.setxxSize()-方法。一个JTextArea,被大量文本占据,将使用所有所需的空间(垂直和水平)。这完全没问题。无论何时调整帧的大小,JTextArea都会增长,这仍然很好。但每当我缩小帧时,JTextArea都不会进行相应的调整。因此会出现一个水平滚动条,但我想避免出现这种情况。我希望用户只能垂直滚动。

    有人有什么好的建议吗?谢谢

    编辑:

    SSCCE公司:

    import java.awt.*;
    
    import javax.swing.*;
    
    public class VerticalStackPanel extends JFrame {
    
        public static void main(String[] args) {
            JFrame frame = new VerticalStackPanel();
            frame.setSize(800, 600);
            frame.setVisible(true);
        }
    
        public VerticalStackPanel() {
            super();
    
            JScrollPane scrollPane = new JScrollPane(createVerticalStackPanel());
            scrollPane.getVerticalScrollBar().setUnitIncrement(16);
            scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
            scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    
            getContentPane().add(scrollPane);
        }
    
        private Component createVerticalStackPanel() {
            JPanel container = new JPanel(new BorderLayout());
            container.add(createInnerContainer(), BorderLayout.NORTH);
    
            return container;
        }
    
        private Component createInnerContainer() {
            JPanel innerContainer = new JPanel();
            innerContainer.setLayout(new BoxLayout(innerContainer, BoxLayout.Y_AXIS));
    
            innerContainer.add(createTextArea());
            innerContainer.add(Box.createRigidArea(new Dimension(0, 10)));
            innerContainer.add(createTextArea());
            innerContainer.add(Box.createRigidArea(new Dimension(0, 10)));
            innerContainer.add(createTextArea());
            innerContainer.add(Box.createRigidArea(new Dimension(0, 10)));
            innerContainer.add(createTextArea());
            innerContainer.add(Box.createRigidArea(new Dimension(0, 10)));
            innerContainer.add(createTextArea());
            innerContainer.add(Box.createRigidArea(new Dimension(0, 10)));
            innerContainer.add(createTextArea());
            innerContainer.add(Box.createRigidArea(new Dimension(0, 10)));
    
            return innerContainer;
        }
    
        private Component createTextArea() {
            JTextArea textArea = new JTextArea();
            textArea.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. In vitae diam nunc. Proin vulputate, odio consectetur tincidunt aliquet, metus ipsum rhoncus tellus, in dignissim ligula tortor at risus. Aenean rhoncus lorem a magna luctus molestie. Fusce consequat enim vel quam pharetra varius. Vivamus porta condimentum orci non ultrices. Duis magna arcu, fringilla ut eleifend a, volutpat ac elit. Sed ligula enim, dictum id fringilla vitae, ornare vel nulla. Proin lobortis suscipit lectus eget placerat. Morbi aliquam dolor quis lectus tincidunt eu volutpat risus fermentum. Nunc et sapien a nisl aliquet auctor. Phasellus nec sem tellus, et scelerisque sapien. In a nibh vestibulum velit convallis sodales. Vestibulum tempor fringilla vulputate. Duis hendrerit dolor id urna aliquam cursus auctor enim pulvinar. Nulla rutrum fringilla eros, id congue nisi mattis in. Pellentesque consectetur eleifend mauris, ut aliquam purus convallis ac. Vestibulum pretium, sem at congue faucibus, leo leo volutpat odio, ut feugiat nulla felis a diam. Praesent dignissim eros ac eros semper auctor. Phasellus eu sapien nibh. Quisque pulvinar tristique lectus, quis porttitor purus suscipit sed. Curabitur gravida, ipsum ut vehicula aliquet, erat ipsum tincidunt nulla, eget bibendum felis dolor vel risus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus vitae nisl odio, blandit laoreet nibh.");
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
            return textArea;
        }
    
    }
    

    无论何时水平调整框架大小,只要框架变小,文本就会消失。出现一个水平滚动条,但由于:

    scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    

    文本只是消失了。。JTextArea应进行相应调整

    4 回复  |  直到 11 年前
        1
  •  20
  •   Kylar    11 年前

    好的,所以问题是JPanel不喜欢嵌入到JScrollPane中。

    为了让一个组件能够用JScrollPane“玩得好”,它需要实现Scrollable。 如果您只是在JScrollPane中添加了一个JTextArea,它将完全按照您的期望工作。

    您需要创建一个扩展JPanel并实现Scrollable的小型自定义类,而不是使用JPanel来保存所有JTextArea。

    我已经重新编写了您的示例并将其粘贴到此处: http://pastebin.com/q9x4fv3H 这样你就可以看到所有的代码。可滚动的JPanel应该是这样的:

    private static class ScrollablePanel extends JPanel implements Scrollable{
        public Dimension getPreferredScrollableViewportSize() {
            return super.getPreferredSize(); //tell the JScrollPane that we want to be our 'preferredSize' - but later, we'll say that vertically, it should scroll.
        }
    
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 16;//set to 16 because that's what you had in your code.
        }
    
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 16;//set to 16 because that's what you had set in your code.
        }
    
        public boolean getScrollableTracksViewportWidth() {
            return true;//track the width, and re-size as needed.
        }
    
        public boolean getScrollableTracksViewportHeight() {
            return false; //we don't want to track the height, because we want to scroll vertically.
        }
    }
    

    干杯

        2
  •  1
  •   joey rohan    11 年前

    您应该为您的 scrollPane :

    scrollPane.setViewportView(textArea)
    
        3
  •  0
  •   Mohan Raj B    11 年前

    使用

    txtArea.setWrapStyleWord(true);
    txtArea.setLineWrap(true);
    

    它包装文本并避免水平滚动窗格。

    尝试一下 GridBagLayout. 使用weightx和weighty。它将处理大小调整问题

        4
  •  0
  •   bob    7 年前

    启用换行时,JTextArea从不收缩

    我在一个带有Gridlayout的JPanel中有一个JTextArea有这个问题。我的问题只需设置TextArea的最小大小即可解决。

    textArea.setMinimumSize(new Dimension(20,40));