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


Groups > comp.lang.java.programmer > #36078

Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this?

From Eric Sosman <esosman@comcast-dot-net.invalid>
Newsgroups comp.lang.java.programmer
Subject Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this?
Date 2016-12-09 15:32 -0500
Organization A noiseless patient Spider
Message-ID <o2f4a1$uhr$1@dont-email.me> (permalink)
References <75624c6e-6a78-4e8a-82a4-4ff2556cc241@googlegroups.com> <5bda0936-09ee-4eea-8001-e0ad17f31b0b@googlegroups.com>

Show all headers | View raw


On 12/9/2016 2:35 PM, The Kreepy Gamer wrote:
> Thanks for your help! I hope I got it right this time. :)
>
>
> In my GUI program, I have a thread with a while loop that resizes the text to fit into the various JLabels and JButtons that are on it. But sometimes when the text is a certain width it will get bigger and smaller. For example, it will have text in the font size 26, it loops and resizes it to 20. Then it loops again and changes it back to 26, creating a "jiggling" effect.

     A few random observations, scattered throughout:

> import java.awt.Component;
> import java.awt.Font;
>
> import javax.swing.JFrame;
> import javax.swing.JLabel;
>
> public class Fonts {
>
>    static JLabel label = new JLabel("text that \"jiggles\"                ");

     You've already been warned that Swing is not thread-safe, and
that almost all manipulation of Swing things must happen on the
event dispatching thread, or EDT.  Here, you construct a Swing
component while *not* running on the EDT.  I don't know whether
this contributes to your trouble, but it would certainly be a good
idea to fix the known errors before attacking the mysteries.

>    public Fonts() {
>       JFrame window = new JFrame("Test");
>       window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
>       window.setSize(300,300);
>
>       label.setHorizontalAlignment(JLabel.CENTER);
>
>       window.add(label);
>       window.setVisible(true);
>    }
>
>    public static void main(String[] args) {
>       new Fonts();

     The constructor builds and manipulates several Swing things,
but is not running on the EDT.  Hence, everything it does is suspect.

>       Thread thread = new Thread(new Runnable() {
>             public void run() {
>                   while (true) {
>                      label.setFont(getMaxFontSize(label,label.getText()));
>                   }
>             }
>       });
>       thread.run();

     You probably meant start() rather than run(), but it's pointless
either way.  Also, it's wrong either way: It manipulates a Swing thing
from a non-EDT thread, whether that thread is the original main thread
(as shown here) or a different thread (if you used start() instead).

     Also, `while(true)' looks like a poor idea: Instead of trying to
set and reset and re-reset the component's font over and over and over
again as rapidly as a dedicated core can do it, you ought to be setting
the font in response to some kind of event.  If you're trying to make
text fit in a predefined space, set the font when the text and/or the
space changes.  Just sitting in a tight loop going SET-SET-SET-SET-SET
is silly (especially if you intend most SET's to use the same font).

>    }
>
>    public static Font getMaxFontSize(Component comp, String text) {
>       Font compFont = comp.getFont();
>       String compText = text;
>       int stringWidth = comp.getFontMetrics(compFont)
>                         .stringWidth(compText);
>       int compWidth = comp.getWidth()-75;

     Still more Swing stuff while not running on the EDT.

>       if (stringWidth == 0) {
>          stringWidth++;
>       }
>
>       while (compWidth < 0) {
>     	  compWidth++;
>       }
>
>       double widthRatio = (double)compWidth / (double)stringWidth;
>
>       int newFontSize = (int)(compFont.getSize() * widthRatio);

     Just a thought: It might be just a little better if you used
Math.round() instead of just throwing the fraction away.  (Then again,
it might not be better.)

>       int compHeight = comp.getHeight();

     Not running on the EDT.  (Is there an echo in here?)

>       int fontSizeToUse = Math.min(newFontSize, compHeight);
>       if (fontSizeToUse < 1) {
>          return new Font(compFont.getName(), Font.PLAIN, 1);
>       }
>       return new Font(compFont.getName(), Font.PLAIN, fontSizeToUse);
>    }
> }
>
> Does anyone know why it is doing this, and how I could fix it?

     Fonts don't shrink and stretch in infinitely fine gradations, so
it's quite possible to arrive at an oscillation.  Let's say you start
with font size S and discover that the string is a little wider than
you want.  Okay, so you change to size S-epsilon -- and now you find
that the string is shorter than you'd like.  So you run through your
calculation again and settle on (S-epsilon)+epsilon, and now the text
is too wide, so ...

     Putting it all together, I'd encourage the following approach:

     1) Fix up the EDT business.  I don't know that it *is* contributing
to your trouble, but it certainly *could* be.  (For example, changing a
font while not on the EDT will probably interact poorly with Swing's
painting of the screen.)  Something is amiss, this aspect of your code
is wrong, fix what's know to be wrong and then see what problems remain.

     2) Restructure your program so it knows *when* a font change is
needed and makes the change *once*, instead of making it over and over
and over again in a tight loop.  When you decide a change is needed,
make a "best effort" to fit the text, knowing that the fit will almost
never be exact.  (Because of granularity, if nothing else: You can't
fill a one-and-a-half car-length gap with cars.)

-- 
esosman@comcast-dot-net.invalid
"Nobody ever went broke underestimating the intelligence of the
American public." -- HLM (paraphrased)

Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? The Kreepy Gamer <tylerc2077@gmail.com> - 2016-12-06 15:21 -0800
  Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2016-12-07 13:36 -0600
  Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? The Kreepy Gamer <tylerc2077@gmail.com> - 2016-12-08 12:48 -0800
    Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2016-12-08 15:30 -0600
    Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Martin Gregorie <martin@address-in-sig.invalid> - 2016-12-08 22:17 +0000
      Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Arne Vajhøj <arne@vajhoej.dk> - 2016-12-08 20:09 -0500
      Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Gene Wirchenko <genew@telus.net> - 2016-12-09 09:07 -0800
        Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Martin Gregorie <martin@address-in-sig.invalid> - 2016-12-09 20:01 +0000
  Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Nigel Wade <nmw@local.domain> - 2016-12-09 10:54 +0000
  Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? The Kreepy Gamer <tylerc2077@gmail.com> - 2016-12-09 11:35 -0800
    Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-12-09 15:32 -0500
    Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Martin Gregorie <martin@address-in-sig.invalid> - 2016-12-09 21:22 +0000
      Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Martin Gregorie <martin@address-in-sig.invalid> - 2016-12-12 12:08 +0000
    Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Arne Vajhøj <arne@vajhoej.dk> - 2016-12-11 20:48 -0500
  Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? The Kreepy Gamer <tylerc2077@gmail.com> - 2016-12-12 11:18 -0800
    Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-12-12 14:22 -0500
    Re: When resizing text to fill a JLabel the text sometimes "jiggles", how do I fix this? Arne Vajhøj <arne@vajhoej.dk> - 2016-12-12 20:15 -0500

csiph-web