Я пытаюсь обновить JLabel в некотором ожидаемом поведении, например -
COND 1: JLabel должен отображаться в течение 5 секунд, затем он должен быть невидимым в течение следующих 3 секунд, затем он должен отображаться в течение 5 секунд и так далее.
COND 2: JLabel должен отображаться в течение 0,5 секунды, затем он должен быть невидимым в течение следующих 3 секунд.
Вид любой комбинации перестановок, поведение должно работать. Ниже приведен пример кода:
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 !" );
}
}
Я определенно делаю что-то не так, так как эта комбинация работает для некоторых данных, и в основном JLabel становится невидимым повсюду, но если я ставлю SOP, я получаю правильные данные с правильной задержкой и временем ожидания.
Приведенный выше код Swing worker имеет две переменные WAIT , DELAY . WAIT делает JLabel видимым на X секунд, а DELAY делает JLAbel невидимым на Y секунд. Но если попробовать другую завивку и расческу, вы обнаружите, что видимость JLabel не работает должным образом. Это может быть из-за обновлений лейбла EDT или из-за перерисовки. Не уверен в первопричине.
Ожидал :
- Хотите, чтобы код работал как SOP или в идеальном случае.
- Нужно знать причину неадекватного поведения.
setVisible(true/false)
использовать простоsetText(""/"newValue")
. Так что вам действительно не нужноrevalidate()/repaint()
каждый раз. И просто переберитеchunks
, чтобы отобразить содержимое вJLabel
, вместо того, чтобы явно брать верхнее значение из списка и отображать то же самое вJLabel
, т.е. просто поместите только эти две строки в методprocess()
for (Integer chunk : chunks) label.setText( "DISPLAYING " + chunk.toString() );
:-) +1 для предоставления исполняемого пример :-) - person nIcE cOw   schedule 07.09.2013