Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #39328 > unrolled thread

JLabel Text Cutoff

Started byEric Douglas <e.d.programmer@gmail.com>
First post2020-03-04 10:06 -0800
Last post2020-03-04 13:25 -0500
Articles 8 — 3 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  JLabel Text Cutoff Eric Douglas <e.d.programmer@gmail.com> - 2020-03-04 10:06 -0800
    Re: JLabel Text Cutoff Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2020-03-04 19:23 +0100
      Re: JLabel Text Cutoff Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2020-03-04 19:23 +0100
      Re: JLabel Text Cutoff Eric Douglas <e.d.programmer@gmail.com> - 2020-03-04 12:15 -0800
        Re: JLabel Text Cutoff Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2020-03-04 21:39 +0100
          Re: JLabel Text Cutoff Eric Douglas <e.d.programmer@gmail.com> - 2020-03-04 12:59 -0800
            Re: JLabel Text Cutoff Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2020-03-04 22:26 +0100
    Re: JLabel Text Cutoff Eric Sosman <esosman@comcast-dot-net.invalid> - 2020-03-04 13:25 -0500

#39328 — JLabel Text Cutoff

FromEric Douglas <e.d.programmer@gmail.com>
Date2020-03-04 10:06 -0800
SubjectJLabel Text Cutoff
Message-ID<c906ffa0-dddc-452b-8a59-afa3ace910d3@googlegroups.com>
Is there an easy way to show text on a JLabel cutoff from the left?
I've tried every method and parameter I can think of but when the text runs out of the control it just wants to cut it off from the right.
 sample:
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;

public class TestLabel {

    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setPreferredSize(new Dimension(600,480));
        f.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
        String text = "too long text to fit in control";
        
        JLabel lbl_1 = new JLabel();
        lbl_1.setPreferredSize(new Dimension(70,20));
        lbl_1.setHorizontalAlignment(SwingConstants.TRAILING);
        lbl_1.setText(text);
        f.getContentPane().add(lbl_1);
        
        f.pack();
        f.setVisible(true);
    }
}

I see text displayed as "too long te..."
I want to see text displayed like "...in control"

[toc] | [next] | [standalone]


#39329

FromDaniele Futtorovic <da.futt.news@laposte-dot-net.invalid>
Date2020-03-04 19:23 +0100
Message-ID<r3ormf$rde$1@dont-email.me>
In reply to#39328
On 2020-03-04 19:06, Eric Douglas wrote:
> Is there an easy way to show text on a JLabel cutoff from the left?
> I've tried every method and parameter I can think of but when the text runs out of the control it just wants to cut it off from the right.
>  sample:
> import java.awt.Dimension;
> import java.awt.FlowLayout;
> 
> import javax.swing.JFrame;
> import javax.swing.JLabel;
> import javax.swing.SwingConstants;
> 
> public class TestLabel {
> 
>     public static void main(String[] args) {
>         JFrame f = new JFrame();
>         f.setPreferredSize(new Dimension(600,480));
>         f.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
>         String text = "too long text to fit in control";
>         
>         JLabel lbl_1 = new JLabel();
>         lbl_1.setPreferredSize(new Dimension(70,20));
>         lbl_1.setHorizontalAlignment(SwingConstants.TRAILING);
>         lbl_1.setText(text);
>         f.getContentPane().add(lbl_1);
>         
>         f.pack();
>         f.setVisible(true);
>     }
> }
> 
> I see text displayed as "too long te..."
> I want to see text displayed like "...in control"
> 

The code you're looking for is in
  sun.swing.SwingUtilities2#clipString
called by (ultimately)
  javax.swing.plaf.basic.BasicLabelUI#layout

Looking at that method, I don't think there's any built-in way of having
the clipping occur at the start of the string:
> return string + clipString;
always appends.

-- 
DF.

[toc] | [prev] | [next] | [standalone]


#39330

FromDaniele Futtorovic <da.futt.news@laposte-dot-net.invalid>
Date2020-03-04 19:23 +0100
Message-ID<r3oro5$rde$2@dont-email.me>
In reply to#39329
On 2020-03-04 19:23, Daniele Futtorovic wrote:
> On 2020-03-04 19:06, Eric Douglas wrote:
>> Is there an easy way to show text on a JLabel cutoff from the left?
>> I've tried every method and parameter I can think of but when the text runs out of the control it just wants to cut it off from the right.
>>  sample:
>> import java.awt.Dimension;
>> import java.awt.FlowLayout;
>>
>> import javax.swing.JFrame;
>> import javax.swing.JLabel;
>> import javax.swing.SwingConstants;
>>
>> public class TestLabel {
>>
>>     public static void main(String[] args) {
>>         JFrame f = new JFrame();
>>         f.setPreferredSize(new Dimension(600,480));
>>         f.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
>>         String text = "too long text to fit in control";
>>         
>>         JLabel lbl_1 = new JLabel();
>>         lbl_1.setPreferredSize(new Dimension(70,20));
>>         lbl_1.setHorizontalAlignment(SwingConstants.TRAILING);
>>         lbl_1.setText(text);
>>         f.getContentPane().add(lbl_1);
>>         
>>         f.pack();
>>         f.setVisible(true);
>>     }
>> }
>>
>> I see text displayed as "too long te..."
>> I want to see text displayed like "...in control"
>>
> 
> The code you're looking for is in
>   sun.swing.SwingUtilities2#clipString
> called by (ultimately)
>   javax.swing.plaf.basic.BasicLabelUI#layout
> 
> Looking at that method, I don't think there's any built-in way of having
> the clipping occur at the start of the string:
>> return string + clipString;
> always appends.
> 

