2012-04-19 12 views
15

मैंने अपना स्वयं का स्विंगवर्कर उदाहरण बनाया है ताकि यह परिचित हो सके कि यह कैसे काम करता है। जब बटन क्लिक किया मैं एक प्रगति बार दिखाई देते हैं जब तक कार्य किया जाता है मैं बस प्रगति बार को हटाने और संवाद के लिए एक स्ट्रिंग जोड़ना चाहते हैं:मैं अपने स्विंगवर्कर उदाहरण को सही तरीके से कैसे काम करूं?

मुझे क्या करना चाहते कर रहा हूँ निम्नलिखित है।

जब बटन क्लिक किया जाता है, तो प्रगति पट्टी आती है लेकिन कभी नहीं जाती है। (10 सेकंड के बाद प्रगति बार कभी नहीं दूर करता है और लेबल देता है कभी नहीं)

यहाँ एक SSCCE है:

package swingtesting; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JProgressBar; 
import javax.swing.SwingWorker; 

public class SwingTesting { 

    /** 
    * Creates a frame that will hold a simple button to make use of SwingWorker 
    */ 
    public static void main(String[] args) { 
     // TODO code application logic here 
     JFrame frame = new JFrame(); 
     JButton button = new JButton(); 

     button.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       new GuiWorker().execute(); 
      } 
     }); 
     button.setText("Test Me"); 
     frame.getContentPane().add(button); 
     frame.pack(); 
     frame.setVisible(true); 
    } 
} 

class GuiWorker extends SwingWorker<Integer, Integer> { 

    /* 
    * This should just create a frame that will hold a progress bar until the 
    * work is done. Once done, it should remove the progress bar from the dialog 
    * and add a label saying the task complete. 
    */ 

    private JFrame frame = new JFrame(); 
    private JDialog dialog = new JDialog(frame, "Swingworker test", true); 
    private JProgressBar progressBar = new JProgressBar(); 


    public GuiWorker() { 
     progressBar.setString("Waiting on time"); 
     progressBar.setStringPainted(true); 
     progressBar.setIndeterminate(true); 
     dialog.getContentPane().add(progressBar); 
     dialog.pack(); 
     dialog.setVisible(true); 
    } 

    @Override 
    protected Integer doInBackground() throws Exception { 
     Thread.sleep(10000); 
     return 0; 
    } 

    @Override 
    protected void done() { 
     JLabel label = new JLabel("Task Complete"); 
     dialog.getContentPane().remove(progressBar); 
     dialog.getContentPane().add(label); 
    } 

} 
+2

आप पर एक नज़र ले जा सकते हैं [इस उत्तर] (http://stackoverflow.com/questions/8916721/java-swing-update-label/8917565#8917565) और अपने कोड के साथ तुलना करें। स्विंग ट्यूटोरियल में एक उदाहरण भी शामिल है (लिंक 'जेपी प्रोग्रेसबार' के वर्ग जावाडोक में उपलब्ध है) – Robin

उत्तर

12

यहाँ जो

import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JProgressBar; 
import javax.swing.SwingWorker; 

public class SwingTesting { 

    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     JFrame frame = new JFrame(); 
     JButton button = new JButton(); 
     button.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
      new GuiWorker().execute(); 
      } 
     }); 
     button.setText("Test Me"); 
     frame.getContentPane().add(button); 
     frame.pack(); 
     frame.setVisible(true); 
     } 
    }); 

    } 
} 

class GuiWorker extends SwingWorker<Integer, Integer> { 

    /* 
    * This should just create a frame that will hold a progress bar until the 
    * work is done. Once done, it should remove the progress bar from the dialog 
    * and add a label saying the task complete. 
    */ 

    private JFrame frame = new JFrame(); 
    private JDialog dialog = new JDialog(frame, "Swingworker test", true); 
    private JProgressBar progressBar = new JProgressBar(); 


    public GuiWorker() { 
    progressBar.setString("Waiting on time"); 
    progressBar.setStringPainted(true); 
    progressBar.setIndeterminate(true); 
    dialog.getContentPane().add(progressBar); 
    dialog.pack(); 
    dialog.setModal(false); 
    dialog.setVisible(true); 
    } 

