【问题标题】:JLabel paints dotsJLabel 绘制点
【发布时间】:2012-04-09 09:49:59
【问题描述】:
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();

    }
}

执行此程序时,我看到了这样的效果。是否可以消除它(零必须是点)?

【问题讨论】:

  • 这基本上是因为你的文字超出了JLabel的界限。
  • sscce+1。

标签: java swing jlabel


【解决方案1】:

不要使用setSize(),而是使用pack() 来利用组件精心计算的首选大小。您还需要初始化您的标签:

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

还要考虑javax.swing.Timer 而不是单独的线程。

附录:方便的是,每个 Swing Timer 共享一个公共后台线程,并在事件调度线程上调用 actionPerformed()。另一种选择是SwingWorker,图示为here

【讨论】:

  • 我应该定期致电setText() 解决我的问题,所以我需要另一个解决方案(我的问题代码仅供示例)
【解决方案2】:

我的回答代码只是示例,

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

【讨论】:

  • +1 表示invokeLater(),很好地说明了为什么javax.swing.Timer 如此方便。
  • @trashgod 同意 +1,但我认为 OP 不了解 FlowLayout 的工作原理,
  • @mKorbel flowLayout 如何影响我的问题?如果我正确理解这种行为的原因(奇怪的点)是在 EDT 之外调用 setTextsetText 不是线程安全方法
  • @eXXXXXXXXXXX FlowLayout 是默认为 JPanel 实现的默认 LayoutManager,这个 LayoutManager 非常接受来自其 JComponents 的 PreferredSize,这意味着每个 JComponents 在屏幕上可以有不同的大小,嗯,与 GridLayout 相比 ....,
  • @eXXXXXXXXXXX no for String "...777" FlowLayout 应该计算另一个pixelx ratio 为0000,这个问题是关于FontMetrics,
猜你喜欢
  • 2011-11-16
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
相关资源
最近更新 更多