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

public class Demo
{
    JFrame jf;
    JLabel[] labels;
    JPanel panel;

    public Demo()
    {
        jf = new JFrame();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        labels = new JLabel[10];
        Box vbox = Box.createVerticalBox();
        for (int i = 0; i < 10; i++)
        {
            labels[i] = new JLabel();
            vbox.add(labels[i]);
        }
        panel = new JPanel();
        panel.add(vbox);
        jf.add(panel);
        jf.setSize(300, 250);
        jf.setVisible(true);
    }
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new DemoRunnable());
    }
    public void updateState()
    {
        for (JLabel l : labels)
        {
            if (Math.random() > 0.5)
                l.setText("777777777777777777777777777777777777");
            else
                l.setText("10000000000000000000000000000000000000");
        }
    }
}
class DemoRunnable implements Runnable
{
    Demo demo;

    DemoRunnable()
    {
        this.demo = new Demo();
    }
    @Override
    public void run()
    {
        Thread t = new Thread(new Runnable()
        {

            @Override
            public void run()
            {
                while (true)
                {
                    try
                    {
                        Thread.sleep(0);
                    }
                    catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                    demo.updateState();
                }
            }
        });
        t.start();

    }
}

I see such effect when this program is perfomed. Is it possible to eliminate it(zeroes must be instead dots)?

enter image description here

eXXXXXXXXXXX2
  • 1,540
  • 1
  • 18
  • 32

2 Answers2

4

Instead of setSize() use pack() to take advantage of the component's carefully calculated preferred size. You'll also need to initialize your label:

labels[i] = new JLabel("10000000000000000000000000000000000000");

Also consider javax.swing.Timer instead of a separate thread.

Addendum: Conveniently, each Swing Timer shares a common background thread, and the actionPerformed() is called on the event dispatch thread. An alternative is SwingWorker, illustrated here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
3

my code in answer is example only,

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

public class Demo {

    private JFrame jf;
    private JLabel[] labels;
    private JPanel panel;

    public Demo() {
        labels = new JLabel[10];
        Box vbox = Box.createVerticalBox();
        for (int i = 0; i < 10; i++) {
            labels[i] = new JLabel();
            labels[i].setText("10000000000000000000000000000000000000");
            vbox.add(labels[i]);
        }
        panel = new JPanel();
        panel.setLayout(new GridLayout());
        panel.add(vbox);
        jf = new JFrame();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.add(panel);
        jf.pack();
        jf.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new DemoRunnable());
    }

    public void updateState() {
        for (final JLabel l : labels) {
            if (Math.random() > 0.5) {
                EventQueue.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        l.setText("777777777777777777777777777777777777");
                    }
                });
            } else {
                EventQueue.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        l.setText("10000000000000000000000000000000000000");
                    }
                });
            }
        }
    }
}

class DemoRunnable implements Runnable {

    private Demo demo;

    DemoRunnable() {
        this.demo = new Demo();
    }

    @Override
    public void run() {
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(250);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    demo.updateState();
                }
            }
        });
        t.start();
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • +1 for `invokeLater()`, and a good illustration of why `javax.swing.Timer` is so convenient. – trashgod Mar 25 '12 at 20:40
  • @trashgod agreed was +1, but I think that OP don't understand how the FlowLayout works, – mKorbel Mar 25 '12 at 20:51
  • @mKorbel How can flowLayout impact on my problem? If I understand correctly reason for such behaviour(strange dots) was calls of `setText` outside EDT but `setText` isn't thread safe method – eXXXXXXXXXXX2 Mar 26 '12 at 06:25
  • @eXXXXXXXXXXX FlowLayout is default LayoutManager implemented for JPanel by default, this LayoutManager pretty accepting PreferredSize from its JComponents, meanings each of JComponents can have different size on the screen, hmmm compare with GridLayout ...., – mKorbel Mar 26 '12 at 06:38
  • @mKorbel `invokeLater` isn't suitable for my problem(apparently in this case `setText` calls are accumulated in EDT queue. program hangs if delay is small with `invokeLater` (`invokeAndWait` fixes it) – eXXXXXXXXXXX2 Mar 26 '12 at 06:39
  • @eXXXXXXXXXXX that the reasons why I set dealay 10times more than average latency from todays Native OS'es :-) – mKorbel Mar 26 '12 at 06:42
  • @mKorbel I use `Box` which has fixed width (width of widest component inside this box) so `JPanel` with `FlowLayout` doesn't change it's size because it has width of "10000000000000000000000000000000000000" `JLabel` – eXXXXXXXXXXX2 Mar 26 '12 at 06:45
  • 2
    @eXXXXXXXXXXX no for String "...777" FlowLayout should be calculated another pixelx ratio as for 0000, this issue is about FontMetrics, – mKorbel Mar 26 '12 at 06:50