Duplicação de execução (JButton)

4 respostas
K

Boa noite, estou montando uma interface. Nela há um botão start que inicia uma Thread e transforma-se em botão stop (não na thread). Até aí, tudo bem, mas se eu aperto o botão consecutivamente (criando um start/stop/start/stop) ele acaba criando uma nova thread antes de parar a anterior, assim, fico com uma thread rodando extra e uma manuseável de acordo com o start/stop (é possível aumentar o número de threads prolongado o número de vezes que pressiona-se o botão).

Já tentei criar um método synchronizad, usar booleans e tudo mais que eu consegui imaginar pra tentar corrigir isso (impedir a criação de mais de 1 thread), mas nada dá certo…

Meu código:

package snow;

import java.io.IOException;

import javax.swing.JOptionPane;

/**
 * @author KaL
 */
public class Listeners
{
	private Sniffer sn;
	private GUI gui;
	private ProcessList pl;
	private PIDsHandler ph;
	private int pid = -1;
	private String recv, send;
	private boolean isRefreshing = false;
	
	public Listeners( GUI gui)
	{
		this.gui = gui;
		pl = new ProcessList();
		ph = new PIDsHandler(this.gui);;
	}

	private boolean load()
	{
		try{			
			int avaliablePID = pl.listProcessIDs()[0];
			if(!ph.isPID(avaliablePID))
				return false;

			String process = pl.getPIDProcess(avaliablePID);
			if(ProcessList.interrupted && !isRefreshing)
			{

				ProcessList.isProcessing = false;
				return false;
			}

			if(process == null && !isRefreshing)
				if(!ph.isProcess(process))
					return false;

			recv = pl.getPIDRecv(process);
			send = pl.getPIDSend(process);
			
			ph.addUsedPID(avaliablePID);
			setPID(avaliablePID);
			ProcessList.isProcessing = false;
			return true;
		} catch (IOException e) {
			gui.showOptionPane("Could not search for avaliable processes.", "Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE);
			return false;
		}
	}
	
	public void start() 
	{
		new Thread()
		{
			public void run()
			{				
				if(getPID() < 0)
				{
					if(!load())
					{
						if(!ProcessList.interrupted)
							gui.startInvert();
					}
				}
				
				if(ProcessList.interrupted)
				{
					ProcessList.interrupted = false;
					return;
				}
				
				getGUI().refresh.setEnabled(true);
				
				sn = new Sniffer(recv, send, gui);
				setSniffer(sn);

				getSniffer().isRunning = true;
				getSniffer().run();
			}
		}.start();
    }
	
	public void stop(boolean disable)
	{
		if(isRefreshing && disable)
			gui.start.setEnabled(false);
			
		if(ProcessList.isProcessing)
			pl.interrupt();
		
		if(getSniffer() != null && getSniffer().isRunning)
			getSniffer().stopSniff();
				
	}
	
	public void setSniffer(Sniffer sn)
	{
		this.sn = sn;
	}
	
	public Sniffer getSniffer()
	{
		return sn;
	}
		
	public void setPID(int PID)
	{
		pid = PID;
	}
	
	public int getPID()
	{
		return pid;
	}
	
	public GUI getGUI()
	{
		return gui;
	}
}

4 Respostas

ViniGodoy

Faça sua thread reabilitar o botão ao final do método run().

K

O botão não é desabilitado ao pressionado (aquele controlador é referente a um refresh que eu criei, este está funcionando)

ViniGodoy

Mas como vc dispara a thread? Eu geralmente proibia isso da maneira mais simples possível:

  1. Ao disparar a thread, desabilite o botão que permite o disparo;
  2. Reabilite no final do run.

Caso você não possa desabilitar o botão:

  1. Guarde o objeto da thread numa variável de instância;
  2. Ao tentar disparar essa thread novamente, teste se a variável não é nula. Somente se for, crie uma thread com new e dispare-a.
K

Como o run executa um loop infinito, fica inviável desabilitar o botão (pois o mesmo serve para interromper).

Coloquei a thread como você disse, mas aí quando eu dou start/stop (até aí, certo) e start de novo, ele dispara uma exceção:

Thread t;
public void start() 
	{
		if(getThread() == null)
		{
			t = new Thread()		
			{
				public void run()
				{		
					if(getPID() < 0)
					{
						if(!load())
						{
							if(!ProcessList.interrupted)
								gui.startInvert();
						}
					}
					
					if(ProcessList.interrupted)
					{
						ProcessList.interrupted = false;
						return;
					}
					
					getGUI().refresh.setEnabled(true);
					
					sn = new Sniffer(recv, send, gui);
					setSniffer(sn);
	
					getSniffer().isRunning = true;
					getSniffer().run();
				}
			};
			setThread(t);
		}
		getThread().start();
    }
	
	public void setThread(Thread t)
	{
		this.t = t;
	}
	
	public Thread getThread()
	{
		return t;	
	}
Exception in thread "AWT-EventQueue-0" java.lang.IllegalThreadStateException at java.lang.Thread.start(Thread.java:595) at snow.Listeners.start(Listeners.java:93) at snow.GUI$13.actionPerformed(GUI.java:458) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236) at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272) at java.awt.Component.processMouseEvent(Component.java:6267) at javax.swing.JComponent.processMouseEvent(JComponent.java:3267) at java.awt.Component.processEvent(Component.java:6032) at java.awt.Container.processEvent(Container.java:2041) at java.awt.Component.dispatchEventImpl(Component.java:4630) at java.awt.Container.dispatchEventImpl(Container.java:2099) at java.awt.Component.dispatchEvent(Component.java:4460) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168) at java.awt.Container.dispatchEventImpl(Container.java:2085) at java.awt.Window.dispatchEventImpl(Window.java:2478) at java.awt.Component.dispatchEvent(Component.java:4460) at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Criado 29 de novembro de 2010
Ultima resposta 29 de nov. de 2010
Respostas 4
Participantes 2