2014-01-21 25 views
0

呦。我需要關於如何最好地實現某些內容的建議。我的程序:當你滾動過某個點時,擺動scrollpane通知

我有一個用不同類型的多個記錄讀取文件的swing程序。我將這些記錄讀入java對象,使用它們的標題和內容製作JTable(所以每個表只有標題和1條記錄),將這些表添加到面板並將面板添加到滾動窗格。有很多記錄,大約70000,所以我不能立即加載所有內容。

我的計劃是通過一次只顯示100條記錄來對頁面進行分頁,如果您滾動過某個特定點(比如第50頁),它會加載下100個表格並將它們添加到滾動窗格中。

這使我想起我的問題

1)林不知道如何通知自己說,香港專業教育學院滾動過去的某個點。所以鑑於我有100個JTables附加到一個滾動窗格的JPanel。我怎麼能添加一個偵聽器來通知當用戶滾動過去時,爲了參數而說出Jtable 50。

2)我有另一個問題與我如何把我的表放到面板。我使用如下的搖擺工:

private class TableRun extends SwingWorker<Void, JTable> { 

     private ArrayDeque<FileRecord> fileRecords; 
     private final GridBagConstraints gc; 
     private final JPanel parentPanel; 
     int counter = 1; 

     TableRun(ArrayDeque<FileRecord> fileRecords, GridBagConstraints gc, JPanel parentPanel) { 
      this.fileRecords = fileRecords; 
      this.gc = gc; 
      this.parentPanel = parentPanel; 
     } 

     @Override 
     protected Void doInBackground() { 
      Iterator<FileRecord> iterator = fileRecords.iterator(); 
      while (iterator.hasNext()) { 
       publish(getTabel(iterator.next())); 
      } 

      return null; 
     } 

     @Override 
     protected void process(final List<JTable> tables) { 
        Iterator<JTable> iterator = tables.iterator(); 
        while(iterator.hasNext()) { 
         JTable table = iterator.next(); 
         gc.fill = 1; 
         parentPanel.add(table.getTableHeader(), gc); 
         gc.gridy++; 
         parentPanel.add(table,gc); 
         gc.gridy++; 

         //validate takes a long time so i try to not do it too often. 
         if(counter == 50 || (counter % 5000) ==0 || (counter == fileRecords.size())) { 
          validate(); 
         } 
         System.out.println("Sequence Nr : " + table.getModel().getValueAt(0,1) + " - Counter :" + counter++); 
        } 
     } 
    } 

我將我的記錄物體餵給搖擺工。然後它將記錄轉換爲具有所有必要格式的JTable,然後將它們添加到面板。它有時會調用驗證以顯示錶,否則它不顯示它們。 (不知道是否有更好的方法來做到這一點?)

所以我的問題是關於滾動。如果我最初只將70000條記錄中的100條記錄給我的swinworker,那麼它顯然會創建一個思考theres只有100條記錄的scrollpane。所以滾動條不是非常小(即清楚你不能滾動很遠)。我真正想要的是,即使即時只顯示100條記錄,我希望滾動條的大小爲​​70000條記錄的大小,以便您可以根據滾動條看到記錄的大小。如果您將滾動條拖動到底部的某個位置,則需要拉動並顯示這些記錄。我如何創建我的scrollpane的大小比實際的組件大,但基於它們的大小?

希望我的問題是有道理的

感謝

+0

