Java JTextArea不';t调整大小

Java JTextArea不';t调整大小,java,swing,jpanel,resize,jtextarea,Java,Swing,Jpanel,Resize,Jtextarea,我试图将JTextArea设置为JPanelas JPanel panel=new JPanel(new BorderLayout()); JTextArea ta=new JTextArea(); ta.setColumns(20); ta.setEditable(false); ta.setLineWrap(true); ta.setRows(5); ta.setWrapStyleWord(true); panel.add(ta,BorderLayout.CENTER); JPanel

我试图将
JTextArea
设置为
JPanel
as

JPanel panel=new JPanel(new BorderLayout());
JTextArea ta=new JTextArea();
ta.setColumns(20);
ta.setEditable(false);
ta.setLineWrap(true);
ta.setRows(5);
ta.setWrapStyleWord(true);

panel.add(ta,BorderLayout.CENTER);

JPanel panel1=new JPanel();
panel1.setLayout(new VerticalLayout(5,VerticalLayout.BOTH));
panel1.add(panel);

JFrame frame=new JFrame();
frame.getContentPane().add(panel1);
    ...
问题是。。。当
panel1
的尺寸先变宽后变窄时,
JTextArea
变为切断。我的意思是,它的行不会恢复为5,而是保持为1,因此它的所有文本都在一行中,当然,
WrapStyleWord
处于非活动状态:S

因此,我的问题是如何使
JTextArea
在重新调整帧大小时恢复到其原始比例

这是代码

