2012-11-28 71 views
1

當用戶滾動它時,我需要處理來自JScrollPane的事件。在here建議使用addAdjustmentListenerJViewport或Vertical/Horizo​​ntalScrollBar。JScrollPane adjustmentListener和scrollRectToVisible

有什麼區別,我應該選擇哪種方法?

我也想使用scrollRectToVisible爲相同的JScrollPane,我應該預計AdjustmentListener工作這種方法?

另外我想知道是否scrollRectToVisible試圖做最低限度的滾動,使所需的矩形可見或試圖使其在JViewport的中間可見?

UPD:要求:

1)有一個的JPanel其中有許多的JLabel(ImageIcon的)一個JScrollPane,因此他們中的一些是不可見的。

2)當網絡事件發生時,我需要向用戶顯示JLabel中的一個(使其可見)。如果我最初不可見,那麼JScrollPane應該自動滾動。這就是我提到scrollRectToVisible的原因。

3)以上帶有ImageIcon的JLabel裏面我需要顯示一個消息來解釋這個元素髮生了什麼。該消息當前被實現爲帶有浮點數的另一個JLabel,這要歸功於層次結構中JLayeredPane的高得多。現在的問題是,如果用戶滾動JScrollPane,那麼浮動JLabel應該相應地移動到對應的JLabel(ImageIcon)之上。

UDP2:SSCCE

我還沒有實現浮動的JLabel還,但我已經不喜歡如何與指數11起反應對scrollRectToVisible標籤,因爲它是成功的一半裁剪。答案

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.AdjustmentEvent; 
import java.awt.event.AdjustmentListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 

public class JScrollPaneTest { 
    protected ArrayList<JLabel> labels = new ArrayList<JLabel>(); 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new JScrollPaneTest(); 
      } 
     }); 
    } 

    public JScrollPaneTest() { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 

       JPanel panel1 = new JPanel(); 

       panel1.setLayout(new GridBagLayout()); 
       GridBagConstraints gbc = new GridBagConstraints(); 

       for (int i = 0; i < 20; i++) { 
        JLabel label = new JLabel(" | Label" + i + " | "); 
        panel1.add(label, gbc); 
        labels.add(label); 
       } 

       panel1.addMouseListener(new MouseAdapter(){ 
        public void mousePressed (MouseEvent me) { 
         JLabel label = labels.get(11); 
         label.scrollRectToVisible(label.getBounds()); 
        } 
       }); 

       JScrollPane pane = new JScrollPane(panel1) { 
        private static final long serialVersionUID = 1L; 

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

       pane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
        @Override 
        public void adjustmentValueChanged(AdjustmentEvent e) { 
         System.out.println("adjustmentValueChanged: " + e); 
        } 
       }); 

       frame.getContentPane().add(pane); 

       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 
+0

可以依賴,如果JComponent中放入JScrollPane中已經實現滾動 – mKorbel

+1

你真的應該開始要求思考(與假設的解決方案):你想實現什麼_exactly_? – kleopatra

+0

@kleopatra我已添加要求。 –

回答

4

一部分(註釋代碼僅僅是...,發現我錯在評論;-)

的方法scrollRectToVisible需要一個矩形組件的座標系中它被呼籲。要滾動一個孩子這樣的,這是完全可見,基本上有兩種選擇(使用他們的一個):

// either call on child with zero offset 
child.scrollRectToVisible(new Rectangle(child.getSize()); 
// or call on child's parent with child bounds 
child.getParent().scrollRectToVisible(child.getBounds()); 
+0

哇,我真的需要爲孩子和父母調用scrollRectToVisible()兩次嗎? –

+0

@NikolayKuznetsov - 不,這是其中之一,選擇你的偏好,試圖澄清。 – kleopatra

+0

是的,它的工作原理。但現在處於邊緣,如果可行的話,如何將它顯示在JScrollPane的中心? –