2015-07-03 78 views
0

我有一個標籤不在GUI的同一實例中更新。 如果我單擊應該更新jLabel(代碼塊中的「testLabel」)的值的jButton,我必須再次運行java程序才能看到所做的更改。我怎樣才能讓它出現在同一個實例中的按鈕點擊? 我知道關於invokelater,我一直在玩它試圖讓它實時更新,但沒有運氣。我一直堅持這一段時間,所以任何幫助表示讚賞。 通過下面列出的代碼塊,我仍然需要運行GUI的新實例來獲取更新的值。標籤不在GUI的相同實例中更新

相關代碼:

public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       MISControlPanel window = new MISControlPanel(); 
       window.frame.setVisible(true); 
       // testLabel.setText(CN); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

JButton searchComputerButton = new JButton("Search"); 
    searchComputerButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 

      String line; 
      BufferedWriter bw = null; 
      BufferedWriter writer = null; 
      try { 
       writer = new BufferedWriter(new FileWriter(tempFile)); 
      } catch (IOException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 
      // String lineToRemove = "OU=Workstations"; 

      String s = null; 

      Process p = null; 
      /* 
      * try { // p = Runtime.getRuntime().exec(
      * "cmd /c start c:\\computerQuery.bat computerName"); } catch 
      * (IOException e1) { // TODO Auto-generated catch block 
      * e1.printStackTrace(); } 
      */ 
      try { 

       p = Runtime.getRuntime().exec("c:\\computerQuery.bat"); 

      } catch (IOException e1) { 

       // TODO Auto-generated catch block 

       e1.printStackTrace(); 

      } 
      StringBuffer sbuffer = new StringBuffer(); 
      BufferedReader in = new BufferedReader(new InputStreamReader(p 
        .getInputStream())); 

      try { 

       while ((line = in.readLine()) != null) { 

        System.out.println(line); 

        // textArea.append(line); 

        String dn = "CN=FDCD111304,OU=Workstations,OU=SIM,OU=Accounts,DC=FL,DC=NET"; 
        LdapName ldapName = new LdapName(dn); 
        String commonName = (String) ldapName.getRdn(
          ldapName.size() - 1).getValue(); 

       } 
       ComputerQuery.sendParam(); 

      } catch (IOException e1) { 

       // TODO Auto-generated catch block 

       e1.printStackTrace(); 

      } catch (InvalidNameException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } finally 

      { 
       try { 
        fw.close(); 

       } 

       catch (IOException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 
      } 

      try { 

       in.close(); 

      } catch (IOException e1) { 

       // TODO Auto-generated catch block 

       e1.printStackTrace(); 

      } 

      ComputerQuery.sendParam(); 

     } 
    }); 

    try (BufferedReader br = new BufferedReader(new FileReader(
      "resultofbatch.txt"))) { 

     final Pattern PATTERN = Pattern.compile("CN=([^,]+).*"); 
     try { 
      while ((sCurrentLine = br.readLine()) != null) { 

       String[] tokens = PATTERN.split(","); // This will return 
                 // you a array, 
                 // containing the 
                 // string array 
                 // splitted by what 
                 // you write inside 
                 // it. 
       // should be in your case the split, since they are 
       // seperated by "," 
       // System.out.println(sCurrentLine); 
       CN = sCurrentLine.split("CN=", -1)[1].split(",", -1)[0]; 

       System.out.println(CN); 
       testLabel.setText(CN); 
      } 

全類代碼 http://pastebin.com/havyqMxP

電腦查詢類(小類) http://pastebin.com/Q89BCjya

+0

您好user6680 ...我不知道您打算執行此操作的執行流程的哪一部分,您正在使用LDAP,我看到..這意味着您正在連接到LDAP服務器,並且可能執行長時間運行的任務... 你是否試圖在組件的任何類型的監聽器(因此在事件調度線程)的回調中執行此操作?或者你正在另一個線程上執行此操作? Swing.invokelater將無助於此...我建議開始閱讀SwingWorker,並在UI上分割表示的操作(處理swing組件的代碼) – Victor

+0

試試這個教程... https://docs.oracle.com/javase/tutorial/uiswing/concurrency /simple.html ... – Victor

+0

我認爲我需要它做的是在不同的線程上運行,以便在GUI的同一實例內更新值。我看着你提供的教程鏈接,但我很困惑。它使用了在done方法中加載圖像的示例,但我不確定如何將其實現到我的代碼中。我一直試圖讓這個工作一個多星期。你有沒有可能向我展示我想要完成的工作示例? – user6680

回答

2

正如所承諾的......這裏是一個獲取UR的簡單示例L內容使用揮杆工作人員從更新揮杆組件的任務中解除獲取內容的任務(長時間運行的任務)。這將顯示你應該如何處理這個問題的一個例子...

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.net.URL; 
import java.util.List; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingWorker; 

/* FrameDemo.java requires no other files. */ 
public class MainWindow extends JFrame { 
    private static final Logger LOOGER = Logger.getLogger(MainWindow.class.getName()); 

    /** 
    * Create the GUI and show it. For thread safety, 
    * this method should be invoked from the 
    * event-dispatching thread. 
    */ 

    private JLabel statusLabel = new JLabel("Status"); 
    private JButton actionButton = new JButton("Push me"); 

    public MainWindow() { 
    super("FrameDemo"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    statusLabel = new JLabel("Status"); 
    actionButton = new JButton("Push me"); 

    statusLabel.setPreferredSize(new Dimension(400, 50)); 
    actionButton.setPreferredSize(new Dimension(100, 50)); 
    getContentPane().setLayout(new BorderLayout()); 
    getContentPane().add(statusLabel, BorderLayout.NORTH); 
    getContentPane().add(actionButton, BorderLayout.CENTER); 

    actionButton.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
     // THIS METHOD IS INVOKED WITHIN THE EVENT DISPATCH THREAD!!.. SO IS CRUCIAL TO NOT PERFORM 
     // HERE LONG TIME RUNNING TASKS... 
     actionButton.setEnabled(false); // let's disable this button, in order to avoid invoking 
     // multiple times the same task and messing up the entire app... 
     UrlFechterSwingWorker urlFechterSwingWorker = new UrlFechterSwingWorker(); 
     urlFechterSwingWorker.execute(); 
     } 
    }); 
    } 

    public void display() { 
    pack(); 
    setVisible(true); 
    } 

    private class UrlFechterSwingWorker extends SwingWorker<String, String> { 
    @Override 
    public String doInBackground() { // this method is executed under a worker thread 

     BufferedReader in; 
     StringBuilder sb = new StringBuilder(); 
     try { 
     URL url = new URL("http://www.stackoverflow.com"); 
     in = new BufferedReader(new InputStreamReader(url.openStream())); 
     String line = in.readLine(); 
     while (line != null) { 
      sb.append(line); 
      publish(line); // publish partial results.... 
      line = in.readLine(); 
     } 
     in.close(); 
     } catch (Exception e) { 
     LOOGER.log(Level.SEVERE, "", e); 
     } 
     return sb.toString(); 
    } 

    @Override 
    protected void process(List<String> readedLines) { // this method in the Event dispatch Thread 
     // do what you want to do with the readedLines.... 
     statusLabel.setText("The doInBackground read... " + readedLines.size() + " lines"); 
    } 

    @Override 
    public void done() { // this method in the Event dispatch Thread 
     // do what you want when the process finish 
     actionButton.setEnabled(true); // well.. at least i would like to enable the button again... 
    } 
    } 

    public static void main(String[] args) { 
    MainWindow mainWindow = new MainWindow(); 
    mainWindow.display(); 
    } 
} 

