6

By default JLabel cuts off text on the right with 3 dots, if the text is too long to be displayed completely like this: enter image description here

(Image is from a small backup application I'm working on). As you can see the last JLabel above the "Cancel"-button is cut off on the right. This behavior is clearly not desirable, as the more relevant part of the text is cut off.

I'd like the resulting label to look like in this image (right column, sry for the bad resolution):
enter image description here

Source

So far I've tried to change the alignment of the text within the label to JLabel.RIGHT, alter the components orientation to ComponentOrientation.RIGHT_TO_LEFT, set horizontalTextPosition, all to no avail:

import javax.swing.*;
import java.awt.*;

public class Backup
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(()->{
            JLabel label = new JLabel("Some test text 1 2 3 4 5 6 7 8 9 10 abcdefghjiklmnopqrstuvwxyz", JLabel.RIGHT);
            label.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
            label.setHorizontalTextPosition(JLabel.RIGHT);

            JFrame frame = new JFrame();
            frame.add(label);
            frame.pack();
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}

What I've tried as well, using HTML:

<html>
    <body>
        <p style="width:300px;overflow-x:hidden;direction:rtl">
            kladsjhglakjsjdghlekfalksjdvhlkjdsnkljhsdlkvjhasdkjhfslkdjhcksdjhvflkasjvhlkajdlkajvsdhvlkjsadhaaaaaaaaaaaaa
        </p>
    </body>
</html>

While this works just in the way it's supposed to in my browser, swing doesn't seem to support a sufficient set of style-properties to support this behavior.

It shouldn't be too hard to code a own implementation that fulfills the requirement of doing precisely this. Nevertheless I was wondering whether there was a "swing-way" of achieving this.

  • `I'd like to look the resulting label like in this image` - that was what I was going to suggest. `I was wondering whether there was a "swing-way" of achieving this.` - not that I know of, that is why the custom renderer was created for the JTable. Otherwise I would have used the Swing way when using the label as the renderer :) – camickr Dec 30 '16 at 21:12
  • @camickr well, I just hoped the hoped there was some way around coding my own renderer by setting some property or something like that. But I already suspected it after going through both the docs and code of `JLabel`. Anyways, thanks. –  Dec 30 '16 at 21:17

3 Answers3

2

This doesn’t provide the leading ellipsis (…), but at least it is simple and clean. You can put the JLabel in a JViewport and keep it scrolled to the end at all times:

JViewport viewport = new JViewport();
viewport.setView(label);
viewport.addComponentListener(new ComponentAdapter() {
    @Override
    public void componentResized(ComponentEvent event) {
        int width = viewport.getWidth();
        Dimension size = label.getPreferredSize();
        viewport.setViewPosition(new Point(size.width - width, 0));
    }
});
VGR
  • 40,506
  • 4
  • 48
  • 63
2

Using the excellent answer from trashgod (https://stackoverflow.com/a/3597688/567496), here is a simple implementation of a BasicLabelUI that creates a left-side ellipsis.

It does use Apache's StringUtils.reverse(text), but only for convenience. It could be replaced with calls to StringBuilder(text).reverse().toString().

static class LeftEllipsisUI extends BasicLabelUI {
    @Override
    protected String layoutCL(JLabel label, FontMetrics fontMetrics, String text, Icon icon, Rectangle viewR, Rectangle iconR, Rectangle textR) {
        return StringUtils.reverse(super.layoutCL(label, fontMetrics, StringUtils.reverse(text), icon, viewR, iconR, textR));
    }
}
Mike Viens
  • 2,467
  • 3
  • 19
  • 23
0

You can add this and see if it is what you need:

label.setHorizontalAlignment(SwingConstants.LEFT);

By the documentation:

Sets the alignment of the label's contents along the X axis.

ddarellis
  • 3,912
  • 3
  • 25
  • 53
  • Doesn't help. Aligning the content of the label to the left won't alter the behavior of the overflow handling. In fact I've tried every single value that is valid as alignment, just to make sure. –  Dec 30 '16 at 21:11
  • With this i see the output you expected in your snippet, aligned to the left. – ddarellis Dec 30 '16 at 21:14
  • The point is not to allign the text to the left, but to cut off text with 3 dots on the left if the text otherwise overflows the boundaries of the component. –  Dec 30 '16 at 21:15
  • 1
    My bad! maybe you can see http://stackoverflow.com/questions/19519940/putting-3-dots-at-the-beginning-of-jlabel – ddarellis Dec 30 '16 at 21:20
  • well, that basically cooks down to creating an own implementation of a label. Though the last answer is quite interesting. Thanks ;) –  Dec 30 '16 at 21:46