HTML テキストを含む JLabel は、使用可能なスペースを使用して行を自動的に折り返します。その JLabel を JSrollPane に追加する場合、preferredSize を適切な値に設定する必要があります。そうしないと、ラップされません。これはすべて、LayoutManager を使用して JPanel 内の他のコンポーネントに沿って正常に機能するはずです。
サイズ変更可能なアプリケーション ウィンドウが必要な理由 JScrollPane を拡張して、サイズ変更イベントを追跡し、ビューポートの幅に同期するサイズを動的に変更しました。基本的には機能しますが、レイアウト マネージャーによる適切な高さの計算が間違っている場合があります (値が大きすぎる、または小さすぎる)。たとえば、最初の行を通る赤い境界線の可視性は、高さの計算が間違っていることを示しています。
単一のラッピング JLabel では失敗を再現できません。
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class WrappedLabel implements Runnable {
public static void main( String[] args ){
SwingUtilities.invokeLater( new WrappedLabel() );
}
@Override
public void run(){
final JPanel panel = new JPanel( new GridBagLayout() );
final GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.BOTH;
gc.weightx = 1.0;
gc.weighty = 1.0;
{
gc.gridx = 0;
gc.gridy = 0;
final JLabel label = new JLabel(
"<html>" + "please add some more text here"
);
label.setBorder( BorderFactory.createLineBorder( Color.RED ) );
panel.add( label, gc );
}
{
gc.gridx = 0;
gc.gridy = 1;
final JLabel label = new JLabel(
"<html>" + "please add some more text here"
);
label.setBorder( BorderFactory.createLineBorder( Color.RED ) );
panel.add( label, gc );
}
final JFrame frame = new JFrame();
frame.add( new ScrollPane( panel ) );
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.setSize( 256, 256 );
frame.setVisible( true );
}
private class ScrollPane extends JScrollPane implements ComponentListener {
ScrollPane( Container view ){
super( view );
this.viewport.addComponentListener( this );
}
@Override
public void componentHidden( ComponentEvent ce ){
}
@Override
public void componentMoved( ComponentEvent ce ){
}
/** calculating required height is a 3 step process
* 1. sync width of client and viewport, set height of client to high value
* 2. let GridbagManager calculate required minimum size
* 3. set preferredSize and revalidate
**/
@Override
public void componentResized( ComponentEvent ce ){
assert( this.viewport == ce.getSource() );
final Container view = (Container) this.viewport.getView();
final int width = this.viewport.getExtentSize().width;
view.setPreferredSize( new Dimension( width, Integer.MAX_VALUE ) );
final int height = view.getLayout().preferredLayoutSize( view ).height;
view.setPreferredSize( new Dimension( width, height ) );
view.revalidate();
}
@Override
public void componentShown( ComponentEvent ce ){
}
}
}