這裏有更多的提示:

  1. 在瞭解(或多或少)事情是如何在上面的例子中工作..你將不得不實施一個適當的doInBackground方法執行所有的LDAP的東西,爲此,你將不得不讓你的想法設想一種方式告知最終用戶的進展...我的意思是,看我的例子,是關於進展的進展非常糟糕......我所說的所有事情是,我們從給定的網址讀取「多行」。你應該考慮什麼是最好的方式來告知你的任務的進展情況..除了對底層域模型的理解之外,沒有模板。

  2. 請記住,擺動工人有兩種方式來告知進度。

    • 一種是使用publishprocess方法。 (像上面的例子)
    • 其他的是要修改方法doInBackground內部的內部屬性(進度和狀態),並將PropertyChangeListener附加到揮杆工。這的PropertyChangeListener對象有其簽名是public void propertyChange(PropertyChangeEvent evt)的方法(稍微複雜一點,在我的觀點。)
  3. 耐心和好運氣!

+1

actionButton.setEnabled(false); == JButton.setMultiClickThreshhold或Swing Action - AbstractAction.setEnabled(false) – mKorbel

+0

加上一個用於相當正確的描述,並且不要將鏡頭修改爲黑暗(SwingWorker),也不會將其單個單獨的偵聽器刪除此建議 – mKorbel

+0

感謝您的建議@mKorbel,我沒有使用JButton.setMultiClickThreshhold ......感謝分享。關於「單獨的聽衆」...你的意思是'PropertyChangeListener'?....請自由編輯我的文章並實施你的建議 – Victor