(Code from OpenJDK 1.8)

-- 
DF.

[toc] | [prev] | [next] | [standalone]


#39332

FromEric Douglas <e.d.programmer@gmail.com>
Date2020-03-04 12:15 -0800
Message-ID<ff0d2533-50b2-4dbb-8e58-3b9b4abcc58c@googlegroups.com>
In reply to#39329
On Wednesday, March 4, 2020 at 1:23:22 PM UTC-5, Daniele Futtorovic wrote:
> The code you're looking for is in
>   sun.swing.SwingUtilities2#clipString
> called by (ultimately)
>   javax.swing.plaf.basic.BasicLabelUI#layout
> 
> Looking at that method, I don't think there's any built-in way of having
> the clipping occur at the start of the string:
> > return string + clipString;
> always appends.
> 
> -- 
> DF.

So there isn't a method that simply does that?
I would have thought that should be the default if the control isn't wide enough for the text and you tell it to align the text to the right side of the control.
So the workaround I came up with sounds ugly.

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Window;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class TestLabel {

    public class MyTextControl extends JLabel {
        private static final long serialVersionUID = 1L;
        private String cText = "";
        
        public String getTextString() {
            return cText;
        }

        @Override
        public void setText(final String text) {
            cText = text;
            String dispText = "";
            final Font fnt = getFont();
            setToolTipText(null);
            if (fnt != null) {
                Window f = SwingUtilities.getWindowAncestor(this);
                final FontRenderContext frc;
                if (f == null) {
                    frc = new FontRenderContext(null, true, true);
                } else {
                    frc = f.getGraphics().getFontMetrics().getFontRenderContext();
                }
                final Rectangle2D textSize = fnt.getStringBounds(text, frc);
                Dimension cs = getPreferredSize();
                if (textSize.getWidth() <= cs.getWidth()) {
                    dispText = text;
                } else {
                    setToolTipText(text);
                    Rectangle2D r2d2 = new Rectangle2D.Double();
                    String dots = "...";
                    final Rectangle2D dotSize = fnt.getStringBounds(dots, frc);
                    if (text.length() > 0) {
                        char[] chars = text.toCharArray();
                        for (int n = chars.length - 1; n >= 0; n--) {
                            final Rectangle2D charSize = fnt.getStringBounds(String.valueOf(chars[n]), frc);
                            if (r2d2.getWidth() + charSize.getWidth() + dotSize.getWidth() > cs.getWidth()) {
                                break;
                            }
                            dispText = chars[n] + dispText;
                            r2d2 = fnt.getStringBounds(dispText, frc);
                        }
                        dispText = dots + dispText;
                    }
                }
            }
            super.setText(dispText);
        }
    }

    public static void main(final String[] args) {
        EventQueue.invokeLater(() -> {
            final JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setVisible(true);
            f.setPreferredSize(new Dimension(600, 480));
            f.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
            final String text = "too long text to fit in control";

            TestLabel lbl = new TestLabel();
            final MyTextControl lbl_1 = lbl.new MyTextControl();
            lbl_1.setPreferredSize(new Dimension(50, 20));
            f.getContentPane().add(lbl_1);
            lbl_1.setText(text);
            
            final MyTextControl lbl_2 = lbl.new MyTextControl();
            lbl_2.setPreferredSize(new Dimension(70, 20));
            f.getContentPane().add(lbl_2);
            lbl_2.setText(text);
            
            final MyTextControl lbl_3 = lbl.new MyTextControl();
            lbl_3.setPreferredSize(new Dimension(100, 20));
            f.getContentPane().add(lbl_3);
            lbl_3.setText(text);
            
            f.pack();
        });
    }
}

[toc] | [prev] | [next] | [standalone]


#39333

FromDaniele Futtorovic <da.futt.news@laposte-dot-net.invalid>
Date2020-03-04 21:39 +0100
Message-ID<r3p3mg$es5$1@dont-email.me>
In reply to#39332
On 2020-03-04 21:15, Eric Douglas wrote:
> On Wednesday, March 4, 2020 at 1:23:22 PM UTC-5, Daniele Futtorovic wrote:
>> The code you're looking for is in
>>   sun.swing.SwingUtilities2#clipString
>> called by (ultimately)
>>   javax.swing.plaf.basic.BasicLabelUI#layout
>>
>> Looking at that method, I don't think there's any built-in way of having
>> the clipping occur at the start of the string:
>>> return string + clipString;
>> always appends.
>>
> So there isn't a method that simply does that?
> I would have thought that should be the default if the control isn't wide enough for the text and you tell it to align the text to the right side of the control.

