我有JLabel
我希望在调整窗口大小时更改其大小。如果JLabel
包含太大的字符串,则应缩短字符串,右侧部分可见,并在字符串的左侧添加点。< / p>
我的JLabel
位于innerPanel
内,middlePanel
中的标题已添加到outerPanel
。因此,当我调整窗口大小时,我会以outerPanel
的方式使用侦听器:
outerPanel.addComponentListener(new ComponentListener() {
@Override
public void componentResized(ComponentEvent evt) {
int width = ((JPanel) evt.getSource()).getWidth();
windowSize = width;
refresh();
}
// [...] other not used override methods
});
refresh()
重新制作视图并创建新的middlePanel
,其中名为class,创建innerPanel
位于JLabel
的位置:
Public class InnerPanel extends JPanel {
private int maxSize;
String string = "<VERY_LONG_STRING>";
private static final int DEFAULT_INDEND_PIXEL = 70;
public InnerPanel(int windowSize) {
maxSize = windowSize - DEFAULT_INDENT_PIXEL;
createPanel();
}
private createPanel() {
// [...] gridbag and GridBagConstraints implementation
String shortString = countString();
JLabel label = new JLabel(shortString);
add(label,gc);
}
private String countString() {
int index = 0;
boolean toBig = true;
StringBuilder sb = new StringBuilder(string);
while(toBig) {
Rectangle2d rect = // [...] code which creates rectangle around text from sb.toString()
// I have no access to repo at home but if it's important I can paste it tomorrow
if(rect.getWidth() > maxSize)
sb.deleteCharAt(0);
else
toBig = false;
}
return sb.toString();
}
}
一般情况下这样做很好,因为当我在宽度上放大窗口时,它会在一步中调整JLabel
。但是当我尝试减小宽度窗口时会出现问题。在这种情况下,componentResized()
逐步计算width
(并且多次调用),逐渐减少width
一些像素,直到达到实际窗口大小。它的行为就是这样,即使我将窗口大小从最大大小一步改为800.整个过程非常缓慢,需要大约一秒钟才能将字符串与窗口大小相匹配。所以看起来有点像动画。
这个问题对我来说非常罕见,因为当我分配width
变量时,componentResized()
方法中的windowSize
会逐步计算 。
当我给windowSize
固定大小时,例如500 - componentResized()
仅被称为onces - 正确width
表示真实窗口大小(!!) - 并且没有它的步骤一步减少!
由width
分配的((JPanel) evt.getSource()).getWidth()
变量似乎知道windowSize
用于动态更改JLabel
组件的大小,即使在第一次调用{{1}之前} 方法。
如果有人知道这里发生了什么 - 我将非常感谢您的帮助。
答案 0 :(得分:1)
您可以调整here所示的方法之一,以获得更好的效果。如here所示,省略号由标签的UI代表通过调用SwingUtilities2.clipString()
提供,追加 clipString
。不是重新发明标签UI,而是使用TextLayout
确定所需的几何图形,预置省略号,并在表格或列表渲染器中处理对齐,如图所示here