I am trying to update JLabel in some expected behaviour like -
COND 1 : JLabel should display for 5 seconds , then it should be invisible for next 3 seconds then it should be visible for 5 second and so on.
COND 2 : JLabel should display for 0.5 second , then it should be invisible for next 3 secons..
Kind of any permutation combination , the behaviour should work. Following is the sample code-
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
public class Main
{
static CounterTask task;
public static void main ( String[] args )
{
final JLabel label = new JLabel( "TEST ME " );
JButton startButton = new JButton( "Start" );
startButton.addActionListener( new ActionListener()
{
public void actionPerformed ( ActionEvent e )
{
task = new CounterTask( label );
task.execute();
}
} );
JButton cancelButton = new JButton( "Cancel" );
cancelButton.addActionListener( new ActionListener()
{
public void actionPerformed ( ActionEvent e )
{
task.cancel( true );
}
} );
JPanel buttonPanel = new JPanel();
buttonPanel.add( startButton );
buttonPanel.add( cancelButton );
JPanel cp = new JPanel();
LayoutManager layout = new BoxLayout( cp, BoxLayout.Y_AXIS );
cp.setLayout( layout );
cp.add( buttonPanel );
cp.add( label );
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setContentPane( cp );
frame.pack();
frame.setVisible( true );
}
}
class CounterTask
extends SwingWorker< Integer, Integer >
{
int DELAY = 3000;
JLabel label;
int WAIT = 5000;
public CounterTask ( JLabel label )
{
this.label = label;
}
@Override
protected Integer doInBackground () throws Exception
{
int i = 0;
int count = 1000;
while ( !isCancelled() && i < count )
{
i++;
publish( new Integer[] { i } );
label.setVisible( false );
Thread.sleep( DELAY );
}
return count;
}
protected void process ( List< Integer > chunks )
{
Integer strContent = chunks.get( chunks.size() - 1 );
label.setVisible( true );
label.validate();
label.setText( "DISPLAYING " + strContent );
try
{
Thread.sleep( WAIT );
}
catch ( InterruptedException e )
{
e.printStackTrace();
}
}
@Override
protected void done ()
{
if ( isCancelled() )
System.out.println( "Cancelled !" );
else
System.out.println( "Done !" );
}
}
I am definately doing something wrong , as this combination works for some data and mostly JLabel becomes invisible throughout , but if I put SOP , I get proper data at proper delay and wait time.
The above code of Swing worker has two variable WAIT , DELAY . WAIT makes the JLabel visible for X seconds and DELAY make the JLAbel invisible for Y seconds. But if try with different perm and comb you will realize JLabel visibility not working as expected. It may be because of EDT updates of Label or something to do with repaint. Not sure the root cause.
Expected :
- Want to make the code work like SOP working or in ideal case.
- Need to know the reason of not behaving properly.
SwingWorker is an overkill for just a blinking label. Try the following timer-based approach, it requires no thread magic at all:
public class Main {
private static Timer setVisibleTimer;
private static Timer setInvisibleTimer;
public static void main(String[] args) {
final JLabel label = new JLabel("TEST ME ");
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisibleTimer = new Timer(8000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label.setVisible(true);
}
});
setInvisibleTimer = new Timer(5000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label.setVisible(false);
}
});
setVisibleTimer.start();
setInvisibleTimer.start();
}
});
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
label.setVisible(true);
if (setVisibleTimer != null){
setInvisibleTimer.stop();
setVisibleTimer.stop();
}
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(startButton);
buttonPanel.add(cancelButton);
JPanel cp = new JPanel();
LayoutManager layout = new BoxLayout(cp, BoxLayout.Y_AXIS);
cp.setLayout(layout);
cp.add(buttonPanel);
cp.add(label);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(cp);
frame.pack();
frame.setVisible(true);
}
}