JScrollPane,JTextArea和JPanel的问题

ak1*_*652 2 java swing jpanel jscrollpane jtextarea

我需要在我的JPanel中添加一个垂直滚动条.当长串文本没有正确包装等时出现问题.所以我在网上执行了步骤并将其放在文本区域中并且工作正常(没有滚动窗格).

然而,在添加JScrollpane(它应该只是垂直的,并且请假设它是必需的,即不能设置最小尺寸)到JPanel时,当我水平调整它时,它会完全混乱.它不会在调整大小时进行包装,而其他组件的位置会变得混乱.

可能看起来很奇怪,我在这里有不必要的面板,但是我作为一个更大的程序的一部分工作并且是必需的(for循环仅用于测试目的).

总而言之:在水平调整窗口大小时,它的行为不符合预期.

会很感激一些指导.

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;

public class Main {

    public static void main(String[] args) {

        String s = "Hello my name is test. I am a test. Hello my name is test. I am a test. Hello my name is test. I am a test. Hello my name is test. I am a test. ";
        JFrame jf = new JFrame("Test");
        jf.setSize(600, 200);

        JPanel big = new JPanel();
        big.setLayout(new BoxLayout(big, BoxLayout.Y_AXIS));

        for (int i = 0; i < 2; i++) {
            JPanel first = new JPanel(new BorderLayout());

            JPanel insideTop = new JPanel(new GridLayout(2, 2));
            insideTop.add(new JLabel("test"));
            insideTop.add(new JLabel("test"));
            insideTop.add(new JLabel("test"));
            insideTop.add(new JLabel("test"));

            JPanel insideMiddle = new JPanel(new BorderLayout());
            insideMiddle.add(new JLabel("Description"), BorderLayout.NORTH);
            JTextArea jta = new JTextArea(s);
            jta.setWrapStyleWord(true);
            jta.setLineWrap(true);
            jta.setEditable(false);
            jta.setFocusable(false);
            jta.setOpaque(false);
            insideMiddle.add(jta, BorderLayout.CENTER);

            JPanel insideBottom = new JPanel(new BorderLayout());
            insideBottom.add(new JLabel("Bottom left"), BorderLayout.WEST);
            insideBottom.add(new JButton("Bottom right"), BorderLayout.EAST);

            first.add(insideTop, BorderLayout.NORTH);
            first.add(insideMiddle, BorderLayout.CENTER);
            first.add(insideBottom, BorderLayout.SOUTH);
            big.add(first);
        }

        JScrollPane scrollPane = new JScrollPane(big, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        jf.add(scrollPane);
        jf.setVisible(true);

    }
}
Run Code Online (Sandbox Code Playgroud)

Mad*_*mer 6

部分问题是,一旦允许组件扩展,它就不希望缩小,因此您需要某种方法将组件约束为始终为可视区域的宽度.

幸运的是,使用Scrollable界面实现它的方法相对简单...

public class BigPane extends JPanel implements Scrollable {

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

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

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

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

    @Override
    public boolean getScrollableTracksViewportHeight() {
        boolean track = true;
        Container parent = getParent();
        if (parent instanceof JViewport) {

            JViewport viewport = (JViewport) parent;
            if (viewport.getHeight() < getPreferredSize().height) {
                track = false;
            }

        }

        return track;
    }

}
Run Code Online (Sandbox Code Playgroud)

这基本上做的是使组件始终遵循宽度JViewport,因此当JScrollPane/ JViewport正在执行它们的布局时,他们知道将组件的宽度约束到可视区域的宽度.因为我喜欢这样工作,当组件的首选高度小于可视区域时,它也会填充空间,但你可以自己做出决定......

滚动

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Rectangle;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JViewport;
import javax.swing.ScrollPaneConstants;
import javax.swing.Scrollable;

public class Main {

    public static void main(String[] args) {

        String s = "Hello my name is test. I am a test. Hello my name is test. I am a test. Hello my name is test. I am a test. Hello my name is test. I am a test. ";
        JFrame jf = new JFrame("Test");
        jf.setSize(600, 200);

        BigPane big = new BigPane();
        big.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.BOTH;

        for (int i = 0; i < 2; i++) {
            JPanel first = new JPanel(new BorderLayout());

            JPanel insideTop = new JPanel(new GridLayout(2, 2));
            insideTop.add(new JLabel("test"));
            insideTop.add(new JLabel("test"));
            insideTop.add(new JLabel("test"));
            insideTop.add(new JLabel("test"));

            JPanel insideMiddle = new JPanel(new BorderLayout());
            insideMiddle.add(new JLabel("Description"), BorderLayout.NORTH);
            JTextArea jta = new JTextArea(s);
            jta.setWrapStyleWord(true);
            jta.setLineWrap(true);
            jta.setEditable(false);
            jta.setFocusable(false);
            jta.setOpaque(false);
            insideMiddle.add(jta, BorderLayout.CENTER);

            JPanel insideBottom = new JPanel(new BorderLayout());
            insideBottom.add(new JLabel("Bottom left"), BorderLayout.WEST);
            insideBottom.add(new JButton("Bottom right"), BorderLayout.EAST);

            first.add(insideTop, BorderLayout.NORTH);
            first.add(insideMiddle, BorderLayout.CENTER);
            first.add(insideBottom, BorderLayout.SOUTH);
            big.add(first, gbc);
        }

        JScrollPane scrollPane = new JScrollPane(big, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        jf.add(scrollPane);
        jf.setVisible(true);

    }

    public static class BigPane extends JPanel implements Scrollable {

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

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

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

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

        @Override
        public boolean getScrollableTracksViewportHeight() {
            boolean track = true;
            Container parent = getParent();
            if (parent instanceof JViewport) {

                JViewport viewport = (JViewport) parent;
                if (viewport.getHeight() < getPreferredSize().height) {
                    track = false;
                }

            }

            return track;
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

我也改为a GridBagLayout,再次,这是个人选择,你可能会发现这BoxLayout对你有用