Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cut off the text of a JLabel on the left

Tags:

java

swing

jlabel

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.

like image 692
Paul Avatar asked Dec 30 '16 21:12

Paul


2 Answers

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));
    }
});
like image 136
VGR Avatar answered Sep 29 '22 12:09

VGR


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));
    }
}
like image 39
Mike Viens Avatar answered Sep 29 '22 12:09

Mike Viens