我希望JLabel changint颜色可以随机播放,同时跳转到随机位置,同时更改其文本。
但是setText和setBounds似乎发生冲突,我不知道为什么。如果您注释掉setText,那么setBounds将起作用,但它们不会一起工作。
import java.awt.*;
import java.util.*;
import javax.swing.*;
public class test2 extends JFrame {
private static JLabel label = new JLabel("0");
private static Random gen = new Random();
public test2() {
JPanel panel = new JPanel();
panel.add(label);
this.add(panel);
}
public static void move() {
for (int i = 0; i < 10; i++) {
int n = gen.nextInt(254)+1;
int nn = gen.nextInt(254)+1;
int nnn = gen.nextInt(254)+1;
label.setText(""+i);
//the setBounds command will not work with the setText command. why?
label.setBounds(n*2, nn*2, 20, 20);
label.setForeground(new Color(n, nn, nnn));
try {
Thread.sleep(200);
} catch (Exception e) {}
}
}
public static void main(String[] args) {
test2 frame = new test2();
frame.setVisible(true);
frame.setSize(600, 600);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
move();
}
}
答案 0 :(得分:3)
setBounds不应该使用非null布局,并且您的问题正在发生,因为更改JLabel中的文本会刺激JPanel的重新布局,并且由于JPanels默认使用FlowLayout,因此JLabel保持在顶部在中间。因此,如果您确实需要此功能,请考虑将JPanel的布局设置为null,否则使用JLayeredPane。
public test2() {
JPanel panel = new JPanel(null);
panel.add(label);
this.add(panel);
}
此外,您不应该在EDT上调用Thread.sleep(...),即Swing线程。而是考虑使用Swing Timer。
由于我不同意另一个例子,我将发布一个我推荐的例子,一个使用Swing Timer的例子:
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
@SuppressWarnings("serial")
public class Test3 extends JPanel {
private static final int SIDE = 600;
public static final int MAX_COUNTER = 20;
private static final int TIMER_DELAY = 400;
private static final int MAX_RAND = 220;
private int counter = 0;
private JLabel label = new JLabel(String.valueOf(counter));
private Random gen = new Random();
private int[] randNumb = new int[3];
public Test3() {
setPreferredSize(new Dimension(SIDE, SIDE));
setLayout(null);
add(label);
new Timer(TIMER_DELAY, new TimerListener()).start();
}
private void myMove() {
for (int i = 0; i < randNumb.length; i++) {
randNumb[i] = gen.nextInt(MAX_RAND);
}
label.setText(String.valueOf(counter));
label.setSize(label.getPreferredSize());
label.setLocation((SIDE * randNumb[0])/MAX_RAND, (SIDE*randNumb[1])/MAX_RAND);
label.setForeground(new Color(randNumb[0], randNumb[1], randNumb[2]));
repaint();
}
private class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (counter < MAX_COUNTER) {
myMove();
counter++;
} else {
((Timer)e.getSource()).stop();
}
}
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Test3");
frame.getContentPane().add(new Test3());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
答案 1 :(得分:0)
不知道为什么会这样,但这是一个丑陋的解决方法:
package com.me;
import java.awt.Color;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class test2 extends JFrame {
private static int i;
private static JLabel label = new JLabel("0"){
@Override
public String getText(){
return i+"";
}
};
private static Random gen = new Random();
public test2() {
JPanel panel = new JPanel();
panel.add(label);
this.add(panel);
}
public static void move() {
for (i = 0; i < 10; i++) {
int n = gen.nextInt(254)+1;
int nn = gen.nextInt(254)+1;
int nnn = gen.nextInt(254)+1;
//the setBounds command will not work with the setText command. why?
label.setBounds(n*2, nn*2, 20, 20);
label.setForeground(new Color(n, nn, nnn));
try {
Thread.sleep(200);
} catch (Exception e) {}
}
}
public static void main(String[] args) {
test2 frame = new test2();
frame.setVisible(true);
frame.setSize(600, 600);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
move();
}
}