2014-01-21 28 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