JScrollPane、JTextArea 和 JPanel 的问题
Issue with JScrollPane, JTextArea & JPanel
我需要向我的 JPanel 添加垂直滚动条。当长文本字符串没有正确换行等时,问题就出现了。所以我按照在线步骤将它放在文本区域并且它工作正常(没有滚动窗格)。
然而,在将 JScrollpane(它应该只是垂直的,请假设它是必需的,即不能设置最小尺寸)添加到 JPanel 后,当我水平调整它的大小时,它完全混乱了。它在调整大小时没有按应有的方式换行,其他组件的位置也乱七八糟。
这可能看起来很奇怪,我在这里有不必要的面板,但是我正在作为一个更大的程序的一部分工作并且需要这些面板(for 循环仅用于测试目的)。
总结一下:在水平调整 window 的大小时,它的行为与预期不符。
希望得到一些指导。
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);
}
}
部分问题是,一旦允许组件扩展,它就不想收缩,因此您需要一些方法来限制组件始终为可视区域的宽度。
幸运的是,有一种相对简单的方法可以使用 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;
}
}
这基本上是让组件始终遵循 JViewport
的宽度,因此当 JScrollPane
/JViewport
执行其布局时,它们知道限制组件的宽度到可视区域的宽度。因为我喜欢这样工作,所以当组件的首选高度小于可视区域时,它也会填充 space,但您可以自行决定...
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;
}
}
}
我也换成了 GridBagLayout
,同样,这是个人选择,您可能会发现 BoxLayout
适合您
我需要向我的 JPanel 添加垂直滚动条。当长文本字符串没有正确换行等时,问题就出现了。所以我按照在线步骤将它放在文本区域并且它工作正常(没有滚动窗格)。
然而,在将 JScrollpane(它应该只是垂直的,请假设它是必需的,即不能设置最小尺寸)添加到 JPanel 后,当我水平调整它的大小时,它完全混乱了。它在调整大小时没有按应有的方式换行,其他组件的位置也乱七八糟。
这可能看起来很奇怪,我在这里有不必要的面板,但是我正在作为一个更大的程序的一部分工作并且需要这些面板(for 循环仅用于测试目的)。
总结一下:在水平调整 window 的大小时,它的行为与预期不符。
希望得到一些指导。
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);
}
}
部分问题是,一旦允许组件扩展,它就不想收缩,因此您需要一些方法来限制组件始终为可视区域的宽度。
幸运的是,有一种相对简单的方法可以使用 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;
}
}
这基本上是让组件始终遵循 JViewport
的宽度,因此当 JScrollPane
/JViewport
执行其布局时,它们知道限制组件的宽度到可视区域的宽度。因为我喜欢这样工作,所以当组件的首选高度小于可视区域时,它也会填充 space,但您可以自行决定...
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;
}
}
}
我也换成了 GridBagLayout
,同样,这是个人选择,您可能会发现 BoxLayout
适合您