2012-12-30 2 views
0

간단한 Ping으로 생성 된 각각의 새 문자열로 JLabel을 동적으로 변경하려고하지만 JLabel의 기존 문자열을 Ping이 들어갈 때마다 새로운 문자열로 대체하는 방법을 알아낼 수 없습니다 실행 중. 아래는 제가 지금까지 가지고있는 것입니다. 지금까지는 JLabel의 텍스트가 Ping의 실행이 끝난 후에 만 ​​바뀝니다.Ping 결과로 동적으로 JLabel을 변경하십시오.

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 
import java.io.*; 

public class Ping extends JFrame implements ActionListener{ 

private JButton runButton = new JButton("Run"); 
private JLabel pingResult = new JLabel("Result"); 
private String results; 

public Ping(){ 
    runButton.addActionListener(this); 

    add(pingResult, BorderLayout.CENTER); 
    add(runButton, BorderLayout.NORTH); 

} 

//Action Listener 
public void actionPerformed(ActionEvent e) 
{ 
    String buttonString = e.getActionCommand(); 

    if (buttonString.equals("Run")) 
    { 
     //Execute Ping 
     try { 
      String line; 
      Process p = Runtime.getRuntime().exec("/sbin/ping -c 4 www.google.com"); 
      BufferedReader input = new BufferedReader(
       new InputStreamReader(p.getInputStream())); 

      while ((line = input.readLine()) != null) { 
       results += line + "\n"; 
       pingResult.setText(results); 
       //System.out.println(line); 
      } 

      input.close(); 
     }catch (Exception err){ 
      err.printStackTrace(); 
     } 

    }else{ 
     System.exit(0); 
    } 
} 

public static void main(String[] args) { 
    Ping sp = new Ping(); 
    sp.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    sp.setSize(400, 400); 
    sp.setVisible(true); 
    sp.setLayout(new BorderLayout()); 
} 

} 

답변

0

정확히, 핑이 완료된 후에 만 ​​업데이트됩니다. 작업을 끝내기 전에 작업을 수행하려면 스레드을 사용해야합니다.

3

이벤트 발송 스레드의 setText를 호출합니다. SwingUtils.invokeLater를 사용하십시오. EDT에서 오래 지속되는 작업을 실행하지 마십시오. 앱이 멈추는 현상이 발생합니다.

1

코드가 EDT (Event Dispatch Thread)를 고정시킵니다. 그것이 핑이 끝난 후에 JLabel 텍스트가 업데이트되는 이유입니다. 그렇게하지 않는 것이 좋습니다. 다른 스레드에서 오래 지속되는 작업을 실행하고 SwingUtils.invokeLater를 사용하여 업데이트하는 것은 하나의 솔루션입니다. 다른 하나는 SwingWorker 클래스의 사용법입니다. 여기서 tutorial을 찾을 수 있습니다.

다음은 첫 번째 옵션이있는 예입니다. JLabel 대신 JTextArea를 사용했습니다.

그리고 Runtime.exec() 대신 ProcessBuilder를 사용해야하는 또 다른 사항은 here입니다.

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.nio.charset.Charset; 
import java.util.ArrayList; 
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.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 

public class PingExample { 
    private static final Logger logger = Logger.getLogger(PingExample.class.getName()); 

    public static void main(String[] args) { 
    PingExample p = new PingExample(); 
    p.run(); 
    } 

    private void run() { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     JFrame frame = new PingFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     } 
    }); 
    } 

    private class PingFrame extends JFrame { 
    private static final long serialVersionUID = 1L; 

    private JTextArea textArea; 

    private PingFrame() { 
     super.setName("Ping Frame"); 
     this.addComponents(); 
     super.setSize(400, 240); 
    } 

    private void addComponents() { 
     super.setLayout(new BorderLayout()); 

     this.textArea = new JTextArea(10, 0); 
     JScrollPane scrollPane = new JScrollPane(this.textArea); 
     super.add(scrollPane, BorderLayout.NORTH); 

     JButton button = new JButton("Run"); 
     button.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      new Thread(new Ping(PingFrame.this.textArea)).start(); 
     } 
     }); 
     super.add(button, BorderLayout.SOUTH); 
    } 

    private class Ping implements Runnable { 
     private JTextArea textArea; 

     private Ping(JTextArea textArea) { 
     this.textArea = textArea; 
     } 

     @Override 
     public void run() { 
     try { 
      List<String> commands = new ArrayList<>(10); 
      commands.add("ping"); 
      commands.add("www.google.com"); 

      ProcessBuilder builder = new ProcessBuilder(); 
      builder.command(commands); 
      Process process = builder.start(); 

      try (
       BufferedReader br = new BufferedReader(
       new InputStreamReader(process.getInputStream(), Charset.defaultCharset()))) { 
      String line = br.readLine(); 
      while (null != line) { 
       final String text = line; 
       SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        Ping.this.textArea.append(text); 
        Ping.this.textArea.append("\n"); 
       } 
       }); 
       line = br.readLine(); 
      } 
      } 

      process.waitFor(); 
      process.destroy(); 
     } catch (IOException | InterruptedException x) { 
      logger.log(Level.SEVERE, "Error", x); 
     } 
     } 
    } 
    } 

}

+0

또한 보조 노트로의 진행률 표시 줄이 더 오래 작업에 대 한 좋은 것 동안 최소 2 초 이상 지속될 수 작업에 마우스 포인터를 "바쁜"로 변경 추천 . –