基于Guillaume Polet片段,我试图编写某种垂直面板列表,但前面提到的问题发生了:(以下是代码

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.util.Hashtable;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class TestTextArea {

    private void initUI() {
        JFrame frame = new JFrame("test");


        JPanel listPanel = new JPanel();
        listPanel.setLayout(new VerticalLayout(5, VerticalLayout.BOTH));


        JPanel mainPanel=new JPanel(new GridLayout());
        JScrollPane sp=new JScrollPane();
        sp.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        sp.setViewportView(listPanel);

        mainPanel.add(sp);

        listPanel.add(new MyPanel());
        listPanel.add(new MyPanel());
        listPanel.add(new MyPanel());
        listPanel.add(new MyPanel());
        listPanel.add(new MyPanel());

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestTextArea().initUI();
            }
        });
    }

    class MyPanel extends JPanel
    {
        public MyPanel(){

        this.setLayout(new BorderLayout());

        JTextArea ta = new JTextArea();
        ta.setText("Hello world Hello world Hello world Hello world " + "Hello world Hello world Hello world Hello world "
                + "Hello world Hello world Hello world Hello world " + "Hello world Hello world Hello world Hello world ");
        ta.setColumns(20);
        ta.setEditable(false);
        ta.setLineWrap(true);
        ta.setRows(5);
        ta.setWrapStyleWord(true);

        this.add(ta, BorderLayout.CENTER);


        }

    }

    public static class VerticalLayout implements LayoutManager {

        /**
         * The horizontal alignment constant that designates centering. Also used to designate center anchoring.
         */
        public final static int CENTER = 0;
        /**
         * The horizontal alignment constant that designates right justification.
         */
        public final static int RIGHT = 1;
        /**
         * The horizontal alignment constant that designates left justification.
         */
        public final static int LEFT = 2;
        /**
         * The horizontal alignment constant that designates stretching the component horizontally.
         */
        public final static int BOTH = 3;

        /**
         * The anchoring constant that designates anchoring to the top of the display area
         */
        public final static int TOP = 1;
        /**
         * The anchoring constant that designates anchoring to the bottom of the display area
         */
        public final static int BOTTOM = 2;
        private int vgap; // the vertical vgap between components...defaults to 5
        private int alignment; // LEFT, RIGHT, CENTER or BOTH...how the components are justified
        private int anchor; // TOP, BOTTOM or CENTER ...where are the components positioned in an overlarge space
        private Hashtable comps;

        // Constructors
        /**
         * Constructs an instance of VerticalLayout with a vertical vgap of 5 pixels, horizontal centering and anchored to the top of the
         * display area.
         */
        public VerticalLayout() {
            this(5, CENTER, TOP);
        }

        /**
         * Constructs a VerticalLayout instance with horizontal centering, anchored to the top with the specified vgap
         *
         * @param vgap
         *            An int value indicating the vertical seperation of the components
         */
        public VerticalLayout(int vgap) {
            this(vgap, CENTER, TOP);
        }

        /**
         * Constructs a VerticalLayout instance anchored to the top with the specified vgap and horizontal alignment
         *
         * @param vgap
         *            An int value indicating the vertical seperation of the components
         * @param alignment
         *            An int value which is one of <code>RIGHT, LEFT, CENTER, BOTH</code> for the horizontal alignment.
         */
        public VerticalLayout(int vgap, int alignment) {
            this(vgap, alignment, TOP);
        }

        /**
         * Constructs a VerticalLayout instance with the specified vgap, horizontal alignment and anchoring
         *
         * @param vgap
         *            An int value indicating the vertical seperation of the components
         * @param alignment
         *            An int value which is one of <code>RIGHT, LEFT, CENTER, BOTH</code> for the horizontal alignment.
         * @param anchor
         *            An int value which is one of <code>TOP, BOTTOM, CENTER</code> indicating where the components are to appear if the
         *            display area exceeds the minimum necessary.
         */
        public VerticalLayout(int vgap, int alignment, int anchor) {
            this.vgap = vgap;
            this.alignment = alignment;
            this.anchor = anchor;
        }

        // ----------------------------------------------------------------------------
        private Dimension layoutSize(Container parent, boolean minimum) {
            Dimension dim = new Dimension(0, 0);
            Dimension d;
            synchronized (parent.getTreeLock()) {
                int n = parent.getComponentCount();
                for (int i = 0; i < n; i++) {
                    Component c = parent.getComponent(i);
                    if (c.isVisible()) {
                        d = minimum ? c.getMinimumSize() : c.getPreferredSize();
                        dim.width = Math.max(dim.width, d.width);
                        dim.height += d.height;
                        if (i > 0) {
                            dim.height += vgap;
                        }
                    }
                }
            }
            Insets insets = parent.getInsets();
            dim.width += insets.left + insets.right;
            dim.height += insets.top + insets.bottom + vgap + vgap;
            return dim;
        }

        // -----------------------------------------------------------------------------
        /**
         * Lays out the container.
         */
        @Override
        public void layoutContainer(Container parent) {
            Insets insets = parent.getInsets();
            synchronized (parent.getTreeLock()) {
                int n = parent.getComponentCount();
                Dimension pd = parent.getSize();
                int y = 0;
                // work out the total size
                for (int i = 0; i < n; i++) {
                    Component c = parent.getComponent(i);
                    Dimension d = c.getPreferredSize();
                    y += d.height + vgap;
                }
                y -= vgap; // otherwise there's a vgap too many
                // Work out the anchor paint
                if (anchor == TOP) {
                    y = insets.top;
                } else if (anchor == CENTER) {
                    y = (pd.height - y) / 2;
                } else {
                    y = pd.height - y - insets.bottom;
                }
                // do layout
                for (int i = 0; i < n; i++) {
                    Component c = parent.getComponent(i);
                    Dimension d = c.getPreferredSize();
                    int x = insets.left;
                    int wid = d.width;
                    if (alignment == CENTER) {
                        x = (pd.width - d.width) / 2;
                    } else if (alignment == RIGHT) {
                        x = pd.width - d.width - insets.right;
                    } else if (alignment == BOTH) {
                        wid = pd.width - insets.left - insets.right;
                    }
                    c.setBounds(x, y, wid, d.height);
                    y += d.height + vgap;
                }
            }
        }

        // -----------------------------------------------------------------------------
        @Override
        public Dimension minimumLayoutSize(Container parent) {
            return layoutSize(parent, false);
        }

        // -----------------------------------------------------------------------------
        @Override
        public Dimension preferredLayoutSize(Container parent) {
            return layoutSize(parent, false);
        }

        // ----------------------------------------------------------------------------
        /**
         * Not used by this class
         */
        @Override
        public void addLayoutComponent(String name, Component comp) {
        }

        // -----------------------------------------------------------------------------
        /**
         * Not used by this class
         */
        @Override
        public void removeLayoutComponent(Component comp) {
        }

        // -----------------------------------------------------------------------------
        @Override
        public String toString() {
            return getClass().getName() + "[vgap=" + vgap + " align=" + alignment + " anchor=" + anchor + "]";
        }
    }

}

我不太确定如何使JTextArea恢复到原来的宽度?或者可能有更好的方法?

