Если вы видите несогласованное / поврежденное изображение, иногда это указывает на обновление набора данных в потоке, отличном от потока отправки событий. Я предлагаю вам добавить несколько утверждений assert, чтобы проверить это:
assert SwingUtilities.isEventDispatchThread ();
Также обратите внимание, что JFreeChart не особенно эффективен, так как он заново отображает весь график всякий раз, когда добавляется новая точка данных. Одна оптимизация, которую вы могли бы сделать здесь:
- Если ваше приложение состоит из нескольких диаграмм, то распространяется только
DatasetChangeEvent
s для диаграммы, отображаемой в данный момент. Если диаграмма скрыта (например, на другой вкладке), просто запишите тот факт, что она устарела и ее необходимо повторно отобразить при выборе вкладки.
EDIT
Исходя из вашего комментария к ответу Дэна, звучит так, что ваш поток ввода-вывода, получающий сообщения, также обновляет набор данных JFreeChart, когда фактически обновление должно выполняться в потоке диспетчеризации событий (а сообщения должны выполняться в отдельном / Нить). Чтобы достичь этого, я предлагаю вам использовать подход, основанный на дросселе, при котором события ввода / вывода объединяются в группы. Вы можете использовать BlockingQueue
для достижения этой цели; например,
// Message definition containing update information.
public interface Message { ... }
// BlockingQueue implementation used to enqueue updates received on I/O thread.
BlockingQueue<Message> msgQ = ...
// Method called by I/O thread when a new Message is received.
public void msgReceived(Message msg) {
boolean wasEmpty = msgQ.isEmpty();
msgQ.add(msg);
// Queue was empty so need to re-invoke Swing thread to process queue.
if (wasEmpty) {
// processUpdates is a re-useable Runnable defined below.
SwingUtilities.invokeLater(processUpdates);
}
}
// Runnable that processes all enqueued events. Much more efficient than:
// a) Creating a new Runnable each time.
// b) Processing one Message per call to run().
private final Runnable processUpdates = new Runnable() {
public void run() {
Message msg;
while ((msg = msgQ.poll) != null) {
// Add msg to dataset within Event Dispatch thread.
}
}
}