2010-01-25 58 views
13

Tôi đã có mã tiếp theo:JScrollPane và JList tự động cuộn

listModel = new DefaultListModel(); 
    listModel.addElement(dateFormat.format(new Date()) + ": Msg1"); 
    messageList = new JList(listModel); 
    messageList.setLayoutOrientation(JList.VERTICAL); 

    messageScrollList = new JScrollPane(messageList); 
    messageScrollList.setPreferredSize(new Dimension(500, 200)); 

    messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      e.getAdjustable().setValue(e.getAdjustable().getMaximum()); 
     } 
    }); 

Nó tự động cuộn xuống. Nhưng, nếu tôi cố gắng cuộn lùi lại để đọc lại một tin nhắn, nó buộc phải cuộn xuống. Làm cách nào để khắc phục sự cố này?

Trả lời

10

Khi thêm thư mới, hãy gọi scrollRectToVisible() trên JList bằng cách sử dụng Rectangle có cùng kích thước với kích thước ưa thích của ngăn thư của bạn. Với hướng thẳng đứng, có thể thuận tiện để làm cho kích thước ưa thích của JScrollPane 's JViewport một bội số tích phân của chiều cao của ngăn thư. Xem thêm: How to Use Scroll Panes.

Phụ lục: Thảo luận hấp dẫn này về Text Area Scrolling cũng có thể hữu ích.

-1

Tôi nghĩ rằng những gì bạn muốn làm là di chuyển xuống khi bạn thêm nội dung vào danh sách thư của mình, thay vào đó là điều chỉnh. Vì vậy, mã của bạn có thể trông như thế này:

Adjustable sb = messageScrollList.getVerticalScrollBar() 
boolean onBottom = sb.getValue() == sb.getMaximum(); 
// 
// add your message to the JList. 
// 
if(onBottom) sb.setValue(sb.getMaximum()); 

Nếu không, bạn sẽ cần phải biết nếu việc điều chỉnh là do một sự thay đổi mô hình, hoặc bằng chuột, và nhìn qua các tài liệu API Tôi không chắc chắn nếu có một cách để làm điều đó một cách dễ dàng. Mặc dù bạn có thể thấy nếu AdjustmentEvent.getAdjustmentType() trả về các giá trị khác nhau trong những trường hợp đó, nếu đó là sự thật thì bạn chỉ có thể có một câu lệnh if trong lớp bên trong ẩn danh của bạn.

Một điều bạn có thể thử là có biến boolean ở đâu đó được đặt khi bạn thêm thứ gì đó vào danh sách. Sau đó, trong trình xử lý của bạn, bạn kiểm tra xem biến có được đặt hay không. Nếu vậy, bạn thực hiện điều chỉnh (và bỏ đặt biến) nếu không, bạn bỏ qua nó. Bằng cách đó, sẽ chỉ có một cuộn xuống cho mỗi mục được thêm vào danh sách.

+0

Adjusttype giống nhau trong cả hai trường hợp. Tôi đã thử điều này để cuộn xuống nếu một tin nhắn được thêm vào. Nhưng nếu tôi làm điều đó, tin nhắn được thêm lần cuối sẽ không hiển thị. Nó cuộn không đủ xuống. Làm thế nào tôi có thể giải quyết điều đó? – dododedodonl

+0

Hmm ... Vâng, một điều bạn có thể làm là có biến boolean ở đâu đó được đặt khi bạn thêm thứ gì đó vào danh sách. Sau đó, trong trình xử lý của bạn, bạn kiểm tra xem biến có được đặt hay không. Nếu vậy, bạn thực hiện điều chỉnh (và bỏ đặt biến) nếu không, bạn bỏ qua nó. Bằng cách đó, sẽ chỉ có một cuộn xuống cho mỗi mục được thêm vào danh sách. –

1
this.list = blah blah... 
this.list.setSelectedValue(whatever); 
final JScrollPane sp = new JScrollPane(this.list); // needs to be after the parent is the sp 
this.list.ensureIndexIsVisible(this.list.getSelectedIndex()); 
1

Tôi thấy điều này thực sự hữu ích: http://forums.sun.com/thread.jspa?threadID=623669 (bài bởi 'inopia')
Nó hoạt động một cách hoàn hảo

Như ông nói: "Vấn đề ở đây là nó có thể trở thành một chút khó khăn để tìm thấy một sự kiện xảy ra sau khi cả ListModel, JList và JScrollPane đã được cập nhật. "

+0

Liên kết đã chết. Bạn có thể làm mới nó? –

0

Để tự động cuộn Tôi đang sử dụng một khái niệm rất đơn giản của biến tĩnh và list.makeVisible (chỉ số int)

public class autoScrollExample 
    { 
    static int index=0; 
    private void someFunction() 
    /* 
    * 
    */ 
    list1.add("element1"); 
    list1.makeVisible(index++); 
    /* 
    * 
    */ 

    private void someOtherFunction() 
    /* 
    * 
    */ 
    list1.add("element2"); 
    list1.makeVisible(index++); 
    /* 
    * 
    */ 


    } 
1

@question Enquirer. Vui lòng thay đổi mã của bạn từ

messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      e.getAdjustable().setValue(e.getAdjustable().getMaximum()); 
     } 
    }); 

để

messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      e.getAdjustable().setValue(e.getAdjustable().getValue()); 
     } 
    }); 

Đó là sự thay đổi getMaximum()-getValue() Sau đó, nó hoạt động theo yêu cầu. getMaximum() lấy mẫu cuộn đến mức tối đa; trong khi getValue() mất nó bất cứ nơi nào sự kiện xảy ra.

Bạn có thể tránh sử dụng đoạn mã này hoàn toàn nếu bạn đặt một dòng

messageScrollList.setViewportView(messageList); 

đó làm việc như add(component) cho JList và được hành vi vốn có của nó.

Các vấn đề liên quan