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();
});
}
}