#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
макет.