1

我在 FlowLayout 中有一个 JFrame,其中添加了多个 JLabel,但是当我在 JLabels 上调用 repaint 时,没有调用它们的 paintComponent。如果我删除 FlowLayout,则只有最后添加的 JLabel 会显示并正确重绘。我尝试使用面板,但它不起作用。我不确定我是否正确使用它。

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import javax.swing.JFrame;

public class RacingLetters {

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                final JFrame jframe = new JFrame();
                jframe.setTitle("Racing letters");
                jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                //jframe.setExtendedState(Frame.MAXIMIZED_BOTH);
                Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
                int x = (int) ((dimension.getWidth() - jframe.getWidth()) / 2);
                int y = (int) ((dimension.getHeight() - jframe.getHeight()) / 2);
                jframe.setLocation(x, y);
                jframe.setMinimumSize(new Dimension(500, 200));
                FlowLayout fl = new FlowLayout();
                jframe.setLayout(fl);
                //jframe.setLayout(null);
                jframe.setVisible(true);    

                StringBuffer[] stringBufferArray = new StringBuffer[20];
                char ch = 'A';

                int yy = 20;
                for (int i = 0; i < 5; i++) {
                    stringBufferArray[i] = new StringBuffer("");
                    BufferThread bt = new BufferThread(stringBufferArray[i], ch, 10, yy);
                    //pane.add(bt);
                    jframe.add(bt);

                    new Thread(bt).start();
                    ch++;
                    yy += 20;
                }

            }
        });

    }
}

..

import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;


public class BufferThread extends JLabel implements Runnable {

    char ch;
    StringBuffer sb;
    int x,y;

    BufferThread(StringBuffer sb, char ch,int x, int y) {
        this.sb = sb;
        this.ch = ch;
        this.x = x;
        this.y = y;
    }

    @Override
    public void run() {
        Random rand = new Random();

        for (int i = 0; i < 5; i++) {
            sb.append(ch);
            System.out.println(x + " " + y + " " + ch);
            repaint();

            try {
                Thread.sleep(rand.nextInt(500));
            } catch (InterruptedException ex) {
                Logger.getLogger(BufferThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void paintComponent(Graphics g) {
        //System.out.println(x + " " + y + " " + ch);
        //System.out.println("aaaa");
        //stem.out.println(sb);
        Graphics2D g2 = (Graphics2D) g;

        Font f = new Font("Serif", Font.PLAIN, 24);
        //if (sb.toString().indexOf("E") < 0)
            g2.drawString(sb.toString(), x, y);

    }

}
4

1 回答 1

2

核心问题是JLabel没有向框架的布局管理器提供任何关于它想要多大的信息。它实际上也没有告诉框架的布局管理器它已更新并且需要调整大小。

为什么你试图在标签上绘制文本超出了我的理解,因为这就是标签的设计。

Thread在处理 Swing 组件时应避免使用javax.swing.Timer,应SwingWorker尽可能使用。

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Ticker {

    public static void main(String[] args) {
        new Ticker();
    }

    public Ticker() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new FlowLayout());
                frame.add(new TickerLabel());
                frame.setSize(100, 100);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TickerLabel extends JLabel {

        private int counter;

        public TickerLabel() {
            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (counter > 4) {
                        ((Timer)e.getSource()).stop();
                    } else {
                        String text = getText();
                        text += (char)(((int)'A') + counter);
                        setText(text);
                    }
                    counter++;
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();
        }

    }

}
于 2013-04-05T20:59:30.693 回答