我不知道为什么不使用
JScrollPane
LineWrap
WordWrap
JScrollPane
中正常工作,那么对于
JPanel
来说,最好使用另一种
布局utManager

  • JTextArea
    放入
    JScrollPane

  • JPanel
    必需(我完全忽略使用的
    VerticalLayout
    )将默认
    LayoutManager
    FlowLayout
    )更改为
    BorderLayout

  • JScrollPane(myTextArea)
    放入
    BorderLayout.CENTER


    • 我不知道为什么不使用
      JScrollPane
      LineWrap
      WordWrap
      JScrollPane
      中正常工作,那么对于
      JPanel
      来说,最好使用另一个
      LayoutManager

      • JTextArea
        放入
        JScrollPane

      • JPanel
        必需(我完全忽略使用的
        VerticalLayout
        )将默认
        LayoutManager
        FlowLayout
        )更改为
        BorderLayout

      • JScrollPane(myTextArea)
        放入
        BorderLayout.CENTER


        • 您似乎在发布问题时遇到了问题,因此您可以从这一问题开始,可能会对其进行更改,然后编辑您的问题,向我们展示您遇到的问题

          编辑:(根据更新的问题更改SSCCE)

          问题是scrollpane的ViewPortView没有实现Scrollable。请使用添加为ViewPortView的专用类ScrollablePanel尝试下面的代码

          import java.awt.BorderLayout;
          import java.awt.Component;
          import java.awt.Container;
          import java.awt.Dimension;
          import java.awt.GridLayout;
          import java.awt.Insets;
          import java.awt.LayoutManager;
          import java.awt.Rectangle;
          import java.util.Hashtable;
          
          import javax.swing.JFrame;
          import javax.swing.JPanel;
          import javax.swing.JScrollBar;
          import javax.swing.JScrollPane;
          import javax.swing.JTextArea;
          import javax.swing.Scrollable;
          import javax.swing.SwingConstants;
          import javax.swing.SwingUtilities;
          
          public class TestTextArea {
          
              private void initUI() {
                  JFrame frame = new JFrame("test");
          
                  class ScrollablePanel extends JPanel implements Scrollable {
          
                      /**
                       * Returns the preferred size of the viewport for a view component. This is implemented to do the default behavior of returning
                       * the preferred size of the component.
                       * 
                       * @return the <code>preferredSize</code> of a <code>JViewport</code> whose view is this <code>Scrollable</code>
                       */
                      @Override
                      public Dimension getPreferredScrollableViewportSize() {
                          return getPreferredSize();
                      }
          
                      /**
                       * Components that display logical rows or columns should compute the scroll increment that will completely expose one new row
                       * or column, depending on the value of orientation. Ideally, components should handle a partially exposed row or column by
                       * returning the distance required to completely expose the item.
                       * <p>
                       * The default implementation of this is to simply return 10% of the visible area. Subclasses are likely to be able to provide a
                       * much more reasonable value.
                       * 
                       * @param visibleRect
                       *            the view area visible within the viewport
                       * @param orientation
                       *            either <code>SwingConstants.VERTICAL</code> or <code>SwingConstants.HORIZONTAL</code>
                       * @param direction
                       *            less than zero to scroll up/left, greater than zero for down/right
                       * @return the "unit" increment for scrolling in the specified direction
                       * @exception IllegalArgumentException
                       *                for an invalid orientation
                       * @see JScrollBar#setUnitIncrement
                       */
                      @Override
                      public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
                          switch (orientation) {
                          case SwingConstants.VERTICAL:
                              return visibleRect.height / 10;
                          case SwingConstants.HORIZONTAL:
                              return visibleRect.width / 10;
                          default:
                              throw new IllegalArgumentException("Invalid orientation: " + orientation);
                          }
                      }
          
                      /**
                       * Components that display logical rows or columns should compute the scroll increment that will completely expose one block of
                       * rows or columns, depending on the value of orientation.
                       * <p>
                       * The default implementation of this is to simply return the visible area. Subclasses will likely be able to provide a much
                       * more reasonable value.
                       * 
                       * @param visibleRect
                       *            the view area visible within the viewport
                       * @param orientation
                       *            either <code>SwingConstants.VERTICAL</code> or <code>SwingConstants.HORIZONTAL</code>
                       * @param direction
                       *            less than zero to scroll up/left, greater than zero for down/right
                       * @return the "block" increment for scrolling in the specified direction
                       * @exception IllegalArgumentException
                       *                for an invalid orientation
                       * @see JScrollBar#setBlockIncrement
                       */
                      @Override
                      public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
                          switch (orientation) {
                          case SwingConstants.VERTICAL:
                              return visibleRect.height;
                          case SwingConstants.HORIZONTAL:
                              return visibleRect.width;
                          default:
                              throw new IllegalArgumentException("Invalid orientation: " + orientation);
                          }
                      }
          
                      /**
                       * Returns true if a viewport should always force the width of this <code>Scrollable</code> to match the width of the viewport.
                       * For example a normal text view that supported line wrapping would return true here, since it would be undesirable for wrapped
                       * lines to disappear beyond the right edge of the viewport. Note that returning true for a <code>Scrollable</code> whose
                       * ancestor is a <code>JScrollPane</code> effectively disables horizontal scrolling.
                       * <p>
                       * Scrolling containers, like <code>JViewport</code>, will use this method each time they are validated.
                       * 
                       * @return true if a viewport should force the <code>Scrollable</code>s width to match its own
                       */
                      @Override
                      public boolean getScrollableTracksViewportWidth() {
                          return true;
                      }
          
                      /**
                       * Returns true if a viewport should always force the height of this <code>Scrollable</code> to match the height of the
                       * viewport. For example a columnar text view that flowed text in left to right columns could effectively disable vertical
                       * scrolling by returning true here.
                       * <p>
                       * Scrolling containers, like <code>JViewport</code>, will use this method each time they are validated.
                       * 
                       * @return true if a viewport should force the Scrollables height to match its own
                       */
                      @Override
                      public boolean getScrollableTracksViewportHeight() {
                          return false;
                      }
          
                  }
          
                  JPanel listPanel = new ScrollablePanel();
                  listPanel.setLayout(new VerticalLayout(5, VerticalLayout.BOTH));
          
                  JPanel mainPanel = new JPanel(new GridLayout());
                  JScrollPane sp = new JScrollPane();
                  sp.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
                  sp.setViewportView(listPanel);
          
                  mainPanel.add(sp);
          
                  listPanel.add(new MyPanel());
                  listPanel.add(new MyPanel());
                  listPanel.add(new MyPanel());
                  listPanel.add(new MyPanel());
                  listPanel.add(new MyPanel());
          
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  frame.add(mainPanel);
                  frame.pack();
                  frame.setVisible(true);
              }
          
              public static void main(String[] args) {
                  SwingUtilities.invokeLater(new Runnable() {
          
                      @Override
                      public void run() {
                          new TestTextArea().initUI();
                      }
                  });
              }
          
              class MyPanel extends JPanel {
                  public MyPanel() {
          
                      this.setLayout(new BorderLayout());
          
                      JTextArea ta = new JTextArea();
                      ta.setText("Hello world Hello world Hello world Hello world " + "Hello world Hello world Hello world Hello world "
                              + "Hello world Hello world Hello world Hello world " + "Hello world Hello world Hello world Hello world ");
                      ta.setColumns(20);
                      ta.setEditable(false);
                      ta.setLineWrap(true);
                      ta.setRows(5);
                      ta.setWrapStyleWord(true);
          
                      this.add(ta, BorderLayout.CENTER);
          
                  }
          
              }
          
              public static class VerticalLayout implements LayoutManager {
          
                  /**
                   * The horizontal alignment constant that designates centering. Also used to designate center anchoring.
                   */
                  public final static int CENTER = 0;
                  /**
                   * The horizontal alignment constant that designates right justification.
                   */
                  public final static int RIGHT = 1;
                  /**
                   * The horizontal alignment constant that designates left justification.
                   */
                  public final static int LEFT = 2;
                  /**
                   * The horizontal alignment constant that designates stretching the component horizontally.
                   */
                  public final static int BOTH = 3;
          
                  /**
                   * The anchoring constant that designates anchoring to the top of the display area
                   */
                  public final static int TOP = 1;
                  /**
                   * The anchoring constant that designates anchoring to the bottom of the display area
                   */
                  public final static int BOTTOM = 2;
                  private int vgap; // the vertical vgap between components...defaults to 5
                  private int alignment; // LEFT, RIGHT, CENTER or BOTH...how the components are justified
                  private int anchor; // TOP, BOTTOM or CENTER ...where are the components positioned in an overlarge space
                  private Hashtable comps;
          
                  // Constructors
                  /**
                   * Constructs an instance of VerticalLayout with a vertical vgap of 5 pixels, horizontal centering and anchored to the top of the
                   * display area.
                   */
                  public VerticalLayout() {
                      this(5, CENTER, TOP);
                  }
          
                  /**
                   * Constructs a VerticalLayout instance with horizontal centering, anchored to the top with the specified vgap
                   * 
                   * @param vgap
                   *            An int value indicating the vertical seperation of the components
                   */
                  public VerticalLayout(int vgap) {
                      this(vgap, CENTER, TOP);
                  }
          
                  /**
                   * Constructs a VerticalLayout instance anchored to the top with the specified vgap and horizontal alignment
                   * 
                   * @param vgap
                   *            An int value indicating the vertical seperation of the components
                   * @param alignment
                   *            An int value which is one of <code>RIGHT, LEFT, CENTER, BOTH</code> for the horizontal alignment.
                   */
                  public VerticalLayout(int vgap, int alignment) {
                      this(vgap, alignment, TOP);
                  }
          
                  /**
                   * Constructs a VerticalLayout instance with the specified vgap, horizontal alignment and anchoring
                   * 
                   * @param vgap
                   *            An int value indicating the vertical seperation of the components
                   * @param alignment
                   *            An int value which is one of <code>RIGHT, LEFT, CENTER, BOTH</code> for the horizontal alignment.
                   * @param anchor
                   *            An int value which is one of <code>TOP, BOTTOM, CENTER</code> indicating where the components are to appear if the
                   *            display area exceeds the minimum necessary.
                   */
                  public VerticalLayout(int vgap, int alignment, int anchor) {
                      this.vgap = vgap;
                      this.alignment = alignment;
                      this.anchor = anchor;
                  }
          
                  // ----------------------------------------------------------------------------
                  private Dimension layoutSize(Container parent, boolean minimum) {
                      Dimension dim = new Dimension(0, 0);
                      Dimension d;
                      synchronized (parent.getTreeLock()) {
                          int n = parent.getComponentCount();
                          for (int i = 0; i < n; i++) {
                              Component c = parent.getComponent(i);
                              if (c.isVisible()) {
                                  d = minimum ? c.getMinimumSize() : c.getPreferredSize();
                                  dim.width = Math.max(dim.width, d.width);
                                  dim.height += d.height;
                                  if (i > 0) {
                                      dim.height += vgap;
                                  }
                              }
                          }
                      }
                      Insets insets = parent.getInsets();
                      dim.width += insets.left + insets.right;
                      dim.height += insets.top + insets.bottom + vgap + vgap;
                      return dim;
                  }
          
                  // -----------------------------------------------------------------------------
                  /**
                   * Lays out the container.
                   */
                  @Override
                  public void layoutContainer(Container parent) {
                      Insets insets = parent.getInsets();
                      synchronized (parent.getTreeLock()) {
                          int n = parent.getComponentCount();
                          Dimension pd = parent.getSize();
                          int y = 0;
                          // work out the total size
                          for (int i = 0; i < n; i++) {
                              Component c = parent.getComponent(i);
                              Dimension d = c.getPreferredSize();
                              y += d.height + vgap;
                          }
                          y -= vgap; // otherwise there's a vgap too many
                          // Work out the anchor paint
                          if (anchor == TOP) {
                              y = insets.top;
                          } else if (anchor == CENTER) {
                              y = (pd.height - y) / 2;
                          } else {
                              y = pd.height - y - insets.bottom;
                          }
                          // do layout
                          for (int i = 0; i < n; i++) {
                              Component c = parent.getComponent(i);
                              Dimension d = c.getPreferredSize();
                              int x = insets.left;
                              int wid = d.width;
                              if (alignment == CENTER) {
                                  x = (pd.width - d.width) / 2;
                              } else if (alignment == RIGHT) {
                                  x = pd.width - d.width - insets.right;
                              } else if (alignment == BOTH) {
                                  wid = pd.width - insets.left - insets.right;
                              }
                              c.setBounds(x, y, wid, d.height);
                              y += d.height + vgap;
                          }
                      }
                  }
          
                  // -----------------------------------------------------------------------------
                  @Override
                  public Dimension minimumLayoutSize(Container parent) {
                      return layoutSize(parent, false);
                  }
          
                  // -----------------------------------------------------------------------------
                  @Override
                  public Dimension preferredLayoutSize(Container parent) {
                      return layoutSize(parent, false);
                  }
          
                  // ----------------------------------------------------------------------------
                  /**
                   * Not used by this class
                   */
                  @Override
                  public void addLayoutComponent(String name, Component comp) {
                  }
          
                  // -----------------------------------------------------------------------------
                  /**
                   * Not used by this class
                   */
                  @Override
                  public void removeLayoutComponent(Component comp) {
                  }
          
                  // -----------------------------------------------------------------------------
                  @Override
                  public String toString() {
                      return getClass().getName() + "[vgap=" + vgap + " align=" + alignment + " anchor=" + anchor + "]";
                  }
              }
          
          }
          

          似乎你在发布一个问题时遇到了问题,所以也许你可以从这一个开始,可能会修改它,然后编辑你的问题,向我们展示你遇到的问题

          编辑:(根据更新的问题更改SSCCE)

          问题是scrollpane的ViewPortView没有实现Scrollable。请使用添加为ViewPortView的专用类ScrollablePanel尝试下面的代码

          import java.awt.BorderLayout;
          import java.awt.Component;
          import java.awt.Container;
          import java.awt.Dimension;
          import java.awt.GridLayout;
          import java.awt.Insets;
          import java.awt.LayoutManager;
          import java.awt.Rectangle;
          import java.util.Hashtable;
          
          import javax.swing.JFrame;
          import javax.swing.JPanel;
          import javax.swing.JScrollBar;
          import javax.swing.JScrollPane;
          import javax.swing.JTextArea;
          import javax.swing.Scrollable;
          import javax.swing.SwingConstants;
          import javax.swing.SwingUtilities;
          
          public class TestTextArea {
          
              private void initUI() {
                  JFrame frame = new JFrame("test");
          
                  class ScrollablePanel extends JPanel implements Scrollable {
          
                      /**
                       * Returns the preferred size of the viewport for a view component. This is implemented to do the default behavior of returning
                       * the preferred size of the component.
                       * 
                       * @return the <code>preferredSize</code> of a <code>JViewport</code> whose view is this <code>Scrollable</code>
                       */
                      @Override
                      public Dimension getPreferredScrollableViewportSize() {
                          return getPreferredSize();
                      }
          
                      /**
                       * Components that display logical rows or columns should compute the scroll increment that will completely expose one new row
                       * or column, depending on the value of orientation. Ideally, components should handle a partially exposed row or column by
                       * returning the distance required to completely expose the item.
                       * <p>
                       * The default implementation of this is to simply return 10% of the visible area. Subclasses are likely to be able to provide a
                       * much more reasonable value.
                       * 
                       * @param visibleRect
                       *            the view area visible within the viewport
                       * @param orientation
                       *            either <code>SwingConstants.VERTICAL</code> or <code>SwingConstants.HORIZONTAL</code>
                       * @param direction
                       *            less than zero to scroll up/left, greater than zero for down/right
                       * @return the "unit" increment for scrolling in the specified direction
                       * @exception IllegalArgumentException
                       *                for an invalid orientation
                       * @see JScrollBar#setUnitIncrement
                       */
                      @Override
                      public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
                          switch (orientation) {
                          case SwingConstants.VERTICAL:
                              return visibleRect.height / 10;
                          case SwingConstants.HORIZONTAL:
                              return visibleRect.width / 10;
                          default:
                              throw new IllegalArgumentException("Invalid orientation: " + orientation);
                          }
                      }
          
                      /**
                       * Components that display logical rows or columns should compute the scroll increment that will completely expose one block of
                       * rows or columns, depending on the value of orientation.
                       * <p>
                       * The default implementation of this is to simply return the visible area. Subclasses will likely be able to provide a much
                       * more reasonable value.
                       * 
                       * @param visibleRect
                       *            the view area visible within the viewport
                       * @param orientation
                       *            either <code>SwingConstants.VERTICAL</code> or <code>SwingConstants.HORIZONTAL</code>
                       * @param direction
                       *            less than zero to scroll up/left, greater than zero for down/right
                       * @return the "block" increment for scrolling in the specified direction
                       * @exception IllegalArgumentException
                       *                for an invalid orientation
                       * @see JScrollBar#setBlockIncrement
                       */
                      @Override
                      public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
                          switch (orientation) {
                          case SwingConstants.VERTICAL:
                              return visibleRect.height;
                          case SwingConstants.HORIZONTAL:
                              return visibleRect.width;
                          default:
                              throw new IllegalArgumentException("Invalid orientation: " + orientation);
                          }
                      }
          
                      /**
                       * Returns true if a viewport should always force the width of this <code>Scrollable</code> to match the width of the viewport.
                       * For example a normal text view that supported line wrapping would return true here, since it would be undesirable for wrapped
                       * lines to disappear beyond the right edge of the viewport. Note that returning true for a <code>Scrollable</code> whose
                       * ancestor is a <code>JScrollPane</code> effectively disables horizontal scrolling.
                       * <p>
                       * Scrolling containers, like <code>JViewport</code>, will use this method each time they are validated.
                       * 
                       * @return true if a viewport should force the <code>Scrollable</code>s width to match its own
                       */
                      @Override
                      public boolean getScrollableTracksViewportWidth() {
                          return true;
                      }
          
                      /**
                       * Returns true if a viewport should always force the height of this <code>Scrollable</code> to match the height of the
                       * viewport. For example a columnar text view that flowed text in left to right columns could effectively disable vertical
                       * scrolling by returning true here.
                       * <p>
                       * Scrolling containers, like <code>JViewport</code>, will use this method each time they are validated.
                       * 
                       * @return true if a viewport should force the Scrollables height to match its own
                       */
                      @Override
                      public boolean getScrollableTracksViewportHeight() {
                          return false;
                      }
          
                  }
          
                  JPanel listPanel = new ScrollablePanel();
                  listPanel.setLayout(new VerticalLayout(5, VerticalLayout.BOTH));
          
                  JPanel mainPanel = new JPanel(new GridLayout());
                  JScrollPane sp = new JScrollPane();
                  sp.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
                  sp.setViewportView(listPanel);
          
                  mainPanel.add(sp);
          
                  listPanel.add(new MyPanel());
                  listPanel.add(new MyPanel());
                  listPanel.add(new MyPanel());
                  listPanel.add(new MyPanel());
                  listPanel.add(new MyPanel());
          
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  frame.add(mainPanel);
                  frame.pack();
                  frame.setVisible(true);
              }
          
              public static void main(String[] args) {
                  SwingUtilities.invokeLater(new Runnable() {
          
                      @Override
                      public void run() {
                          new TestTextArea().initUI();
                      }
                  });
              }
          
              class MyPanel extends JPanel {
                  public MyPanel() {
          
                      this.setLayout(new BorderLayout());
          
                      JTextArea ta = new JTextArea();
                      ta.setText("Hello world Hello world Hello world Hello world " + "Hello world Hello world Hello world Hello world "
                              + "Hello world Hello world Hello world Hello world " + "Hello world Hello world Hello world Hello world ");
                      ta.setColumns(20);
                      ta.setEditable(false);
                      ta.setLineWrap(true);
                      ta.setRows(5);
                      ta.setWrapStyleWord(true);
          
                      this.add(ta, BorderLayout.CENTER);
          
                  }
          
              }
          
              public static class VerticalLayout implements LayoutManager {
          
                  /**
                   * The horizontal alignment constant that designates centering. Also used to designate center anchoring.
                   */
                  public final static int CENTER = 0;
                  /**
                   * The horizontal alignment constant that designates right justification.
                   */
                  public final static int RIGHT = 1;
                  /**
                   * The horizontal alignment constant that designates left justification.
                   */
                  public final static int LEFT = 2;
                  /**
                   * The horizontal alignment constant that designates stretching the component horizontally.
                   */
                  public final static int BOTH = 3;
          
                  /**
                   * The anchoring constant that designates anchoring to the top of the display area
                   */
                  public final static int TOP = 1;
                  /**
                   * The anchoring constant that designates anchoring to the bottom of the display area
                   */
                  public final static int BOTTOM = 2;
                  private int vgap; // the vertical vgap between components...defaults to 5
                  private int alignment; // LEFT, RIGHT, CENTER or BOTH...how the components are justified
                  private int anchor; // TOP, BOTTOM or CENTER ...where are the components positioned in an overlarge space
                  private Hashtable comps;
          
                  // Constructors
                  /**
                   * Constructs an instance of VerticalLayout with a vertical vgap of 5 pixels, horizontal centering and anchored to the top of the
                   * display area.
                   */
                  public VerticalLayout() {
                      this(5, CENTER, TOP);
                  }
          
                  /**
                   * Constructs a VerticalLayout instance with horizontal centering, anchored to the top with the specified vgap
                   * 
                   * @param vgap
                   *            An int value indicating the vertical seperation of the components
                   */
                  public VerticalLayout(int vgap) {
                      this(vgap, CENTER, TOP);
                  }
          
                  /**
                   * Constructs a VerticalLayout instance anchored to the top with the specified vgap and horizontal alignment
                   * 
                   * @param vgap
                   *            An int value indicating the vertical seperation of the components
                   * @param alignment
                   *            An int value which is one of <code>RIGHT, LEFT, CENTER, BOTH</code> for the horizontal alignment.
                   */
                  public VerticalLayout(int vgap, int alignment) {
                      this(vgap, alignment, TOP);
                  }
          
                  /**
                   * Constructs a VerticalLayout instance with the specified vgap, horizontal alignment and anchoring
                   * 
                   * @param vgap
                   *            An int value indicating the vertical seperation of the components
                   * @param alignment
                   *            An int value which is one of <code>RIGHT, LEFT, CENTER, BOTH</code> for the horizontal alignment.
                   * @param anchor
                   *            An int value which is one of <code>TOP, BOTTOM, CENTER</code> indicating where the components are to appear if the
                   *            display area exceeds the minimum necessary.
                   */
                  public VerticalLayout(int vgap, int alignment, int anchor) {
                      this.vgap = vgap;
                      this.alignment = alignment;
                      this.anchor = anchor;
                  }
          
                  // ----------------------------------------------------------------------------
                  private Dimension layoutSize(Container parent, boolean minimum) {
                      Dimension dim = new Dimension(0, 0);
                      Dimension d;
                      synchronized (parent.getTreeLock()) {
                          int n = parent.getComponentCount();
                          for (int i = 0; i < n; i++) {
                              Component c = parent.getComponent(i);
                              if (c.isVisible()) {
                                  d = minimum ? c.getMinimumSize() : c.getPreferredSize();
                                  dim.width = Math.max(dim.width, d.width);
                                  dim.height += d.height;
                                  if (i > 0) {
                                      dim.height += vgap;
                                  }
                              }
                          }
                      }
                      Insets insets = parent.getInsets();
                      dim.width += insets.left + insets.right;
                      dim.height += insets.top + insets.bottom + vgap + vgap;
                      return dim;
                  }
          
                  // -----------------------------------------------------------------------------
                  /**
                   * Lays out the container.
                   */
                  @Override
                  public void layoutContainer(Container parent) {
                      Insets insets = parent.getInsets();
                      synchronized (parent.getTreeLock()) {
                          int n = parent.getComponentCount();
                          Dimension pd = parent.getSize();
                          int y = 0;
                          // work out the total size
                          for (int i = 0; i < n; i++) {
                              Component c = parent.getComponent(i);
                              Dimension d = c.getPreferredSize();
                              y += d.height + vgap;
                          }
                          y -= vgap; // otherwise there's a vgap too many
                          // Work out the anchor paint
                          if (anchor == TOP) {
                              y = insets.top;
                          } else if (anchor == CENTER) {
                              y = (pd.height - y) / 2;
                          } else {
                              y = pd.height - y - insets.bottom;
                          }
                          // do layout
                          for (int i = 0; i < n; i++) {
                              Component c = parent.getComponent(i);
                              Dimension d = c.getPreferredSize();
                              int x = insets.left;
                              int wid = d.width;
                              if (alignment == CENTER) {
                                  x = (pd.width - d.width) / 2;
                              } else if (alignment == RIGHT) {
                                  x = pd.width - d.width - insets.right;
                              } else if (alignment == BOTH) {
                                  wid = pd.width - insets.left - insets.right;
                              }
                              c.setBounds(x, y, wid, d.height);
                              y += d.height + vgap;
                          }
                      }
                  }
          
                  // -----------------------------------------------------------------------------
                  @Override
                  public Dimension minimumLayoutSize(Container parent) {
                      return layoutSize(parent, false);
                  }
          
                  // -----------------------------------------------------------------------------
                  @Override
                  public Dimension preferredLayoutSize(Container parent) {
                      return layoutSize(parent, false);
                  }
          
                  // ----------------------------------------------------------------------------
                  /**
                   * Not used by this class
                   */
                  @Override
                  public void addLayoutComponent(String name, Component comp) {
                  }
          
                  // -----------------------------------------------------------------------------
                  /**
                   * Not used by this class
                   */
                  @Override
                  public void removeLayoutComponent(Component comp) {
                  }
          
                  // -----------------------------------------------------------------------------
                  @Override
                  public String toString() {
                      return getClass().getName() + "[vgap=" + vgap + " align=" + alignment + " anchor=" + anchor + "]";
                  }
              }
          
          }
          

          为了更快地获得更好的帮助,请发布一个。
          frame.getContantPane().add(panel1);
          该代码无法编译。因此它不能用作查看运行时问题的代码。@Andrew Thompson,你说得对,谢谢。我是手工编写的,所以输入有点错误:)我用SSCCE(即复制/粘贴)修复了它。为了更快地获得更好的帮助,发布一个.frame.getContantPane().add(panel1)该代码无法编译。所以它不能是用来查看运行时问题的代码。@Andrew Thompson,你说得对,谢谢。我是手写的,所以有点输入错误:)我用SSCCE(即复制/粘贴)修复了它。我不使用JScrollPane,因为我对不可滚动和不可编辑的JTextArea感兴趣。只需使用wordwrap支持在其中设置文本。。。但问题是,一旦调整了JTextArea的大小,它就不会变成原来的:有没有办法让它四处走动,但保持垂直布局管理器?或者您可以建议一些alt垂直流布局管理器吗?然后您必须添加并使用override
          ComponentResistized()
          ,确保在调整大小期间避免闪烁,您必须从Swing Timer调用代码,如果调整继续调用计时器的大小#重新启动
          但保持垂直布局管理器的方式?
          对不起,我不知道有关此布局管理器的信息,也没有使用过..“对不起,我不知道有关此布局管理器的信息,也没有使用过”不,我的意思是,您可以建议另一种垂直流布局管理器吗?支持垂直填充组件添加的布局…我不使用JScrollPane,因为我对不可滚动和不可编辑的JTextArea感兴趣。只需使用wordwrap支持在其中设置文本。。。但问题是,一旦调整了JTextArea的大小,它就不会变成原来的:有没有办法让它四处走动,但保持垂直布局管理器?或者您可以建议一些alt垂直流布局管理器吗?然后您必须添加并使用override
          ComponentResistized()
          ,确保在调整大小期间避免闪烁,您必须从Swing Timer调用代码,如果调整继续调用计时器的大小#重新启动
          但保持垂直布局管理器的方式?
          对不起,我不知道有关此布局管理器的信息,也没有使用过..“对不起,我不知道有关此布局管理器的信息,也没有使用过”不,我的意思是,您可以建议另一种垂直流布局管理器吗?一个支持垂直填充组件添加…@mKorbel的布局感谢您的编辑(我知道这不是您第一次在我的代码中修复此问题)。我总是忘记框架上的默认关闭操作(我从IDE运行所有代码),尽管我完全知道它。好的,谢谢你的片段。在此基础上,我试图找出某种类型的SSCCE:)我编辑了我的问题。请注意it@user592704我还更新了我的SSCCE;-)我想你会觉得这更容易接受。问题源于视口视图未实现Scrollabl