JTextArea中对里面的JPanel JScrollPane的不正常调整 [英] JTextArea on JPanel inside JScrollPane does not resize properly

查看:403
本文介绍了JTextArea中对里面的JPanel JScrollPane的不正常调整的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现如下:

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

我能够得到最接近的是用下面的(伪)code:

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);

每当我想添加组件它们添加到内部容器:

Whenever I'd like to add components they're added to the inner container:

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元素大小的照顾。所以preferable我不使用任何.setxxSize() - 方法。一个JTextArea中,有很多文字的占用,将使用所有必需的空间(水平和垂直)。这完全是罚款。每当帧大小JTextArea中将会增长,这仍然是完全的罚款。但每当我缩小框架,JTextArea中并没有相应的调整。因此,水平滚动条出现,但是这个我想避免的。我希望用户只垂直滚动。

I let the layout managers take care of all UI element size. So preferable I do not use any .setxxSize()-method. A JTextArea, occupied with alot of text, will use all the required space (vertical and horizontal). Which is totally fine. Whenever the frame is resized the JTextArea will grow, which is still totally fine. But whenever I shrink the frame, the JTextArea does not adjust accordingly. Therefore a horizontal scrollbar appears, but this I'd like to avoid. I want users only to scroll vertically.

有没有人有一些好的建议?谢谢!

Does anyone have some good tips? Thanks!

编辑:

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;
    }

}

当你水平调整框架,文本将每当框架变得不那么大dissapear。一个水平滚动条出现,但因为:

Whenever you'll resize the frame horizontally, text will dissapear whenever the frame becomes less big. A horizontal scrollbar appears, but since:

scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

文字只是自败.. JTextArea中应相应调整

Text just dissapears.. the JTextArea should adjust accordingly

推荐答案

好了,问题是,JPanel的不喜欢被嵌入JScrollPane中。

Ok, so the issue is that JPanel does not like to be embedded into a JScrollPane.

为了一个组件玩得很漂亮与JScrollPane的,它需要实现滚动。
如果你只是增加了一个JTextArea中到JScrollPane中,它会工作完全按照您所希望的。

In order for a component to "Play Nicely" with JScrollPane, it needs to implement Scrollable. If you just added a JTextArea into the JScrollPane, it would work exactly as you desired.

而不是使用一个JPanel来容纳所有的JTextAreas的,你需要做扩展JPanel并实现滚动的小自定义类。

Instead of using a JPanel to hold all your JTextAreas, you'll need to make a small custom class that extends JPanel and implements Scrollable.

我已经重新编写你的榜样,并粘贴在这里吧: http://pastebin.com/q9x4fv3H ,以便您可以看到所有code。可滚动的JPanel应该是这样的:

I've re-written your example and pasted it here: http://pastebin.com/q9x4fv3H so that you can see all the code. The Scrollable JPanel should look like this:

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.
    }
}

干杯!

这篇关于JTextArea中对里面的JPanel JScrollPane的不正常调整的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