java метки setText и setBounds конфликтуют? - PullRequest
3 голосов
/ 16 января 2011

Я хотел бы, чтобы цвет JLabel изменялся на случайный, при переходе на случайную позицию и при изменении его текста.

, но 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 ]

3 голосов
/ 16 января 2011

setBounds не должен работать с ненулевым макетом, и ваша проблема возникает из-за того, что изменение текста в JLabel стимулирует изменение макета JPanel, и, поскольку JPanels по умолчанию использует FlowLayout, JLabel остается наверху в середине. Так что если вам действительно нужна эта функциональность, тогда рассмотрите возможность установки макета JPanel на ноль, или же используйте JLayeredPane.

  public test2() {
     JPanel panel = new JPanel(null);
     panel.add(label);
     this.add(panel);
  }

Также вы не должны вызывать Thread.sleep (...) на EDT, нити Swing. Вместо этого рассмотрите возможность использования Swing Timer.

Поскольку я не согласен с другим примером, я опубликую пример того, что я рекомендовал вместо него, тот, который использует таймер Swing:

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();
            }
        });
    }
}
0 голосов
/ 16 января 2011

Не знаю, почему это происходит, но вот уродливый обходной путь:

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

}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...