<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    zeyuphoenix

    愿我愛的人快樂,愿愛我的人快樂,為了這些,我愿意不快樂.

    表格(排序)

    JTable的單元格和表頭寫完之后,關于JTable就剩下排序和過濾了,對于過濾來說,簡單的直接使用SunRowSorter就可以了,復雜的可以集成Lucence等排序工具,對于它來說,性能比實現更重要,有時間就開個專題寫,沒時間就不寫了,這里主要寫排序.

    排序從界面表現看其實就是對JTableHeader的鼠標操作,引發TableModel的數值比較,最后表現到畫面的過程,知道這個過程很重要,它可以幫助我們完全實現自己的排序過程.

    對于JavaJTable排序來說,主要分為兩個階段:Java1.6以前和Java1.6版本:Java1.6之前想要實現JTable的話,必須自己實現TableSorter,然后對JTableHeader去注冊,很麻煩,但是可以完全自己控制;Java1.6為了方便,Sun增加了排序和過濾的類:

    javax.swing.table. TableRowSorter<M extends TableModel> -à

    javax.swing. DefaultRowSorter<M, I> -à

    javax.swing. RowSorter<M>

    我們可以直接使用了.

    實現很容易,Sun官方的例子:

    RowSorter<TableModel> rowSorter = new TableRowSorter<TableModel>(table.getModel());

    table.setRowSorter(rowSorter);

    這是JTable就自動為你實現了過濾,它的好處是不污染任何的JTable數據和渲染,自然進行排序,結果如圖:

    但是對于默認的JTable來說, TableRowSorter的默認排序都是把數據當做Object來處理的,這時我們看表格的數據行:

    對于年份來說,這個排序是不對的,這個時候我們必須要復寫TableModelgetColumnClass方法,告訴TableRowSorter我們現在需要排序的數據類型, TableRowSorter就會根據類型給我們的列設置合適的比較器Comparator

    Collator.getInstance()

           @Override

            public Class<? extends Object> getColumnClass(int c) {

                return getValueAt(0, c).getClass();

            }

    這是對JTable的排序就完成了:

    但有時候還有別的情況,比如我們單元格放置的是一個特殊組件, TableRowSorter根本沒有合適的比較器給我們提供,或者是基本類型但是我們不希望使用默認的比較器Comparator,這個時候我們就需要自己實現一個Comparator,然后通過TableRowSortersetComparator設置某一列一個新的比較器.比如我們希望我們的第二列按字符串的反序排序:

    TableRowSorter<TableModel> rowSorter = new TableRowSorter<TableModel>(table.getModel());

        rowSorter.setComparator(1, new Comparator<String>() {

                @Override

                publicint compare(String str1, String str2) {

                    return -str1.compareTo(str2);

                }

            });

    table.setRowSorter(rowSorter);

    效果如圖:

    到此為止,Java1.6排序的基本使用就完成了,通過Sun的方法很簡單就實現了.

    Java1.6以前的JTable排序功能必須自己實現,Sun官方也提供了例子,當然在1.6里你也可以自己實現,但是自己實現必須考慮排序Model,排序狀態,JTableHeader的狀態和監聽,還要自己寫HeaderRnederer,所以不是不能用1.6的話,最好不要自己實現.先看看是如何實現的,因為是Sun官方給的例子,就大概寫下,算是學習和回憶以前使用1.5自己寫Sorter的日子了.

    效果和1.6類似:

    首先看TableSorter,它繼承AbstractTableModel,這樣它也就相當于自己也是一種底層數據模型,可以記錄數據和排序數據:

    publicclass TableSorter extends AbstractTableModel {

    然后看它的屬性:

        private JTableHeader tableHeader;

    這個是需要排序的JTableHeader,這里需要對它進行鼠標監聽和狀態管理.

        private MouseListener mouseListener;

    private TableModelListener tableModelListener;

    這兩個是鼠標監聽器和TableModel監聽器,主要是當鼠標排序和JTabel數據變化時排序也隨之變化.

        private Map<Class<?>, Comparator<?>> columnComparators

            = new HashMap<Class<?>, Comparator<?>>();

        private List<Directive> sortingColumns

            = new ArrayList<Directive>();

    這連個主要是記錄狀態的,一個是記錄列的排序比較器,一個是記錄列的排序狀態.

    publicstaticfinal Comparator<Object> LEXICAL_COMPARATOR = new Comparator<Object>() {

                publicint compare(Object o1, Object o2) {

                    return o1.toString().compareTo(o2.toString());

                }

        };

    另外還提供了幾種基本的排序比較器,這是String的比較器.

    然后是是構造函數,

    public TableSorter(TableModel tableModel) {

    傳入我們需要排序的JTableTableModel,并對JTable增加事件監聽和TableModel數據變化監聽:

       this.tableHeader.addMouseListener(mouseListener);

       this.tableHeader.setDefaultRenderer(new SortableHeaderRenderer(

                        this.tableHeader.getDefaultRenderer()));

    this.tableModel.addTableModelListener(tableModelListener);

    然后處理這些監聽:

        privateclass MouseHandler extends MouseAdapter {

            @Override

            publicvoid mouseClicked(MouseEvent e) {

    首先取得排序列和當前排序狀態:

        JTableHeader h = (JTableHeader) e.getSource();

                TableColumnModel columnModel = h.getColumnModel();

        int viewColumn = h.columnAtPoint(e.getPoint());

        int column = columnModel.getColumn(viewColumn).getModelIndex();

    int status = getSortingStatus(column);

    然后判斷后調用排序方法:

    setSortingStatus(column, status);

    TableModel數據變化監聽也類似:

        privateclass TableModelHandler implements TableModelListener {

            @Override

            publicvoid tableChanged(TableModelEvent e) {

    非排序狀態直接插入:

     if (!isSorting()) {

                    clearSortingState();

                    fireTableChanged(e);

                    return;

     }

    排序狀態比較插入:

       int column = e.getColumn();

       if (e.getFirstRow() == e.getLastRow()

            && column != TableModelEvent.ALL_COLUMNS

            && getSortingStatus(column) == NOT_SORTED

            && modelToView != null) {

              int viewIndex = getModelToView()[e.getFirstRow()];

              fireTableChanged(new TableModelEvent(TableSorter.this,

                            viewIndex, viewIndex, column, e.getType()));

                    return;

      }

    然后是一個行的比較器:

        // Helper classes

    privateclass Row implements Comparable<Object> {

    它取得比較的行:

            @Override

            publicint compareTo(Object o) {

                int row1 = modelIndex;

                int row2 = ((Row) o).modelIndex;

    再去的比較的值:

          Object o1 = tableModel.getValueAt(row1, column);

          Object o2 = tableModel.getValueAt(row2, column);

    根據我們提供的構造器比較:

    comparison = getComparator(column).compare(o1, o2);

    其它的還有一些設置比較器,設置JTableHeaderRenderer,繪制排序的圖標的方法,基本都是以前JTable會學習到的,就不寫了,很多但是不難.

    然后是使用,先創建我們自己構造的TableSorter:

    TableSorter sorter = new TableSorter(new MyTableModel());

    當做JTableTableModel放入JTable中:

    JTable table = new JTable(sorter);

    還要設置一下Header,目的是使用我們自己做成的HeaderRenderer,可以出現圖標

    sorter.setTableHeader(table.getTableHeader());

    以后就和正常JTable一樣了.

    最后,我們看一個我們自己實現排序比較和Renderer的例子:

    工程目錄如下:

    其中和類是實現了Icon接口的繪制JTableHeader排序時的圖片的類,

    publicclass MyBlankIcon implements Icon {

    publicclass MySortIcon implements Icon {

    主要過程就是實現paintIcon方法繪制圖片,前面寫過這種三角形形式的圖片繪制方法了,這里省略.

    void paintIcon(Component c, Graphics g, int x, int y);

    然后就是比較重要的MyTableSorter,它繼承TableRowSorter,擴充了我們自己的排序實現:

    publicclass MyTableSorter extends TableRowSorter<TableModel> {

    提供了三個方法,正序、逆序和無序:

        /**

         * Enumeration value indicating the items are sorted in increasing

         */

        protectedvoid setASCSort(int colIdx) {

            ArrayList<SortKey> key = new ArrayList<SortKey>();

            key.add(new RowSorter.SortKey(colIdx, SortOrder.ASCENDING));

            setSortKeys(key);

        }

        /**

         * Enumeration value indicating the items are sorted in decreasing * order.

         */

        protectedvoid setDESCSort(int colIdx) {

            ArrayList<SortKey> key = new ArrayList<SortKey>();

            key.add(new RowSorter.SortKey(colIdx, SortOrder.DESCENDING));

            setSortKeys(key);

        }

        /**

         * Enumeration value indicating the items are unordered.

         */

        protectedvoid setUNSort(int colIdx) {

            ArrayList<SortKey> key = new ArrayList<SortKey>();

            key.add(new RowSorter.SortKey(colIdx, SortOrder.UNSORTED));

            setSortKeys(key);

        }

    提供設置當前排序狀態的方法:

        protectedvoid setSorterStatus(int column, boolean CtrlDown) {

        List<SortKey> SortStatus = new ArrayList<SortKey>(getSortKeys());

            SortKey sortKey = null;

            int sortIndex = -1;

            for (sortIndex = SortStatus.size() - 1; sortIndex >= 0; sortIndex--) {

                if (SortStatus.get(sortIndex).getColumn() == column) {

                    break;

                }

            }

            if (sortIndex == -1) {

                // Key doesn't exist

                if (CtrlDown) {

                    sortKey = new SortKey(column, SortOrder.DESCENDING);

                } else {

                    sortKey = new SortKey(column, SortOrder.ASCENDING);

                }

                SortStatus.add(0, sortKey);

            } elseif (sortIndex == 0) {

                // It's the primary sorting key, toggle it

                SortStatus.set(0, toggle(SortStatus.get(0), CtrlDown));

            } else {

                // It's not the first, but was sorted on, remove old

                // entry, insert as first with ascending.

                SortStatus.remove(sortIndex);

                if (CtrlDown) {

                    sortKey = new SortKey(column, SortOrder.DESCENDING);

                } else {

                    sortKey = new SortKey(column, SortOrder.ASCENDING);

                }

                SortStatus.add(0, sortKey);

            }

            if (SortStatus.size() > getMaxSortKeys()) {

                SortStatus = SortStatus.subList(0, getMaxSortKeys());

            }

            setSortable(column, true);

            setSortKeys(SortStatus);

            setSortable(column, false);

        }

    提供取得下一個狀態的方法:

        protected SortKey toggle(SortKey key, boolean CtrlDown) {

            if (key.getSortOrder() == SortOrder.ASCENDING) {

             returnnew SortKey(key.getColumn(), SortOrder.DESCENDING);

            } elseif (key.getSortOrder() == SortOrder.DESCENDING) {

                returnnew SortKey(key.getColumn(), SortOrder.UNSORTED);

            } else {

                returnnew SortKey(key.getColumn(), SortOrder.ASCENDING);

            }

        }

    然后就是Renderer方法了,它繼承TableCellRenderer,設置排序狀態和Header狀態:

    publicclass MyHeaderButtonRenderer extends JButton implements

            TableCellRenderer, MouseListener {

    它提供一個屬性存儲當前列的排序狀態:

        /** save the header state. */

        private Hashtable<Integer, Integer> state = null;

    在它的鼠標事件里,設置排序和排序狀態:

        /**

         * Invoked when the mouse button has been clicked (pressed and

     * released) on a component.

         */

        @Override

        publicvoid mouseClicked(MouseEvent e) {

    先取得鼠標事件的列,設置表現:

          int col = header.columnAtPoint(e.getPoint());

          int sortCol = header.getTable().convertColumnIndexToModel(col);

          renderer.setPressedColumn(col);

          renderer.setSelectedColumn(col);

          header.repaint();

    再設置排序和狀態:

    if (header.getTable().isEditing()) {

                 header.getTable().getCellEditor().stopCellEditing();

          }

          if (!(DOWN == renderer.getState(col))

                   && !(UP == renderer.getState(col))) {

                sorter.setUNSort(sortCol);

          }

    實現TableCellRenderer的方法設置列的Header的表現:

    @Override

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

    if (header != null && renderer != null) {

                boolean isPressed = (column == pushedColumn);

                button.getModel().setPressed(isPressed);

                button.getModel().setArmed(isPressed);

            }

    使用也不是很麻煩:

    先創建Sorter:

    TableSorter tableSorter = new MyTableSorter(table);

    設置某一列的比較器,TableSorter一樣:

    tableSorter.setComparator(2, new MyComparator<String>());

     table.setRowSorter(tableSorter);

    然后是創建Renderer:

    MyHeaderButtonRenderer renderer = new MyHeaderButtonRenderer();

    然后設置JTableHeaderRenderer:

     table.getColumnModel().getColumn(i).setHeaderRenderer(renderer)

    這樣就完成了.

    posted on 2010-04-15 21:11 zeyuphoenix 閱讀(3721) 評論(0)  編輯  收藏 所屬分類: JTable的使用

    導航

    <2010年4月>
    28293031123
    45678910
    11121314151617
    18192021222324
    2526272829301
    2345678

    統計

    常用鏈接

    留言簿(52)

    隨筆分類

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 免费观看的a级毛片的网站| 亚洲成A∨人片天堂网无码| 亚洲伊人久久大香线蕉在观| 51在线视频免费观看视频| 亚洲国产精品一区二区三区在线观看| 一个人免费高清在线观看| 亚洲AV第一成肉网| 伊人亚洲综合青草青草久热| 国内少妇偷人精品视频免费| 亚洲日韩国产精品无码av| 色吊丝最新永久免费观看网站 | 丝袜足液精子免费视频| 亚洲AV日韩AV天堂久久| 欧亚精品一区三区免费| 国产成人亚洲精品播放器下载| 亚洲人成人一区二区三区| 亚洲免费观看网站| 免费国产黄网站在线观看动图| 亚洲人成人无码网www电影首页| 麻豆高清免费国产一区| 亚洲国产一区二区三区在线观看 | 在线视频亚洲一区| 国产亚洲色婷婷久久99精品| 三年片在线观看免费西瓜视频| 亚洲性色成人av天堂| 日本免费人成黄页在线观看视频 | 亚洲国产成人精品女人久久久| h片在线免费观看| 日韩电影免费在线观看网站| 蜜臀亚洲AV无码精品国产午夜.| 麻豆亚洲av熟女国产一区二| 中文字幕第一页亚洲| 免费在线观看中文字幕| 岛国片在线免费观看| 国产99视频精品免费观看7| 国产精品免费观看调教网| 国产精品免费大片一区二区| 亚洲av无码专区国产不乱码| youjizz亚洲| 亚洲一区二区三区国产精品无码| 亚洲avav天堂av在线不卡|