2009-03-10 24 views
23

Tôi đang cố gắng tạo một giao diện người dùng Swing rất đơn giản để ghi nhật ký thông tin lên màn hình thông qua JTextArea khi quá trình xử lý diễn ra ở chế độ nền. Khi người dùng nhấp vào một nút, tôi muốn mỗi cuộc gọi đến:Làm mới động JTextArea khi xử lý xảy ra?

textArea.append(someString + "\n"); 

để hiển thị ngay lập tức trong giao diện người dùng.

Hiện tại, JTextArea không hiển thị tất cả thông tin nhật ký cho đến khi quá trình xử lý hoàn tất sau khi nhấp vào nút. Làm thế nào tôi có thể làm cho nó để làm mới động?

Trả lời

23

Tôi đã gặp sự cố tương tự với đơn đăng ký của mình. Tôi đã có một "Run" nút ứng dụng của tôi đã thực hiện một số hành động và xuất kết quả cho một JTextArea. Tôi đã phải gọi phương thức từ một Thread. Đây là những gì tôi đã làm.

Tôi có một số nút thao tác trên radio có thể thực hiện và sau đó một nút "Chạy" để thực hiện tác vụ cụ thể đó. Tôi có một hành động được gọi là Xác thực. Vì vậy, khi tôi kiểm tra nút radio đó và nhấp vào nút "Chạy", nó gọi phương thức xác thực(). Vì vậy, lần đầu tiên tôi đặt phương pháp này thành một lớp bên trong mà thực hiện Runnable

class ValidateThread implements Runnable { 
    public void run() { 
     validate(); 
    } 
} 

sau đó tôi gọi là chủ đề này trong ActionListener của nút "Run" như vậy

runButton.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent ae) { 
     // Some code checked on some radio buttons 
     if(radioButton.isSelected()) { 
      if(radioButton.getText().equals("VALIDATE")) { 
       Runnable runnable = new ValidateThread(); 
       Thread thread = new Thread(runnable); 
       thread.start(); 
      } 
     } 
    } 

}); 

Voila! Đầu ra hiện được gửi đến JTextArea.

Bây giờ, bạn sẽ nhận thấy rằng JTextArea sẽ không cuộn xuống với văn bản. Vì vậy, bạn cần phải đặt vị trí dấu mũ như

textArea.setCaretPosition(textArea.getText().length() - 1); 

Bây giờ khi dữ liệu được thêm vào JTextArea, nó sẽ luôn cuộn xuống.

+3

Tại sao không sử dụng EventQueue.invokeLater (runnable)? –

+0

Tôi không chắc chắn rằng đã có sẵn - bình luận của bạn là 4 năm sau khi tôi lol – Ascalonian

0

Bạn sẽ cần đa luồng cho việc này. Bạn đã sẵn sàng để lao vào?

+0

Tôi đã có mũ cứng. Vì vậy, có. – digiarnie

4

Như những người khác đã nói điều này yêu cầu đa luồng. Hãy xem Concurrency in Swing.

Một giải pháp sẽ là triển khai chế biến bằng cách sử dụng SwingWorker. Phương thức doInBackground sẽ thực hiện việc xử lý và bạn sẽ gọi phương thức publish với String được thêm vào làm đối số. SwingWorker của bạn sau đó sẽ ghi đè lên phương thức quy trình để lấy một đối số String và nối nó vào vùng văn bản.

32

Hãy thử điều này:

jTextArea.update(jTextArea.getGraphics()); 
+0

nó là hoàn hảo. Cảm ơn bạn :) – olyanren

+0

nó hoạt động. Cảm ơn :) –

+0

Nó hoạt động và rất dễ thực hiện. Đó sẽ là câu trả lời tốt nhất. – Nautilus

1

Tôi xin lỗi vì trả lời cho câu hỏi này đã được đăng cách đây 4 năm, nhưng tôi có một giải pháp mà làm việc cho tôi. Tôi chỉ sử dụng con trỏ để cập nhật số JTextArea như vậy:

//JScrollPane variable pane initialized with JTextArea area 
//We will update area with new text 
JTextArea temp = (JTextArea) pane.getViewPort().getView(); 
//new text to add 
JTextArea c = new JTextArea(); 
c.append("text \n)"; 
//update through pointers 
temp = c; 
pane.validate(); 
Các vấn đề liên quan