#java
#java
Вопрос:
Итак, я пытаюсь обновить JPanel, используя массив байтов с указанным байтом / цветом, это очень простая версия. Когда я запускаю программу, она становится белой на полсекунды, затем становится правильного цвета, а затем через 1 секунду она снова становится белой, я пытался распечатать текущий цвет, и иногда он меняется на ‘0’. Что я делаю не так?
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
public static Random ran = new Random();
public static byte[] buffer;
public static int num = 0;
public static JFrame frame = new JFrame();
public static JPanel panel = new JPanel() {
private static final long serialVersionUID = 1L;
@Override
public void paint(Graphics g) {
num = 0;
byte[] current_buffer = buffer.clone();
for (int y = 0; y < panel.getHeight(); y ) {
for (int x = 0; x < panel.getWidth(); x ) {
g.setColor(new Color(current_buffer[num], current_buffer[num], current_buffer[num]));
g.fillRect(x, y, 1, 1);
num ;
}
}
}
};
public static void main(String[] args) {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1200, 800);
frame.setLocationRelativeTo(null);
frame.setContentPane(panel);
frame.setResizable(false);
frame.setVisible(true);
engine.run();
}
public static boolean running = true;
public static Thread engine = new Thread() {
@Override
public void run() {
buffer = new byte[panel.getWidth() * panel.getHeight()];
for (int i = 0; i < buffer.length; i ) {
buffer[i] = (byte) 34;
}
while (running) {
panel.repaint(10L);
}
}
};
}
Комментарии:
1. Используйте paintComponent вместо paint
2. Он по-прежнему не работает: (мигает на секунду, а затем становится белым
3. Используйте SwingWorker вместо потока или используйте SwingUtilities.invokeLater() для вызова repaint в очереди событий Swing. Вы также можете использовать таймер swing для обновления каждые 30 или 60 изображений в секунду
4. Это тоже не работает.
Ответ №1:
Не совсем понимаю вашу логику:
for (int i = 0; i < buffer.length; i ) {
buffer[i] = (byte) 34;
}
Вы присваиваете буферу то же значение.
Затем вы создаете цветной объект, используя то же значение.
g.setColor(new Color(current_buffer[num], current_buffer[num], current_buffer[num]));
Таким образом, каждый пиксель будет одного цвета.
И поскольку буфер всегда создается с одинаковыми значениями, цвет не изменится.
Кроме того, зачем вам использовать
byte[] current_buffer = buffer.clone();
Вы просто используете значения в буфере, а не обновляете значения в буфере, поэтому я не вижу причин для клонирования.
Не используйте поток с циклом while. Для анимации вы должны использовать Swing Timer
. При срабатывании таймера вы обновляете значения в буфере, а затем вызываете repaint().
Когда я запускаю программу, она становится белой на полсекунды, затем становится правильного цвета, а затем через 1 секунду она снова становится белой,
Я не вижу такого поведения.
- он мигает светлым цветом
- он остается окрашенным в более темный цвет
Вышесказанное имеет смысл, потому что:
- Ваш метод paintCompnent() не вызывает super.paintComponent(…), чтобы убедиться, что фон очищен
- Массив не инициализируется никакими значениями при его создании, поэтому значение по умолчанию будет равно 0.
- После того, как поток возьмет верх, массив всегда будет содержать одно и то же значение, поэтому будет окрашен в тот же цвет.
Что вы ожидаете от этого?
Комментарии:
1. как я уже сказал, это всего лишь небольшая версия; Я знаю, что все цвета будут одинаковыми; я просто создал эту маленькую версию движка, чтобы попытаться заставить ее работать; Я не буду делать анимацию на этом движке, только обновляю и делаю несколько других математических вещей в этой теме,а затем создайте другой поток с полуфиксированной частотой обновления для анимации
2. Анимация должна выполняться с помощью таймера Swing, а не потока! Обновления состояния компонента должны выполняться в EDT, поэтому вам нужен таймер, а не поток. См. Редактирование.