java标签setText和setBounds发生冲突?

时间:2011-01-15 23:33:45

标签: java swing animation

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

2 个答案:

答案 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();

}

}