2009-03-13 6 views
1

スイングで「仮想リスト」がうまく機能していますが、特定の数のアイテムを超えると失敗するようです。 「失敗」とは、アイテムの数が> Nmaxのときにスクロールバーが魔法のように消えることを意味し、アイテムの数が< = Nmaxのときに戻ってきます。 Nmaxは私のシステムで約119,304,000位のどこかにあるようだ。AbstractListModelを使用したSwingの大きな仮想リスト - 119,000,000アイテムに制限?

私は何に対して対処していますか?!?!

package com.example.test; 

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import javax.swing.AbstractListModel; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JSpinner; 
import javax.swing.SpinnerModel; 
import javax.swing.SpinnerNumberModel; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

// based on: 
// http://www.java2s.com/Tutorial/Java/0240__Swing/extendsAbstractListModel.htm 
// http://www.java2s.com/Tutorial/Java/0240__Swing/SpinnerNumberModel.htm 
// http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/SpinnerNumberModel.html 
// http://www.java2s.com/Tutorial/Java/0240__Swing/ListeningforJSpinnerEventswithaChangeListener.htm 
// http://java.sun.com/products/jfc/tsc/tech_topics/jlist_1/jlist.html 

public class BigVirtualList extends JFrame { 

    public static void main(String[] args) { 
     new BigVirtualList(); 
    } 

    static final int initialLength = 1; 
    final private JList list1 = new JList(); 
    final private BVLData bvldata = new BVLData(initialLength*1000); 

    public BigVirtualList() { 
     this.setTitle("Big virtual list"); 
     this.getContentPane().setLayout(new BorderLayout()); 
     this.setSize(new Dimension(400, 300)); 
     list1.setModel(bvldata); 

     list1.setPrototypeCellValue(list1.getModel().getElementAt(0)); 


     SpinnerModel model1 = new SpinnerNumberModel(initialLength,1,1000000,1); 
     final JSpinner spinner1 = new JSpinner(model1); 

     this.getContentPane().add(new JScrollPane(list1), BorderLayout.CENTER); 
     JLabel label1 = new JLabel("Length (1000s of items):"); 
     JPanel panel1 = new JPanel(new BorderLayout()); 
     panel1.add(label1, BorderLayout.WEST); 
     panel1.add(spinner1, BorderLayout.CENTER); 
     this.getContentPane().add(panel1, BorderLayout.SOUTH);  

     ChangeListener listener = new ChangeListener() { 
      public void stateChanged(ChangeEvent e) { 
       Integer newLength = (Integer)spinner1.getValue(); 
       bvldata.setLength(newLength*1000); 
      } 
     }; 

     spinner1.addChangeListener(listener); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setVisible(true); 
    } 
} 

class BVLData extends AbstractListModel { 
    public BVLData(int length) { this.length = length; } 

    private int length; 

    public int getLength() { return length; } 
    public void setLength(int length) { 
     int oldLength = getLength(); 
     this.length = length; 
     int newLength = getLength(); 

     if (newLength > oldLength) 
      fireIntervalAdded(this, oldLength+1, newLength); 
     else if (newLength < oldLength) 
      fireIntervalRemoved(this, newLength+1, oldLength);  
    } 

    @Override 
    public Object getElementAt(int index) { 
     return "Item "+index+" mod 107 = "+(index%107); 
    } 

    @Override 
    public int getSize() { return getLength(); } 

} 
+0

好奇心で、なぜ119,000,000アイテムのリストが必要ですか? –

+0

これは仮想リストであり、アイテムが必ずしも実際にすべて格納されているわけではありません。または、疎なリスト(たとえば、ほとんどのアイテムでは「空白」の要素、要素1〜1000、および12000000〜12100000、および207300000〜207400000の実際のアイテム)である可能性があります。私は、データのストリームを視覚化することでうんざりしています。 –

+0

とにかく、正確にはこの点があまり重要ではありません。私はこの制限をどのようにドライブしているのか知りたいのですが、システムによっては3,000,000と言うよりはるかに低いでしょう。 –

答えて

6

まあ、私は目的が表示されない:

(私はそれがうまく動作119304で入力すると、自分のコンピュータ上で、私は上向き矢印をクリックして、スクロールバーが消えここでテストプログラムがあります)とにかく...

私はあなたがどこかにスクロールペイン内の整数の最大値を破る推測:

System.out.println("CellHeight:"+list1.getFixedCellHeight()); 
System.out.println("CellHeight*119304000:"+NumberFormat.getNumberInstance().format(list1.getFixedCellHeight()*119304000.0)); 
System.out.println("MAXINT:"+Integer.MAX_VALUE); 

はあなたの番号を与える:

 
CellHeight:18 
CellHeight*119304000:2.147.472.000 
MAXINT:2.147.483.647 

もう1つの18000ピクセルの高さを追加すると、MAXINTを超えることになります...これは問題に陥ります。

+0

+1:私は同じ結論に達していた。 2^31/18〜= 119304647。 –

+0

ああ!それは理にかなっている。したがって、リストは実際にはアイテムを適切な場所にある非常に大きなキャンバスとしてレンダリングしようとしますか? –

+0

+1:「list1.setFixedCellHeight(10);」という行を追加しました。今は214,748になります。 –

関連する問題