如何在更改窗口大小和JLabel的奇怪行为时更改字符串长度(以像素为单位计算其宽度)

时间:2013-12-12 22:10:14

标签: java swing jpanel jlabel

我有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}之前} 方法。

如果有人知道这里发生了什么 - 我将非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您可以调整here所示的方法之一,以获得更好的效果。如here所示,省略号由标签的UI代表通过调用SwingUtilities2.clipString()提供,追加 clipString。不是重新发明标签UI,而是使用TextLayout确定所需的几何图形,预置省略号,并在表格或列表渲染器中处理对齐,如图所示here