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

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

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

    有才華的人,別忘記給滋潤你的那塊土壤施肥

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      28 隨筆 :: 5 文章 :: 147 評論 :: 0 Trackbacks

            
              當(dāng)很表格中有很多列的時候出現(xiàn)Scrollbar的時候,當(dāng)用戶拖動Scrollbar那么有的列就會看不見,而用戶需
    要輸入數(shù)據(jù)的時候,需要對照第一列或前幾列以方便輸入數(shù)據(jù),則需要固定前幾列的需求了。像Excle表格
    中可以固定前幾列,而在JTable中沒有直接的方法實現(xiàn),網(wǎng)上比較流行的方法是用兩個JTable,如下圖(一)其中
    一個talbe渲染固定列的數(shù)據(jù),另外一個主table渲染其他數(shù)據(jù),然后把渲染固定列數(shù)據(jù)的表格當(dāng)做裝載主table的
    JScrollPane的Row Header。這樣實現(xiàn)就要把表格中的數(shù)據(jù)拆分成兩個TableModel用于其渲染。
    其中實現(xiàn)的效果如圖二,其詳細(xì)的代碼見  Fixed Demo


        圖一

                                                           圖二                                                     

             很顯然這種實現(xiàn)方式有一下缺點:
             1)、當(dāng)用戶對于自己的表格有自己實現(xiàn)的自定義的列頭,比如行的序列號或增加了選擇框等等這樣就會有沖突。
             2)、如上所說當(dāng)拆分成兩個TableModel的時候,那么要很好的維護兩個表格一些屬性保持一致將很麻煩,比如
                      選擇,排序等。
              3)、最重要的一點就是如果在其原有的項目中增加這一需求,那么這種方法就要修改很多地方,侵入性太強。
            
            基于上述缺點,Elie Levy 用了另外一種方法,盡管也有些缺點(暫且后面再說),他實現(xiàn)的方法很簡單(效果如圖三),
    就是將要固定的列的內(nèi)容畫在一個另外一個組件上然后將這個組件放在JTable之上,其總是占據(jù)其表格的指定需要固定
    的列上,這表格的前幾列看起來就是固定了的,如圖三,我們需要固定前三列,那么我們將前三列的內(nèi)容畫在一個
    JLabel上如圖中黑色部分,這時候的關(guān)鍵技術(shù)就是利用JLayeredPane的原理了,獲得JTable的JLayeredPane,然后將這個
    畫出所要固定列的內(nèi)容的JLabel加進JLayeredPane,就能忽悠成固定了。


    圖三

          主要實現(xiàn)代碼分析,實現(xiàn)主要監(jiān)聽鼠標(biāo)事件,捕捉所要固定的列的內(nèi)容予以即時更新,這個類FixTableManager
    為了方便我們繼承于JTableHeader,那么在這里我們重寫paint()方法:以更新拖動Scrollbar的時候列頭的現(xiàn)實信息,
    代碼如:
     @Override
     
    public void paint(Graphics g) {
      
    super.paint(g);
      
    //int division = mouseListener.getDivision();
      int division = mouseListener.getDivision();
      
    if (division > 0){
       Rectangle r 
    = getVisibleRect();
       BufferedImage image 
    = new BufferedImage(division, r.height,
         BufferedImage.TYPE_INT_ARGB);
       Graphics g2 
    = image.getGraphics();
       g2.setClip(
    00, division, r.height);
       g2.setColor(Color.WHITE);
       g2.fillRect(
    00, division, r.height);
       
    super.paint(g2);
       g.drawImage(image, r.x, r.y, division, r.height, 
    null);
       g2.dispose();
      }

     }
         畫完了固定的列的列頭,我們就要畫表格中的內(nèi)容了,這里我們就是把這些內(nèi)容畫在一個JLabel上,如下:
     private class FixedColumnsDelegate extends JLabel{
      
    public void paintComponent(Graphics g) {
       Rectangle r 
    = table.getBounds();
       
    if (division > 0{
        table.invalidate();
        table.validate();
        Rectangle visibleRect 
    = table.getVisibleRect();
        BufferedImage image 
    = new BufferedImage(division, r.height,
          BufferedImage.TYPE_INT_ARGB);
        Graphics g2 
    = image.getGraphics();

        g2.setClip(
    0, visibleRect.y, division,
          table.getBounds().height);
        
        g2.setColor(Color.RED);
        g2.fillRect(
    00, division, table.getBounds().height);
        
        table.paint(g2);
        g.drawImage(image, 
    00, division,
          table.getBounds().height, 
    0, visibleRect.y,
          division, visibleRect.y 
    + table.getBounds().height,
          
    null);
    //    g.setColor(Color.BLACK);
    //    for (int i = 0; i < visibleRect.y
    //      + table.getBounds().height; i += 8) {
    //     g.drawLine(division - 1, i, division - 1, i + 4);
    //     g.drawLine(division - 2, i, division - 2, i + 4);
    //    }
        g2.dispose();
       }

      }

     }
       
          接下來就是鼠標(biāo)等一些事件來監(jiān)聽畫出固定列的信息了。當(dāng)捕捉到需要將固定的列固定住,就調(diào)用如下方法:
    /**
      *固定列
      *利用JLayeredPane使其顯示在JTable之上
      *
    */

      
    public void freeze() {
       JLayeredPane pane 
    = table.getRootPane().getLayeredPane();
       
    if (added) {
        pane.remove(fixedColumns);
       }
     
       pane.add(fixedColumns, JLayeredPane.POPUP_LAYER);
       setBoundsOnFrozenColumns();
       added 
    = true;
       fixedColumns.setVisible(
    true);
      }

        還有一些繁雜的計算ixedColumns的位置大小大家可以下載代碼自己看了,大致原理就是如此簡單,就是利用JLayeredPane
    層的概念,用起來也很方便,只需要在原有的代碼傳入JTable,以及裝在這個JTable的JScrollPane,如
     JTable table = new JTable(data, columnNames);
      JScrollPane scrollPane 
    = new JScrollPane(table);
      FixTableManager tableHeader 
    = new FixTableManager(table,scrollPane);
      
    //固定前三列
      tableHeader.setFixCol(2);
       
        總之這樣能忽悠成看起來像是固定了,那它也有感覺不帶勁的地方,大家如有興趣,可以在下面的鏈接中下載代碼,
    運行其看看效果  ,效果是Scrollbar不會的最小值停留的位置不是在固定列的最后位置,隨之scrollbar的拖動,我們可以看到
    有的列會被固定的列擋住,正如前面所說,這個所謂的固定是個假象。還有一些缺點如有的皮膚可能算出來的結(jié)果會和原有
    的Table看起來不一致等。
         代碼我在Elie Levy的基礎(chǔ)上做了一些修改更容易使用,以及修復(fù)了一些bug,可以點擊這里下載:Source Download
    posted on 2009-08-12 23:22 kissjava 閱讀(3302) 評論(4)  編輯  收藏 所屬分類: swing

    評論

    # re: 固定JTable中的前幾列 2009-08-13 13:10 iSwing
    layeredpanel絕對是Swing的經(jīng)典設(shè)計之一  回復(fù)  更多評論
      

    # re: 固定JTable中的前幾列[未登錄] 2012-09-06 20:51 lovejava
    謝謝,非常好!  回復(fù)  更多評論
      

    # re: 固定JTable中的前幾列 2015-01-29 19:27 founder
    行數(shù)很多時(如2W行,30列),paintComponent會導(dǎo)致內(nèi)存溢出  回復(fù)  更多評論
      

    # re: 固定JTable中的前幾列 2015-01-29 19:35 founder
    Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferInt.<init>(Unknown Source)
    at java.awt.image.Raster.createPackedRaster(Unknown Source)
    at java.awt.image.DirectColorModel.createCompatibleWritableRaster(Unknown Source)
    at java.awt.image.BufferedImage.<init>(Unknown Source)
    at com.ykxd.wage.ui.common.FixTableManager$1.paintComponent(FixTableManager.java:59)  回復(fù)  更多評論
      

    主站蜘蛛池模板: 亚洲爆乳AAA无码专区| 亚洲成A∨人片天堂网无码| 亚洲AV无码一区东京热久久| 亚洲欧美日韩中文无线码| 久热中文字幕在线精品免费| 少妇中文字幕乱码亚洲影视| 欧洲人成在线免费| 久久噜噜噜久久亚洲va久| 一级大黄美女免费播放| 久久久久亚洲AV无码专区桃色| v片免费在线观看| 亚洲综合另类小说色区| 黄网站免费在线观看| 亚洲国产一区二区三区青草影视| 91制片厂制作传媒免费版樱花| 久久亚洲AV无码精品色午夜麻豆| 亚洲黄色免费在线观看| 亚洲av成人综合网| 日本免费一二区在线电影| 四虎精品免费永久免费视频| 国产AV无码专区亚洲AWWW| 日韩精品久久久久久免费| 亚洲资源最新版在线观看| 国产精品无码一二区免费| 中文在线观看国语高清免费| 亚洲精品美女在线观看| 国产精品四虎在线观看免费| 好猛好深好爽好硬免费视频| 亚洲色欲或者高潮影院| 日韩视频免费一区二区三区| jizz免费观看视频| 亚洲欧洲日产韩国在线| 日本黄色免费观看| 在线涩涩免费观看国产精品| 亚洲国产亚洲片在线观看播放| 国产aa免费视频| 99热免费在线观看| 美女无遮挡免费视频网站| 亚洲第一区香蕉_国产a| 日本人的色道www免费一区| 黄网站色视频免费在线观看的a站最新|