Swing/PageInputForPagination の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/PageInputForPagination へ行く。
- Swing/PageInputForPagination の差分を削除
--- category: swing folder: PageInputForPagination title: JTableのPaginationとSwingWorkerでの逐次読み込み tags: [JTable, RowFilter, SwingWorker, JButton] author: aterai pubdate: 2013-11-04T03:33:05+09:00 description: JTableでRowFilterを使ったPaginationとSwingWorkerでの逐次読み込みを行います。 image: https://lh5.googleusercontent.com/-1qIJd4HlwkQ/UnaN9fNNZtI/AAAAAAAAB5Y/JqssphQAq3Q/s800/PageInputForPagination.png --- * 概要 [#summary] `JTable`で`RowFilter`を使った`Pagination`と`SwingWorker`での逐次読み込みを行います。 #download(https://lh5.googleusercontent.com/-1qIJd4HlwkQ/UnaN9fNNZtI/AAAAAAAAB5Y/JqssphQAq3Q/s800/PageInputForPagination.png) * サンプルコード [#sourcecode] #code(link){{ worker = new SwingWorker<String, List<Object[]>>() { private int max = 2013; @Override public String doInBackground() { int current = 1; int c = max / itemsPerPage; int i = 0; while (i < c && !isCancelled()) { current = makeRowListAndPublish(current, itemsPerPage); i++; } int m = max % itemsPerPage; if (m > 0) { makeRowListAndPublish(current, m); } return "Done"; } private int makeRowListAndPublish(int current, int size) { try { Thread.sleep(500); // dummy Thread.sleep(500); } catch (Exception ex) { ex.printStackTrace(); } List<Object[]> result = new ArrayList<Object[]>(size); int j = current; while (j < current + size) { result.add(new Object[] {j, "Test: " + j, j % 2 == 0 ? "" : "comment..."}); j++; } publish(result); return j; } @Override protected void process(List<List<Object[]>> chunks) { for (List<Object[]> list : chunks) { for (Object[] o : list) { model.addRow(o); } } int rowCount = model.getRowCount(); maxPageIndex = (rowCount / itemsPerPage) + (rowCount % itemsPerPage == 0 ? 0 : 1); initFilterAndButton(); } @Override public void done() { String text = null; if (isCancelled()) { text = "Cancelled"; } else { try { text = get(); } catch (Exception ex) { ex.printStackTrace(); text = "Exception"; } } table.setEnabled(true); } }; worker.execute(); // ... private static final int itemsPerPage = 100; private int maxPageIndex; private int currentPageIndex = 1; private void initFilterAndButton() { sorter.setRowFilter(new RowFilter<TableModel, Integer>() { @Override public boolean include( Entry<? extends TableModel, ? extends Integer> entry) { int ti = currentPageIndex - 1; int ei = entry.getIdentifier(); return ti * itemsPerPage <= ei && ei < ti * itemsPerPage + itemsPerPage; } }); first.setEnabled(currentPageIndex > 1); prev.setEnabled(currentPageIndex > 1); next.setEnabled(currentPageIndex < maxPageIndex); last.setEnabled(currentPageIndex < maxPageIndex); field.setText(Integer.toString(currentPageIndex)); label.setText(String.format("/ %d", maxPageIndex)); } }} * 解説 [#explanation] 上記のサンプルでは、[[RowFilterでJTableのページ分割>Swing/TablePagination]]に以下の変更を追加しています。 - `JTextField`に数値を入力して指定ページにジャンプ可能 - `First(|<)`、`Prev(<)`、`Next(>)`、`Last(>|)`などのリンクに`JRadioButton`ではなく`JButton`を使用 - `SwingWorker`を使ってページ単位での逐次読み込み(最大ページの表示を更新) ---- - `SwingWorker`を使って`sqlite`から`JTable`にデータを読み込むテスト #code{{ class LoadTask extends SwingWorker<String, List<Object[]>> { private final int max; private final int itemsPerPage; protected LoadTask(int max, int itemsPerPage) { super(); this.max = max; this.itemsPerPage = itemsPerPage; } @Override public String doInBackground() { File file = new File( "C:/Users/.../AppData/Roaming/Mozilla/Firefox/Profiles/xx.default/places.sqlite"); String db = "jdbc:sqlite:/" + file.getAbsolutePath(); try (Connection conn = DriverManager.getConnection(db); Statement stat = conn.createStatement()) { int current = 1; int c = max / itemsPerPage; int i = 0; while (i < c && !isCancelled()) { try { Thread.sleep(500); // dummy Thread.sleep(500); } catch (InterruptedException ex) { // ex.printStackTrace(); return "Interrupted"; } current = load(stat, current, itemsPerPage); i++; } int surplus = max % itemsPerPage; if (surplus > 0) { load(stat, current, surplus); } } catch (SQLException ex) { // ex.printStackTrace(); return "Error"; } return "Done"; } private int load(Statement stat, int current, int limit) throws SQLException { List<Object[]> result = new ArrayList<>(limit); String q = String.format( "select * from moz_bookmarks limit %d offset %d", limit, current - 1); ResultSet rs = stat.executeQuery(q); int i = current; while (rs.next() && !isCancelled()) { result.add(new Object[] {i, rs.getInt("id"), rs.getString("title")}); i++; } publish(result); return current + result.size(); } } }} * 参考リンク [#reference] - [[RowFilterでJTableのページ分割>Swing/TablePagination]] * コメント [#comment] #comment #comment