Java 带换行符的JTextArea报告JDialog包的首选大小不正确?
我使用多个JTextAreas来显示可变大小的文本,换行符和WrapStyleWord都为true。其中一个应用程序是在JScrollPane中显示包含多个文本区域的JDialog。包含所有这些文本区域的面板实现了可滚动(如上所述),允许JDialog具有最大大小,但仍会缩小。但是,JDialog有一个设置的水平大小。水平滚动条被强制从不显示,垂直滚动条不应显示,除非对话框达到其最大大小。但是,在JTextArea换行的情况下,当JDialog的高度小于其最大值时,会出现垂直滚动条。问题似乎是当JDialog被压缩时,JTextArea报告一行的首选高度,这导致对话框的高度小于面板的高度,因为文本区域占据了多行 这似乎是第22条军规,为了获得文本区域的适当高度,需要将其添加到具有所需宽度的面板中,以计算换行,这将允许计算实际行数(使用找到的方法)。但是JDialog在调用pack之前需要一个首选的大小(据我所知),这导致了这个问题。要演示问题,请执行以下操作:Java 带换行符的JTextArea报告JDialog包的首选大小不正确?,java,swing,awt,jtextarea,jdialog,Java,Swing,Awt,Jtextarea,Jdialog,我使用多个JTextAreas来显示可变大小的文本,换行符和WrapStyleWord都为true。其中一个应用程序是在JScrollPane中显示包含多个文本区域的JDialog。包含所有这些文本区域的面板实现了可滚动(如上所述),允许JDialog具有最大大小,但仍会缩小。但是,JDialog有一个设置的水平大小。水平滚动条被强制从不显示,垂直滚动条不应显示,除非对话框达到其最大大小。但是,在JTextArea换行的情况下,当JDialog的高度小于其最大值时,会出现垂直滚动条。问题似乎是当
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Rectangle;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.Scrollable;
public class DisplayPopup extends JDialog {
public DisplayPopup() {
JPanel actual = new JPanel();
actual.setLayout(new BoxLayout(actual, BoxLayout.Y_AXIS));
actual.setOpaque(false);
JTextArea jta = new JTextArea();
jta.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac dictum magna. Nam sed mattis sem. Donec tortor felis, finibus in lectus fringilla, semper finibus turpis. ");
jta.setFont(new java.awt.Font("Arial", 0, 18));
jta.setForeground(new java.awt.Color(204, 204, 204));
jta.setLineWrap(true);
jta.setWrapStyleWord(true);
jta.setEditable(false);
jta.setBackground(new Color(45,45,45));
jta.setHighlighter(null);
actual.add(jta);
PopupScroll ps = new PopupScroll(actual);
JScrollPane scroll = new JScrollPane();
scroll.getViewport().add(ps);
setModalityType(java.awt.Dialog.ModalityType.MODELESS);
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(scroll);
pack();
}
public static void launch() {
DisplayPopup dp = new DisplayPopup();
dp.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(DisplayPopup::launch);
}
private class PopupScroll extends JPanel implements Scrollable {
public PopupScroll(JPanel jp) {
setBackground(Color.PINK);
setLayout(new BorderLayout());
add(jp);
}
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(500,Math.min((int)getPreferredSize().getHeight(),700));
}
@Override
public int getScrollableUnitIncrement(Rectangle arg0, int arg1, int arg2) {
return 1;
}
@Override
public int getScrollableBlockIncrement(Rectangle arg0, int arg1, int arg2) {
return 1;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
}
对话框的大小不能包含所有文本行。与类似问题的解决方案不同,调用pack并不能解决问题。我对这个解决方案有一些猜测,可能使用了JTextArea之外的东西(因为我只想显示文本…?),但我不知道会是什么。我曾尝试在垂直滚动条上放置一个层次侦听器,以便在不显示对话框的情况下检测它何时处于活动状态,但这不起作用。这是一个难题还是我遗漏了一些明显的内容?做了一些更改,我看到文本显示在3行上:
pack();
pack();
是的,这是正确的,我添加了第二个包()。第一个包似乎能识别宽度,第二个包使文本被包装
然而,我也不得不改变:
//actual.setLayout(new BoxLayout(actual, BoxLayout.Y_AXIS));
actual.setLayout(new BorderLayout());
我知道您并不真的想使用BorderLayout(因为您希望多个组件垂直对齐),但不知怎的,它首选的大小计算似乎是可行的
您可以使用GridBagLayout
,而不是BoxLayout。它允许您指定“填充”约束。我猜你会尝试水平填充
或者另一种选择是使用。我会比GridBagLayout更简单,因为您不需要担心任何约束。使用它的代码是:
//actual.setLayout(new BoxLayout(actual, BoxLayout.Y_AXIS));
RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
rl.setFill( true );
actual.setLayout( rl );
您应该设置JTextArea的行和列属性以使其大小最佳,通常在构造函数中完成:
newjtextarea(rowCount,columnCount)代码>。通常,在将JScrollPane放入GUI之前,JTextArea本身会被放入JScrollPane中。@dontKnowmMuchButgeting更好地设置行和列会使其适合一定的大小。但是,如果我不知道有多少行,如何确定正确的行/列值?是的,我知道将每个JTextArea放入自己的JScrollPane是很常见的,但我不希望每个单独的文本区域滚动,而是希望整个面板包含所有文本区域。边框布局很有趣。非常有趣的是,解决方案,就像在一个链接问题中一样,只需要添加一个pack()。我使用相对布局,它的工作非常完美。它还解决了我的第二个问题,即需要在JTextArea旁边包含一个JLabel(我也在使用BoxLayout,但现在不再使用)。我想我也会在其他方面使用您的布局-谢谢,我们刚刚遇到了类似的问题,两次调用pack()解决了这个问题。在某些Linux设备上,同一JDialog类的不同实例,包含一个JTextArea(不放在JScrollBar中),并将static final
常量文本设置为内容(读取:每个实例中完全相同的文本),将以完全随机的方式为该JTextArea返回至少两个不同的首选大小。在一个带有GridBagLayout的不可调整大小的JDialog中使用它会造成巨大的破坏,因为在一种情况下,组件的布局就像天皇棒一样,而在另一种情况下,一切都会很好。