Mam Swing JTable
dynamicznie aktualizowaną z dużą ilością danych - nowe wiersze są stale dodawane na żywo, a niektóre 1000-2000 wierszy można dodać w ciągu kilku minut. Zarejestrowałem odbiorcę do odpowiedzi na jednoosobowe wydarzenie wyboru, aby wykonać część personelu. Użyłem wzoru Observer do wiązania danych Swing, a model tabeli jest wspierany przez implementację WritableList. Nowe pozycje dodawane są do tabeli z własnej dziedziny. Dodał też Listener z wątku interfejsu użytkownika SWT. Problem polega na tym, że po dodaniu nowych wierszy do tabeli nie reaguje od razu na zdarzenie wyboru wiersza użytkownika. Dopiero po zatrzymaniu aktualizacji modelu tabeli tabela zareaguje na wybór użytkownika - czasami z opóźnieniem ponad 30-60 sekund. Proszę, pomóż mi podkreślić, dlaczego mój model tabeli nie reaguje natychmiast na wybór użytkownika podczas intensywnej aktualizacji i jak przezwyciężyć to ograniczenie. Wszelkie sugestie zostaną docenione.Opóźniona reakcja na zdarzenie selekcji wierszy JTable pod ogromnym obciążeniem danych
5
A
Odpowiedz
11
Zastosowanie SwingWorker
do publish()
twoje wiersze w tle i aktualizuje TableModel
w swojej realizacji process()
. SwingWorker
będzie limit aktualizacje do stałej stopy. Profile, aby upewnić się, że nie blokujesz urządzenia event dispatch thread.
Dodatek: GUI reaguje zgodnie z testem 1 000 000 wierszy variation. Podczas profilowania pamiętaj, że każde kliknięcie przycisku "Idź" uruchamia nowego pracownika.
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
/** @see https://stackoverflow.com/a/17415635/230513 */
public class TestTableLoad01 {
public static void main(String[] args) {
new TestTableLoad01();
}
public TestTableLoad01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final MyTableModel model = new MyTableModel();
JTable table = new JTable(model);
table.setDefaultRenderer(Date.class, new TimeCellRenderer());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.add(new JButton(new AbstractAction("Go") {
@Override
public void actionPerformed(ActionEvent e) {
TableSwingWorker worker = new TableSwingWorker(model);
worker.execute();
}
}), BorderLayout.SOUTH);
}
});
}
public class TimeCellRenderer extends DefaultTableCellRenderer {
private DateFormat df;
public TimeCellRenderer() {
df = new SimpleDateFormat("HH:mm:ss");
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof Date) {
value = df.format(value);
}
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
return this;
}
}
public class MyTableModel extends AbstractTableModel {
private String[] columnNames = new String[]{"Date", "Row"};
private List<RowData> data;
public MyTableModel() {
data = new ArrayList<RowData>(25);
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return columnIndex == 0 ? Date.class : Integer.class;
}
@Override
public String getColumnName(int col) {
return columnNames[col];
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public Object getValueAt(int row, int col) {
RowData value = data.get(row);
return col == 0 ? value.getDate() : value.getRow();
}
public void addRow(RowData value) {
int rowCount = getRowCount();
data.add(value);
fireTableRowsInserted(rowCount, rowCount);
}
public void addRows(RowData... value) {
addRows(Arrays.asList(value));
}
private void addRows(List<RowData> rows) {
int rowCount = getRowCount();
data.addAll(rows);
fireTableRowsInserted(rowCount, getRowCount() - 1);
}
}
public class RowData {
private Date date;
private int row;
public RowData(int row) {
this.date = new Date();
this.row = row;
}
public Date getDate() {
return date;
}
public int getRow() {
return row;
}
}
public class TableSwingWorker extends SwingWorker<MyTableModel, RowData> {
private final MyTableModel tableModel;
public TableSwingWorker(MyTableModel tableModel) {
this.tableModel = tableModel;
}
@Override
protected MyTableModel doInBackground() throws Exception {
// This is a deliberate pause to allow the UI time to render
Thread.sleep(1000);
System.out.println("Start polulating");
for (int index = 0; index < 1000000; index++) {
RowData data = new RowData(index);
publish(data);
Thread.yield();
}
return tableModel;
}
@Override
protected void process(List<RowData> chunks) {
System.out.println("Adding " + chunks.size() + " rows");
tableModel.addRows(chunks);
}
}
}
Powiązane problemy
- 1. Zdarzenie selekcji kratek kendoui
- 2. Czy CherryPy jest solidnym serwerem internetowym (tzn. Czy jest niezawodny pod ogromnym obciążeniem, takim jak Apache)?
- 3. Wybieranie wielu wierszy JTable
- 4. Sesje ASP.NET uszkodzone pod obciążeniem
- 5. monitorować zachowanie log4j pod obciążeniem
- 6. Cassandra jako sklep sesji pod dużym obciążeniem
- 7. jquery jtable niestandardowe zdarzenie click
- 8. JTable Przewijanie do określonego indeksu wierszy
- 9. Java Swing JTable wybierz programowo wiele wierszy
- 10. JTable - zdarzenie click click Selected Row
- 11. Jak dodać podpowiedzi do wierszy JTable
- 12. Suma impulsów opóźnień w aplikacji App pod niskim obciążeniem
- 13. Jak przewinąć UIScrollView pod obciążeniem podczas korzystania z automatycznego układu
- 14. Implementacja kolejkowania bez użycia bloków kończy się pętlą pod obciążeniem
- 15. BindException/Zbyt wiele plików otwarte podczas używania HttpClient pod obciążeniem
- 16. Usterki połączenia PHP/MYSQL pod dużym obciążeniem przez mysql.sock
- 17. Połączenie tcp nie działa losowo pod dużym obciążeniem
- 18. Klucz do wprowadzania danych JTable
- 19. D3.js: łączenie selekcji?
- 20. Wczytywanie danych array array do JTable
- 21. Reakcja na przesyłanie pliku js
- 22. usunąć wybrany wiersz z jtable na przycisku kliknij
- 23. Cron Zadania na serwerach zbalansowanych z obciążeniem
- 24. Visual Studio 2013 Powolna reakcja na IDE
- 25. Konwertowanie wielu wierszy tekstu na ramkę danych
- 26. Operate na parach wierszy ramki danych
- 27. Słuchacz zmiany wartości JTable
- 28. JTable - przeciągnij i upuść
- 29. Jak obliczyć korelację dwóch zmiennych w ogromnym zestawie danych w R?
- 30. Przechowywanie danych hierarchicznych w MySQL z dużym obciążeniem zapisu
Dziękuję za odpowiedź, Trashgod. Używałem VisualVM - ale nie mam zbyt wiele informacji, czy wątek wysyłki zdarzenia został zablokowany, czy nie. Z tego profilera widzę tylko listę aktywnych wątków. Jak sprawdzić, czy wątek jest blokowany przez inny? Z góry dziękuję – kioria
Nie pamiętam dokładnego schematu kolorów w 'jvisualvm'; w NetBeans jest czerwony; porównać z [zrzutem wątku] (http://javatechniques.com/blog/jdb-example-generating-a-thread-dump/), na [przykład] (http://stackoverflow.com/q/12728589/230513). – trashgod
Zastanawiam się, ile wątków trzeba utworzyć i uruchomić, aby opublikować wiele nowych wierszy ... Wiem, że tworzenie i usuwanie wątków nie jest operacją chipową. I w przypadku SwingWorker wydaje mi się, że potrzebuję za każdym razem tworzyć nową instancję w celu wywołania metody doInBackground(). Czy to jest wydajne? – kioria