Как изменить положение JLabel?

#java #swing #jpanel #jlabel

#java #swing #jpanel #jlabel

Вопрос:

Я пытаюсь использовать таймер для изменения положения JLabel с одного места на моей JPanel на другое. Я не уверен, что мог бы использовать say .getLocation() , затем изменить только значение horizontal x и, наконец, использовать .setLocation() для эффективного изменения JLabel. Я также использовал .getBounds и .setBounds , но все еще не уверен, как я могу получить старое горизонтальное значение x для изменения и повторного применения к новому значению x.

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

 // mPos is an arraylist of JLabels to be moved.

for(int m = 0; m < mPos.size(); m  ){
        mPos.get(m).setLocation(getLocation()-100);
    }
  

или

     for(int m = 0; m < mPos.size(); m  ){
        mPos.get(m).setBounds(mPos.get(m).getBounds()-100);
    }
  

Если бы я мог просто получить положение горизонтального значения x, я мог бы изменить положение метки.

Комментарии:

1. Также, когда таймер запускает мой прослушиватель действий, это то, что вызывает изменение значения horizontal x. И это изменение значения x всегда является постоянным.

2. Пожалуйста, покажите минимальный рабочий пример, демонстрирующий, что вы пробовали.

3. Используете ли вы null layout? Существует множество менеджеров компоновки.

Ответ №1:

Попробуйте использовать Swing Timer, если вы ищете какую-нибудь анимацию.

Пожалуйста, взгляните на как использовать таймеры Swing

Вот пример кода:

 int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
  public void actionPerformed(ActionEvent evt) {
      //...Perform a task...
  }
};
new Timer(delay, taskPerformer).start();
  

Найдите пример кода здесь

введите описание изображения здесь


Пример кода: (Переместить сообщение Hello World на 10 пикселей по горизонтали слева направо с интервалом в 200 мс)

 private int x = 10;
...
final JPanel panel = new JPanel() {
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawString("Hello World", x, 10);
    }
};

int delay = 200; // milliseconds
ActionListener taskPerformer = new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        x  = 10;
        if (x > 100) {
            x = 10;
        }
        panel.repaint();
    }
};
new Timer(delay, taskPerformer).start();
  

Ответ №2:

Я привел аналогичный пример, просто чтобы вы могли понять основную суть этого, попробуйте скопировать, вставив это в новый класс под названием «LabelPlay», и он должен работать нормально.

 import java.awt.EventQueue;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;


public class LabelPlay {

private JFrame frame;
private JLabel label;
private Random rand;

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                LabelPlay window = new LabelPlay();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public LabelPlay() {
    initialize();
}

private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 659, 518);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);

    label = new JLabel("YEEEHAH!");
    label.setBounds(101, 62, 54, 21);
    frame.getContentPane().add(label);

    JButton btnAction = new JButton("Action!");
    rand = new Random();
    btnAction.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            int a = rand.nextInt(90) 10;
            int b = rand.nextInt(90) 10;
            int c = rand.nextInt(640) 10;
            int d = rand.nextInt(500) 10;
            label.setBounds(a, b, c, d);                
        }
    });
    btnAction.setBounds(524, 427, 89, 23);
    frame.getContentPane().add(btnAction);

}
  

}

Если вы хотите, чтобы это происходило в цикле в определенное время, вы можете просто поместить это в цикл и использовать Thread.sleep (количество миллисекунд) в цикле перед запуском кода.

Комментарии:

1. Это хороший пример! Я поработаю с этим и посмотрю, смогу ли я заставить это работать для нескольких меток. Я просто хочу сохранить значение высоты, ширины и вертикали y для каждой метки, должен измениться только x.

2. Что ж, считайте это сложной задачей и поиграйте с ней, пока не получите желаемый результат, в конце концов, это будет более приятным.

3. почему вы используете null layout? Будет ли это работать с разным разрешением в разных операционных системах.

4. Я сделал это примерно за 2 минуты и не вдавался в подробности… Я просто хотел показать ему основную суть этого, чтобы он мог сам разобраться в остальном.

Ответ №3:

Почему бы вам не создать JLabel в позиции a, установив для него значение visible, и другую в позиции b, установив для нее значение not visible? По истечении таймера скройте первую и покажите вторую.

Комментарии:

1. Это была бы хорошая идея, о которой я не подумал. К сожалению, проблема в том, что у меня есть несколько JLabels, которые должны перемещаться примерно 100 раз. Я мог бы это сделать, но это заняло бы очень много времени и утомительно. Я ищу способ, которым я мог бы использовать постоянное значение для изменения положения всех моих JLabels, используя цикл, чтобы поразить их все.

Ответ №4:

Вы планируете создать какое-нибудь движущееся изображение для какого-нибудь типа игры? Или какая-то метка, которая перемещается практически везде? Я бы использовал абсолютный макет и каждый раз устанавливал местоположение вручную.

 myPanel.setLayout(null);

// an initial point
int x = 100;
int y =100;

while (
    //some moving pattern
    x  ;   // 1 pixel per loop
    y =2;  // 2 pixels per loop
    myLabel.setLocation(x,y);
}
  

Комментарии:

1. Никогда не предлагайте null макет.