2015-01-01 95 views
0

問題的簡短版本:我有一個JScrollPane,其中有大量滾動的項目。在某些時候,我想添加一些項目到JScrollPane中,並讓它們不在列表的末尾,但在(例如)第17項之後。將滾動項動態添加到JscrollPane上的特定位置

通常情況下,如果問題的代碼是在JScrollPane派生類中,我只是說this.add();但是我相信這會走到名單的最後。理由:案例1:我正在滾動的基礎數據是項目的有序列表,但列表中的任意位置都允許添加。當我將東西添加到列表的中間時,我想避免將整個列表再次加載到JScrollPane中。

案例2:我正在模擬一個帶有擴展子類別的滾動列表。因此,如果用戶選擇一個擴展子類別的項目,我的Action代碼將識別此案例,查看程序數據以查找子類別,然後將它們添加到選定類別下的JScrollPane。不要擔心,但也會有一些視覺指示,它是由我的操作代碼提供的子類別。

我可以編寫所有這些。我希望學習的是如何將某些內容添加到JScrollPane中,而不將其添加到列表的末尾。

+0

1-您不應該調用'JScrollPane#add'; 2-答案取決於這個「組件」是什麼 – MadProgrammer

回答

1

答案取決於這個組件是什麼,你正在添加項目。如果您使用的是JList,則可以使用類似DefaultListModel#add(int, Object)的東西將項目添加到特定位置。

如果您正在使用基於JComponent(如JPanel)的東西,你可以用JComponent#add(Component, int)指定組件時,應添加的地點,這種假設存在的位置(即你不能添加組件如果容器僅包含單個組件,則將其置於位置100)。

以下示例將生成一個隨機數,確定該數字應該插入的位置,以便維護有序列表並在該點插入組件。它也會嘗試滾動JScrollPane使項目可見

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridLayout; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JViewport; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test10 { 

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

    public Test10() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private JPanel numbers; 
     private List<Integer> values; 

     public TestPane() { 
      values = new ArrayList<>(25); 
      setLayout(new BorderLayout()); 
      numbers = new JPanel(new GridLayout(0, 1)); 
      add(new JScrollPane(numbers)); 

      Timer timer = new Timer(500, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        int next = (int) (Math.random() * Integer.MAX_VALUE); 
        int insertion = Collections.binarySearch(values, next); 
        if (insertion < 0) { 
         insertion = (Math.abs(insertion)) - 1; 
        } 
        values.add(insertion, next); 
        JLabel label = new JLabel(Integer.toString(next)); 
        numbers.add(label, insertion); 
        numbers.revalidate(); 
        SwingUtilities.invokeLater(new Runnable() { 
         @Override 
         public void run() { 
          Point p = label.getLocation(); 
          JViewport vp = (JViewport) numbers.getParent(); 
          JScrollPane sp = (JScrollPane) vp.getParent(); 
          vp.setViewPosition(p); 
         } 
        }); 
       } 
      }); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

    } 

} 
+0

謝謝。這很好,但我有一個評論和一個進一步的要求。這給了我第一個場景的答案(我不知道add方法中的可選位置參數),但是我意識到我的第二個場景並不像我想象的那麼容易。 –

+0

我以前的評論被切斷了。爲了解決第二種情況,作爲JList成員的對象想要在JList之後立即添加另一個成員。看起來,子對象需要找出它的'index'在JList中,然後調用帶有所需對象和索引的JList的add函數。子對象如何找到其索引? –

+0

如果她使用[DefaultListModel](http://docs.oracle.com/javase/7/docs/api/javax/swing/DefaultListModel.html),則可以使用indexOf方法 – MadProgrammer