2016-01-10 2 views
1

Что вы думаете о чем-то вроде этого:Как насчет запуска doLayout() в потоке?

public class HeavyJTable extends JTable implements Runnable { 
public HeavyJTable (AbstractTableModel m) { 
    super(m); 
    /* .... */ 
    this.setAutoResizeMode(AUTO_RESIZE_OFF); 
    this.setFillsViewportHeight(false); 
} 

@Override 
public void run() { 
    final TableColumnModel columnModel = this.getColumnModel(); 
    int width = 60; 
    for (int column = 0; column < this.getColumnCount(); column++) { 
     TableCellRenderer renderer = this.getCellRenderer(0, column); 
     Component comp = this.prepareRenderer(renderer, 0, column); 
     if(comp == null) 
      continue; 
     width = Math.max(comp.getPreferredSize().width + 1, width); 
     columnModel.getColumn(column).setPreferredWidth(width); 
    } 
    super.doLayout(); 
} 

@Override 
public void doLayout() { 
    if (getColumnModel().getTotalColumnWidth() == getWidth()) { 
     return; //filter some useless refreshes 
    } else 
     new Thread(this).start(); 
} 

}

Контекста: Я имею в Дифференц вкладок JTabbedPane, которые слушают обновление/вставки/удаления и обновляют свои собственные данные в одиночку несколько JTable , Все эти таблицы изменяются по размеру с помощью счетчика. Так что много данных и много обновлений.

Поэтому я хотел поместить весь процесс рисования в другой поток (каждая разумная часть защищена семафорами).

Что вы думаете об этом? Есть ли другие лучшие варианты? Я думаю о SwingWorkers. Или запущенные наборы doLayout() в разных пулах потока.

+0

Да, вот почему я спрашиваю, что вы предлагаете. У меня есть базовый компьютер и даже без того, чтобы мой основной поток был занят, программе нужны и другие сервисы и ресурсы. Поэтому я не думаю, что преждевременно выделять поток для представления таблиц в этом контексте. – Totem

+1

Беспокойство о дизайне/управляемости. Если вы беспокоитесь о памяти/производительности, профайл приложения, чтобы узнать, есть ли что-то беспокоиться о –

+0

Спасибо Винсу, я проверю профилирование. Но я уже потратил много времени на оптимизацию логики. Я почти уверен, что это происходит из представления, когда я смотрю на стек. Есть ли способ пропустить X 'doLayout()' per 'JTable'? – Totem

ответ

2

Swing не является потокобезопасным, вы никогда не должны делать ничего (прямо или косвенно), которое будет обновлять или изменять пользовательский интерфейс вне контекста Event Dispatching Thread. См. Concurrency in Swing для получения более подробной информации.

Итак, я хотел поместить весь процесс рисования в другой поток (каждая разумная часть защищена семафорами).

Нет, это не так, как работает живопись. Картина ВСЕГДА выполняется из контекста Диспетчерского потока событий (события рисования помещаются в очередь на EventQueue). См Painting in AWT and Swing для более подробной информации

Контекста: У меня есть несколько JTable через Дифференц вкладки JTabbedPane, которые слушают обновление/вставки/удаления и обновляют свои данные в одиночку. Все эти таблицы изменяются по размеру с помощью счетчика. Так что много данных и много обновлений.

Отделите управление своими данными с вашего вида. Используйте фоновые потоки, чтобы загрузить данные с EDT, а затем повторно выполнить повторные результаты после их завершения.

Что вы думаете об этом? Есть ли другие лучшие варианты? Я думаю о SwingWorkers. Или запуск наборов doLayout() в разных пулах потока.

SwingWorker будет гораздо лучшим решением, но вы должны использовать его для загрузки данных (в методе doInBackground) и обновить пользовательский интерфейс либо через функциональные process/publish или done метод в зависимости от ваших потребностей

Смежные вопросы