我在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);
}
}
答案 0 :(得分:2)
核心问题是JLabel
没有向框架的布局管理器提供有关它有多大的信息。它也不是实际告诉框架的布局管理器它已更新并需要调整大小。
为什么你试图在标签上绘制文字超出我的范围,被视为标签在设计上的作用。
在处理Swing组件时应避免使用Thread
,并尽可能使用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();
}
}
}