2017-02-12 73 views
0

我遇到了一些actionlisteners問題,經過一些搜索後,我在這裏找不到任何關於此的信息。從類中刪除ActionListener

所以我有一個類「OctetsGraph」,它擴展JPanel並表示一個圖,另一個類叫做「DataGenerator」,它實現了ActionListener。 DataGenerator用於運行everey X毫秒並將新數據添加到圖形更新的數據集中。

DataGenerator(int interval) 
     { 
      super(interval, null); 
      addActionListener(this); 
     } 

在I繪製在曲線圖上的形式,我有一個列表,以及列表上的每個元素被suposed具有「OctetsGraph」。每次更改選定的對象時更新圖形都沒有問題。我在程序的開始處有一個「OctetsGraph」,我將它設置爲null,然後在選擇其他元素時創建另一個「OctetsGraph」。問題是,與它關聯的actionListener仍然在運行...

我認爲actionListneres會簡單地停止時,將OctetsGraph對象設置爲null,但他們沒有。那我該如何解決這個問題?

這是我的列表鼠標按下的事件,它爲新對象設置了一個新的八位字節圖形和一個新的動作列表器。我究竟做錯了什麼?

private void jList1MousePressed(java.awt.event.MouseEvent evt) {          

    this.panel = new OctetsGraph(60000); 

    jPanel2.removeAll(); 

    javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); 
    jPanel2.setLayout(jPanel2Layout); 
    jPanel2Layout.setHorizontalGroup(
     jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) 
     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() 
      .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, 20) 
      .addComponent(panel) 
      .addGap(20, 20, 20)) 
    ); 
    jPanel2Layout.setVerticalGroup(
     jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) 
     .addGroup(jPanel2Layout.createSequentialGroup() 
      .addGap(20, 20, 20) 
      .addComponent(panel) 
      .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, 20)) 
    ); 

    jPanel2.revalidate(); 
    jPanel2.repaint(); 

    //Listener that fetches data every second 
    panel.new DataGenerator(1000).start(); 
} 

有沒有一種方法,我可以刪除「面板」上活動的actionListeners?

預先感謝您

回答

1

DataGenerator被suposed運行everey X milisecond和新數據添加到數據集從圖的更新。

所以你應該使用Swing Timer安排事件。

然後你需要添加一個方法到你的OcetsGraph類,類似stopTimer()。 (也許你還需要一個startTimer()方法?)

我認爲actionListneres只會停止設置OctetsGraph對象時爲空

而不是設置對象爲空的,你調用stopTimer()方法在物體上。一旦Timer停止,事件將不再生成,因此處理將停止。

編輯:

首先學習如何啓動/停止計時器。然後,當你理解了基本的修改您的實際應用代碼:

import java.awt.*; 
import java.awt.event.*; 
import java.util.Date; 
import javax.swing.*; 

public class SSCCE extends JPanel implements ActionListener 
{ 
    private Timer timer; 
    private JLabel label = new JLabel("Press Start"); 

    public SSCCE() 
    { 
     setLayout(new BorderLayout(10, 10)); 
     add(label, BorderLayout.PAGE_START); 


     JButton start = new JButton("Start"); 
     start.addActionListener(new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       startTimer(); 
      } 
     }); 
     add(start, BorderLayout.LINE_START); 

     JButton stop = new JButton("Stop"); 
     stop.addActionListener(new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       stopTimer(); 
      } 
     }); 
     add(stop); 
     add(stop, BorderLayout.LINE_END); 

     timer = new Timer(1000, this); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     label.setText(new Date().toString()); 
    } 

    private void startTimer() 
    { 
     timer.start(); 
    } 

    private void stopTimer() 
    { 
     timer.stop(); 
    } 

    private static void createAndShowGUI() 
    { 
     JFrame frame = new JFrame("SSCCE"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new SSCCE()); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(() -> createAndShowGUI()); 
/* 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowGUI(); 
      } 
     }); 
*/ 
    } 
} 

編輯2:

如果你需要一個基準,然後創建一個參考:

//panel.new DataGenerator(1000).start(); 
timer = panel.new DataGenerator(1000); 
timer.start(); 

過程中的「定時器」變量需要是類的實例變量,以便稍後可以引用它。你如何管理這取決於你。我可以根據所提供的信息提供具體的細節。

+0

嗨there @camickr,是的,我使用Timer。對不起,我忘記提到這一點。這個想法很好,但我會如何阻止它?我嘗試使用stop,但actionPerformed函數只是不停地重複......停止似乎沒有做任何事情。我試圖在DataGenerator中調用stopTimer來執行「this.stop()」,但也沒有幫助。 –

+0

哦,我想我發現了這個問題......出於某種原因,我沒有收到任何聽衆......不應該這樣做嗎? 「面板」是OctetsGraph對象 DataGenerator [] mls = panel.getListeners(DataGenerator.class); –

+0

@PeterL。,聽者與問題無關。當Timer觸發時,它會調用您添加到Timer中的Action。所以你需要停止Timer,然後Timer停止調用Action。定時器有一個stop()方法。 – camickr