Let's say you have a TextView
that displays an number like 0 and you have a Button
.
Now if the user presses the Button the Number in the TextView will increase for one (this i know how to do) but if the user presses the Button and don't release it then the number in the TextView
should be increased an this should repeat it self as long the user don't release the Button
.
In other words: How to increase the Number over and over again as long the user holds down the Button?
A general approach (not specific to Android) would be to detect the press and release event separately. The press event starts a periodic task (Runnable
or Thread
) which adds to the counter (let us say 5 times a second, or once every 200 ms). The release event stops the periodic task.
You'll need to schedule an asynchronous repeating event when you receive a mousePressed
event and stop it when you receive a mouseReleased
event.
There's lots of ways to handle this in Java. I like using the java.util.concurrent
classes, which are quite flexible. There's a few things to keep in mind though:
If your asynchronous events don't happen on the Event Dispatch Thread, you need to set the JButton
text using SwingUtilities.invokeLater()
.
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Frame
{
public static void main( String[] args )
{
JFrame frame = new JFrame( );
final JButton button = new JButton( "0" );
final ScheduledExecutorService executor = Executors.newScheduledThreadPool( 1 );
button.addMouseListener( new MouseAdapter( )
{
int counter = 0;
ScheduledFuture<?> future;
@Override
public void mousePressed( MouseEvent e )
{
Runnable runnable = new Runnable( )
{
public void run( )
{
SwingUtilities.invokeLater( new Runnable( )
{
public void run( )
{
button.setText( String.valueOf( counter++ ) );
}
} );
}
};
future = executor.scheduleAtFixedRate( runnable, 0, 200, TimeUnit.MILLISECONDS );
}
@Override
public void mouseReleased( MouseEvent e )
{
if ( future != null )
{
future.cancel( true );
}
}
} );
frame.add( button );
frame.setSize( 400, 400 );
frame.setVisible( true );
}
}
View.OnLongClickListener
for your buttonRunnable
, and initialize (but don't start it) when you load the activityOnTouchListener
that pauses the Runnable
when the touch event is realeased.I know that's a rough draft, but this is a really useful pattern to be able to reuse and modify, so it's worth sinking your talons into it...