    @Override 
    protected Integer doInBackground() throws Exception { 
    System.out.println("GuiWorker.doInBackground"); 
    Thread.sleep(1000); 
    return 0; 
    } 

    @Override 
    protected void done() { 
    System.out.println("done"); 
    JLabel label = new JLabel("Task Complete"); 
    dialog.getContentPane().remove(progressBar); 
    dialog.getContentPane().add(label); 
    dialog.getContentPane().validate(); 
    } 

} 

कुंजी बिंदु काम करता है अपने कोड का अद्यतन संस्करण यह है कि जब तक संवाद का निपटारा नहीं किया जाता है तब तक एक मॉडल संवाद दृश्य ब्लॉक स्थापित करता है। इसलिए इसे गैर-मोडल को ठीक करना + validate जब आप घटक स्विच करते हैं तो सामग्री फलक पर कॉल करें। मैंने ईडीटी पर चलाने के लिए अपनी मुख्य विधि भी समायोजित की, और कुछ सिस्टम.आउट कॉल जोड़े। यदि आप setModal(false) कॉल को हटाते हैं तो आप देखेंगे कि जब तक आप संवाद बंद नहीं करते हैं तब तक उन कथन मुद्रित नहीं होते हैं

+1

इसे इंगित करने के लिए धन्यवाद! मुझे लगता है कि मुझे यह देखना चाहिए था कि पहले स्थान पर 'सेटमोडल' विधि थी या नहीं। मैंने मुख्य रूप से परिवर्तन को भी ध्यान में रखा, इसे इंगित करने के लिए धन्यवाद। मैंने बस इसके बारे में यहां पढ़ा है: http://java.sun.com/developer/technicalArticles/javase/swingworker/ मेरे पास इसके साथ एक समस्या है, हालांकि, मॉडल को झूठी बदलकर, यह उपयोगकर्ता को बटन को क्लिक करने की अनुमति देता है एक बार। – WilliamShatner

+0

@ विलियमशहरनर: संवाद को गैर-मोडल बनाने की कोई आवश्यकता नहीं है। स्विंगवर्कर शुरू करने के बाद बस संवाद प्रदर्शित करें। यह कॉलिंग क्लास से किया जा सकता है, जो स्विंगवर्कर को निष्पादित करता है, पहले कॉलिंग निष्पादित करके, और फिर संवाद दिखाता है, या इसे स्विंगवर्कर से किया जा सकता है, लेकिन यदि बाद वाले से, आपको अपना खुद का बनाना होगा छद्म निष्पादन विधि जो सुपर के निष्पादन को कॉल करती है, और फिर संवाद दिखाती है। ध्यान दें कि आप अंतिम होने के बाद 'निष्पादन()' को ओवरराइड नहीं कर सकते हैं। –

+1

@WilliamShatner आप स्विंगवर्कर शुरू करते समय बटन को अक्षम कर सकते हैं, और बाद में इसे फिर से सक्षम कर सकते हैं – Robin

10

संवाद को गैर-मोडल बनाने की आवश्यकता नहीं है। स्विंगवर्कर शुरू करने के बाद बस संवाद प्रदर्शित करें। यह कॉलिंग क्लास से किया जा सकता है, जो स्विंगवर्कर को निष्पादित करता है, पहले कॉलिंग निष्पादित करके, और फिर संवाद दिखाता है, या इसे स्विंगवर्कर से किया जा सकता है, लेकिन यदि बाद वाले से, आपको अपना खुद का बनाना होगा छद्म निष्पादन विधि जो सुपर के निष्पादन को कॉल करती है, और फिर संवाद दिखाती है। ध्यान दें कि आप इसे अंतिम रूप से निष्पादित() स्वयं ओवरराइड नहीं कर सकते हैं।

उदाहरण के लिए ...

