有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JFrame组件能够通过重绘调用paintComponent,尽管使用flowlayout

我在FlowLayout中有一个JFrame,其中添加了多个JLabel,但是当我在JLabel上调用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);

    }

}

共 (1) 个答案

  1. # 1 楼答案

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

    我无法理解为什么你要在标签上画文字,因为标签的设计就是这样的

    在处理Swing组件时,应该避免使用Thread,并尽可能使用javax.swing.TimerSwingWorker

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