2012-01-18 32 views
8

Tôi có nhãn thư và nút gửi. Nút gửi sẽ được nhấn nhiều lần và hành động cho mỗi lần nhấn có thể mất tới một phút.Swing - Cập nhật nhãn

Khi nhấn nút, tôi muốn đặt thư thành trống và sau khi tác vụ hoàn tất, tôi muốn đặt thư thành "Hoàn thành".

private void submitActionPerformed(java.awt.event.ActionEvent evt) { 
    message = ""; 
    updateMessageLabel(); 

    doTheTask(); 

    /* this update is apply to the label after completion */ 
    message = "Complete"; 
} 

Có thể cập nhật nhãn thư đó trước khi phương thức submitActionPerformed() được chạy (hoặc trong phương pháp), nhưng sau khi nút được nhấp?

+2

tôi có thể suy luận quá nhiều ở đây, nhưng gần như có vẻ giống như một thanh tiến trình sẽ làm việc độc đáo ở đây (http://docs.oracle. com/javase/tutorial/uiswing/components/progress.html)? –

+0

@ZackMacomber là bước tiếp theo –

Trả lời

10

Có bạn có thể làm điều này bằng SwingWorker chủ đề, làm tất cả những hoạt động submitActionPerformed() trước như cập nhật các nhãn, trong phương pháp execute() của currentThread và gọi doTheTask() như một công việc nền sử dụng lao động Thread.

tôi đề nghị bạn phải đi qua các tài liệu này để tham khảo về SwingWorker Thread

+2

Tốt nhất là liên kết tới phiên bản JavaDocs mới nhất. Tôi đã chỉnh sửa câu trả lời của bạn để trỏ đến J2SE 7. Đối với lời khuyên về nhận được một liên kết đến các tài liệu mới nhất, xem [điểm 2 lợi thế] (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7090875) . –

13

Mặc dù Swing concurrency tutorial đã có chứa một số mẫu rất tốt về cách đối phó với đồng thời trong Swing, tìm thấy bên dưới một ví dụ mà

  • chứa hộp kiểm để chứng minh giao diện người dùng vẫn còn sống
  • có thanh tiến trình, được cập nhật từ SwingWorker
  • có nhãn, mà được cập nhật khi SwingWorker xong

    import javax.swing.JCheckBox; 
    import javax.swing.JFrame; 
    import javax.swing.JLabel; 
    import javax.swing.JProgressBar; 
    import javax.swing.SwingWorker; 
    import java.awt.BorderLayout; 
    import java.awt.EventQueue; 
    import java.lang.reflect.InvocationTargetException; 
    import java.util.List; 
    import java.util.concurrent.ExecutionException; 
    
    public class SwingWorkerExample { 
        private static JProgressBar PROGRESS_BAR; 
        private static JLabel OUTPUT_LABEL; 
        private static JFrame createGUI(){ 
        JFrame testFrame = new JFrame("TestFrame"); 
    
        PROGRESS_BAR = new JProgressBar(); 
        PROGRESS_BAR.setMinimum(0); 
        PROGRESS_BAR.setMaximum(100); 
    
        OUTPUT_LABEL = new JLabel("Processing"); 
    
        testFrame.getContentPane().add(PROGRESS_BAR, BorderLayout.CENTER); 
        testFrame.getContentPane().add(OUTPUT_LABEL, BorderLayout.SOUTH); 
    
        //add a checkbox as well to proof the UI is still responsive 
        testFrame.getContentPane().add(new JCheckBox("Click me to proof UI is responsive"), BorderLayout.NORTH); 
    
    
    
        testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        return testFrame; 
        } 
    
        public static void main(String[] args) throws InvocationTargetException, InterruptedException { 
        EventQueue.invokeAndWait(new Runnable() { 
         @Override 
         public void run() { 
         JFrame frame = createGUI(); 
    
         frame.pack(); 
         frame.setVisible(true); 
         } 
        }); 
        //start the SwingWorker outside the EDT 
        MySwingWorker worker = new MySwingWorker(PROGRESS_BAR, OUTPUT_LABEL); 
        worker.execute(); 
        } 
        private static class MySwingWorker extends SwingWorker<String, Double>{ 
        private final JProgressBar fProgressBar; 
        private final JLabel fLabel; 
        private MySwingWorker(JProgressBar aProgressBar, JLabel aLabel) { 
         fProgressBar = aProgressBar; 
         fLabel = aLabel; 
        } 
    
        @Override 
        protected String doInBackground() throws Exception { 
         int maxNumber = 10; 
         for(int i = 0; i < maxNumber; i++){ 
         Thread.sleep(2000);//simulate long running process 
         double factor = ((double)(i+1)/maxNumber); 
         System.out.println("Intermediate results ready"); 
         publish(factor);//publish the progress 
         } 
         return "Finished"; 
        } 
    
        @Override 
        protected void process(List<Double> aDoubles) { 
         //update the percentage of the progress bar that is done 
         int amount = fProgressBar.getMaximum() - fProgressBar.getMinimum(); 
         fProgressBar.setValue((int) (fProgressBar.getMinimum() + (amount * aDoubles.get(aDoubles.size() - 1)))); 
        } 
    
        @Override 
        protected void done() { 
         try { 
         fLabel.setText(get()); 
         } catch (InterruptedException e) { 
         e.printStackTrace(); 
         } catch (ExecutionException e) { 
         e.printStackTrace(); 
         } 
        } 
        } 
    } 
    
+0

cảm ơn mã. rất hữu ích. –

+3

quá trình triển khai không hoạt động như người dùng có thể mong đợi: có thể là một vài giá trị (được tích luỹ) trong danh sách, nhưng nó chỉ đặt giá trị progressBar cho giá trị đầu tiên. Thay vào đó, hãy lặp lại tất cả hoặc chỉ sử dụng điểm cuối tốt nhất là – kleopatra

+0

@kleopatra. Tôi sẽ điều chỉnh mã – Robin

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