import java.awt.CardLayout; 
import java.awt.Window; 
import java.awt.Dialog.ModalityType; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.util.concurrent.ExecutionException; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class SwingTesting2 { 

    private static void createAndShowGui() { 
     final JFrame frame = new JFrame("SwingTesting2"); 
     final JDialog dialog = new JDialog(frame, "Dialog", 
      ModalityType.APPLICATION_MODAL); 
     final DialogPanel dialogPanel = new DialogPanel(); 
     dialog.getContentPane().add(dialogPanel.getMainPanel()); 
     dialog.pack(); 
     dialog.setLocationRelativeTo(frame); 

     JButton button = new JButton(new AbstractAction("Test Me") { 

     @Override 
     public void actionPerformed(ActionEvent actEvt) { 
      final GuiWorker2 guiWorker = new GuiWorker2(); 
      guiWorker.addPropertyChangeListener(new PropertyChangeListener() { 

       @Override 
       public void propertyChange(PropertyChangeEvent pcEvt) { 
        if (pcEvt.getPropertyName().equals("state")) { 
        if (pcEvt.getNewValue() == SwingWorker.StateValue.DONE) { 
         try { 
          dialogPanel.done(guiWorker.get()); 
         } catch (InterruptedException e) { 
          e.printStackTrace(); 
         } catch (ExecutionException e) { 
          e.printStackTrace(); 
         } 
        } 
        } else if (pcEvt.getPropertyName().equals("progress")) { 
        dialogPanel.setProgress((Integer)pcEvt.getNewValue()); 
        } 
       } 
      }); 

      guiWorker.execute(); 
      dialogPanel.start(); 
      dialog.setVisible(true); 
     } 
     }); 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(button); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

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

class GuiWorker2 extends SwingWorker<Integer, Integer> { 
    private static final int MAX_COUNT = 20; 
    private static final long SLEEP_TIME = 100; 
    private int count = 0; 

    @Override 
    protected Integer doInBackground() throws Exception { 
     while (count < MAX_COUNT) { 
     Thread.sleep(SLEEP_TIME); 
     count++; 
     setProgress((100 * count)/MAX_COUNT); 
     } 
     return count; 
    } 
} 

@SuppressWarnings("serial") 
class DialogPanel { 
    public static final String PROGRESS_BAR = "Progress Bar"; 
    public static final String DONE = "Done"; 
    private static final int TIMER_DELAY = 2000; 
    private CardLayout cardLayout = new CardLayout(); 
    private JPanel mainPanel = new JPanel(cardLayout); 
    private JLabel doneLabel = new JLabel("Done", JLabel.CENTER); 
    private JProgressBar progressBar = new JProgressBar(); 

    public DialogPanel() { 
     progressBar.setString("Waiting on time"); 
     progressBar.setStringPainted(true); 
     progressBar.setIndeterminate(false); 

     mainPanel.add(progressBar, PROGRESS_BAR); 
     mainPanel.add(doneLabel, DONE); 
    } 

    public void setProgress(Integer newValue) { 
     progressBar.setValue(newValue); 
    } 

    public void start() { 
     cardLayout.show(mainPanel, PROGRESS_BAR); 
     progressBar.setValue(0); 
    } 

    public void done(int countValue) { 
     doneLabel.setText(DONE + ". Count: " + countValue); 
     cardLayout.show(mainPanel, DONE); 
     new Timer(TIMER_DELAY, new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      Window win = SwingUtilities.getWindowAncestor(mainPanel); 
      win.dispose(); 
     } 
     }){{setRepeats(false);}}.start(); 
    } 

    public JPanel getMainPanel() { 
     return mainPanel; 
    } 

} 
+0

सहमत हैं कि मैं इसे भी देख सकता हूं – mKorbel

+1

@ होवरक्राफ्ट उदाहरण बहुत अच्छा था। इसका परीक्षण किया और यह अच्छी तरह से काम किया। मैं सभी कोड के साथ बहुत परिचित नहीं हूं लेकिन मैंने इसके साथ खेला। मैं तस्वीर में एक और कक्षा जोड़ने का भी शौक नहीं हूं, लेकिन मुझे खुशी है कि आपने इसे पोस्ट किया है। उपरोक्त :) – WilliamShatner

+0

@ विलियम: टिप्पणियों के लिए धन्यवाद। अपनी परियोजना के साथ शुभकामनाएँ! –

संबंधित मुद्दे

 संबंधित मुद्दे