包含HTML文本的JLabel會使用可用空間自動換行。如果將JLabel添加到一個JSrollPane,他必須將preferredSize設置爲一個合適的值,否則它不會換行。所有這些都可以使用LayoutManager在JPanel內部的其他組件上正常工作。帶有包裝HTML文本作爲JScrollPane客戶端的JLabel
原因我想要一個可調整大小的應用程序窗口我擴展了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){
}
}
}
+1很好的問題 – mKorbel
'//添加一些文字here'呃,不,謝謝,我會留下那*你*做的。事實上,爲了更快提供更好的幫助,請發佈[SSCCE](http://sscce.org/)。 –