They probably could have added that -- and for all I know perhaps they
have, somewhere.

But in their defense, I wouldn't say that this kind of functionality
should /obviously/ be there. The label clipping is really just a crutch.
It doesn't make much sense for a label to be clipped in the first place
-- and if your UI relies on that, I would say the fault is more with
your UI.
I found it at times (when I was still doing UIs) helpful to use the path
of least resistance with respects to the library; mostly, they knew what
they were doing, much more so, I found, than me. Don't underestimate how
much UIs rely, to be effective, on paradigms and implicit assumptions.

Lastly, note that what I've seen in the wild for labels that didn't fit
their space, were animations to scroll the text back and forth (or
looping around) through the available space. It's a bit trickier (since
it involves background tasks), but works decently as a widget.

> So the workaround I came up with sounds ugly.

Seems fairly par for the course of Swing code to me.

>             final MyTextControl lbl_1 = lbl.new MyTextControl();

Ugh. Here's a tip: don't do this. Don't ever do this. I mean the
qualified `new`. Make that inner class static. If you absolutely can't
(and you always can), then create an instance method in the enclosing
that returns a new instance of the inner class. But qualified new should
be avoided IMO.

-- 
DF.

[toc] | [prev] | [next] | [standalone]


#39334

FromEric Douglas <e.d.programmer@gmail.com>
Date2020-03-04 12:59 -0800
Message-ID<6b92da41-287d-4517-991e-9a55b8176375@googlegroups.com>
In reply to#39333
On Wednesday, March 4, 2020 at 3:39:57 PM UTC-5, Daniele Futtorovic wrote:
> But in their defense, I wouldn't say that this kind of functionality
> should /obviously/ be there. The label clipping is really just a crutch.
> It doesn't make much sense for a label to be clipped in the first place
> -- and if your UI relies on that, I would say the fault is more with
> your UI.
> I found it at times (when I was still doing UIs) helpful to use the path
> of least resistance with respects to the library; mostly, they knew what
> they were doing, much more so, I found, than me. Don't underestimate how
> much UIs rely, to be effective, on paradigms and implicit assumptions.
> 
The use case here is a button that allows the user to select a file, then a text control showing what file they selected.  Obviously we can't show the full file name with path, it likely wouldn't fit on the screen much less in half the screen.  I thought they'd rather see the end of file name .ext instead of "C:\Documents and Settings...".

> Lastly, note that what I've seen in the wild for labels that didn't fit
> their space, were animations to scroll the text back and forth (or
> looping around) through the available space. It's a bit trickier (since
> it involves background tasks), but works decently as a widget.
> 
Sounds curious.

> > So the workaround I came up with sounds ugly.
> 
> Seems fairly par for the course of Swing code to me.
> 
> >             final MyTextControl lbl_1 = lbl.new MyTextControl();
> 
> Ugh. Here's a tip: don't do this. Don't ever do this. I mean the
> qualified `new`. Make that inner class static. If you absolutely can't
> (and you always can), then create an instance method in the enclosing
> that returns a new instance of the inner class. But qualified new should
> be avoided IMO.
> 
> -- 
> DF.

That is not part of a real API, just to make this runnable test class.  That's how Eclipse told me to write that, with trying to instantiate the control from the static main method, having the control class declared within the test class.  In the real API of course it's not instantiated from the main method and the control class is in it's own file.

[toc] | [prev] | [next] | [standalone]


#39335

FromDaniele Futtorovic <da.futt.news@laposte-dot-net.invalid>
Date2020-03-04 22:26 +0100
Message-ID<r3p6e6$vk7$1@dont-email.me>
In reply to#39334
On 2020-03-04 21:59, Eric Douglas wrote:
> The use case here is a button that allows the user to select a file, then a text control showing what file they selected.  Obviously we can't show the full file name with path, it likely wouldn't fit on the screen much less in half the screen.  I thought they'd rather see the end of file name .ext instead of "C:\Documents and Settings...".

Makes sense. But how about a simple tooltip?

-- 
DF.

[toc] | [prev] | [next] | [standalone]


#39331

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2020-03-04 13:25 -0500
Message-ID<r3orq6$s67$1@dont-email.me>
In reply to#39328
On 3/4/2020 1:06 PM, Eric Douglas wrote:
> Is there an easy way to show text on a JLabel cutoff from the left?
> I've tried every method and parameter I can think of but when the text runs out of the control it just wants to cut it off from the right.

     Haven't tried it myself, but have you looked at
setHorizontalTextPosition()?  Also, try setComponentOrientation().

     If those don't work out and you really need the effect,
you could (I guess) get the label's Font and FontMetrics,
measure the as-rendered width of the string, and set the
label's text to as much of the tail as will fit.  (If I
were doing this a lot, I'd subclass JLabel.)

-- 
esosman@comcast-dot-net.invalid
Three hundred twenty-two days to go.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web