很難回答的東西菜刀,因爲一切都在保護無效的過程(最終名單表){是錯誤的(理論上每個re_creating整個JTable中的記錄,一定有可能在等待有人來分享她/他的企圖) – mKorbel

+0

從未在Worker Thread或try-catch-finally塊內創建任何Swing GUI,在Worker Thread啓動之前,GUI應該已經準備就緒(初始化,放置) – mKorbel

+0

愚蠢的問題--->請問是否有任何理由忽略[回答和鏈接代碼回答@trashgod](http://stackoverflow.com/a/21134944/714968) – mKorbel

回答

1

我如何添加一個監聽器通知,當用戶滾動過去說 的JTable 50爲了討論。

例如(可能的方式之一,你可以測試oneRectangle.intersects(anotherRectangle)),(道歉我)的問題,剩下的就是不回答的,注意,你必須重新調度從父鼠標事件(鼠標滾輪)(JScrollPane的包含的JPanel)到兒童的包含JTable中

enter image description here

enter image description here

enter image description here

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.image.BufferedImage; 
import javax.swing.*; 
import javax.swing.RepaintManager; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 
import javax.swing.table.TableModel; 

//http://stackoverflow.com/a/8249353/714968 
public class ViewPortFlickeringOriginal { 

    private JFrame frame = new JFrame("Table"); 
    private JViewport viewport = new JViewport(); 
    private Rectangle RECT = new Rectangle(); 
    private Rectangle RECT1 = new Rectangle(); 
    private JTable table = new JTable(50, 3); 
    private javax.swing.Timer timer; 
    private int count = 0; 
    private boolean topOrBottom = false; 
    private GradientViewPortOriginal tableViewPort; 

    public ViewPortFlickeringOriginal() { 
     tableViewPort = new GradientViewPortOriginal(table); 
     viewport = tableViewPort.getViewport(); 
     viewport.addChangeListener(new ChangeListener() { 

      @Override 
      public void stateChanged(ChangeEvent e) { 
       if (tableViewPort.bolStart) { 
        RECT = table.getCellRect(0, 0, true); 
        RECT1 = table.getCellRect(table.getRowCount() - 1, 0, true); 
        Rectangle viewRect = viewport.getViewRect(); 
        if (viewRect.intersects(RECT)) { 
         System.out.println("Visible RECT -> " + RECT); 
         tableViewPort.paintBackGround(new Color(250, 150, 150)); 
        } else if (viewRect.intersects(RECT1)) { 
         System.out.println("Visible RECT1 -> " + RECT1); 
         tableViewPort.paintBackGround(new Color(150, 250, 150)); 
        } else { 
         System.out.println("Visible RECT1 -> ???? "); 
         tableViewPort.paintBackGround(new Color(150, 150, 250)); 
        } 
       } 
      } 
     }); 
     frame.add(tableViewPort); 
     frame.setPreferredSize(new Dimension(600, 300)); 
     frame.pack(); 
     frame.setLocation(50, 100); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     RepaintManager.setCurrentManager(new RepaintManager() { 

      @Override 
      public void addDirtyRegion(JComponent c, int x, int y, int w, int h) { 
       Container con = c.getParent(); 
       while (con instanceof JComponent) { 
        if (!con.isVisible()) { 
         return; 
        } 
        if (con instanceof GradientViewPortOriginal) { 
         c = (JComponent) con; 
         x = 0; 
         y = 0; 
         w = con.getWidth(); 
         h = con.getHeight(); 
        } 
        con = con.getParent(); 
       } 
       super.addDirtyRegion(c, x, y, w, h); 
      } 
     }); 
     frame.setVisible(true); 
     start(); 
    } 

    private void start() { 
     timer = new javax.swing.Timer(100, updateCol()); 
     timer.start(); 
    } 

    public Action updateCol() { 
     return new AbstractAction("text load action") { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public void actionPerformed(ActionEvent e) { 

       System.out.println("updating row " + (count + 1)); 
       TableModel model = table.getModel(); 
       int cols = model.getColumnCount(); 
       int row = 0; 
       for (int j = 0; j < cols; j++) { 
        row = count; 
        table.changeSelection(row, 0, false, false); 
        timer.setDelay(100); 
        Object value = "row " + (count + 1) + " item " + (j + 1); 
        model.setValueAt(value, count, j); 
       } 
       count++; 
       if (count >= table.getRowCount()) { 
        timer.stop(); 
        table.changeSelection(0, 0, false, false); 
        java.awt.EventQueue.invokeLater(new Runnable() { 

         @Override 
         public void run() { 
          table.clearSelection(); 
          tableViewPort.bolStart = true; 
         } 
        }); 
       } 
      } 
     }; 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ViewPortFlickeringOriginal viewPortFlickering = new ViewPortFlickeringOriginal(); 
      } 
     }); 
    } 
} 

class GradientViewPortOriginal extends JScrollPane { 

    private static final long serialVersionUID = 1L; 
    private final int h = 50; 
    private BufferedImage img = null; 
    private BufferedImage shadow = new BufferedImage(1, h, BufferedImage.TYPE_INT_ARGB); 
    private JViewport viewPort; 
    public boolean bolStart = false; 

    public GradientViewPortOriginal(JComponent com) { 
     super(com); 
     viewPort = this.getViewport(); 
     viewPort.setScrollMode(JViewport.BLIT_SCROLL_MODE); 
     viewPort.setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE); 
     viewPort.setScrollMode(JViewport.SIMPLE_SCROLL_MODE); 
     paintBackGround(new Color(250, 150, 150)); 
    } 

    public void paintBackGround(Color g) { 
     Graphics2D g2 = shadow.createGraphics(); 
     g2.setPaint(g); 
     g2.fillRect(0, 0, 1, h); 
     g2.setComposite(AlphaComposite.DstIn); 
     g2.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 0f), 0, h, 
       new Color(0.1f, 0.8f, 0.8f, 0.5f))); 
     g2.fillRect(0, 0, 1, h); 
     g2.dispose(); 
    } 

    @Override 
    public void paint(Graphics g) { 
     if (img == null || img.getWidth() != getWidth() || img.getHeight() != getHeight()) { 
      img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); 
     } 
     Graphics2D g2 = img.createGraphics(); 
     super.paint(g2); 
     Rectangle bounds = getViewport().getVisibleRect(); 
     g2.scale(bounds.getWidth(), -1); 
     int y = (getColumnHeader() == null) ? 0 : getColumnHeader().getHeight(); 
     g2.drawImage(shadow, bounds.x, -bounds.y - y - h, null); 
     g2.scale(1, -1); 
     g2.drawImage(shadow, bounds.x, bounds.y + bounds.height - h + y, null); 
     g2.dispose(); 
     g.drawImage(img, 0, 0, null); 
    } 
} 
+0

如何獲得面板內的矩形或特定表的點?如果我在表格上說getLocation()它只是說x = 0和y = 0 – 3uPh0riC

+0

這是non_sence :-),忘記了,爲什麼你想要轉換動態的原因(每個JTable可以直接滾動,然後保持JScrollBar中的變量值)將座標(JScrollPane中的100個JTable)添加到JPanel的父級, – mKorbel