2016-07-26 24 views
0

Je travaille sur un projet swing. Il y a une carte, j'ai des images raster d'une donnée donnée pour différents temps. Normalement, je change l'heure via un JSlider et il demande au serveur d'obtenir une image raster. Ensuite, j'ajoute l'image de réponse à la carte. Il y a un jeu JButton, lorsqu'il est pressé, il va ajouter ces images une par une à la couche raster de la carte. Ce sera vu comme une animation. Dans cette JButton'sactionPerfomed méthode je change la valeur JSlider's dans une boucle for.Jslider ne peut pas cocher lorsque sa valeur a changé de JButton périodiquement

Mon problème est lorsque j'appuie sur Lecture JButton, je ne vois pas les données sont jouées mais je sais que le bloc de code fonctionne parce que j'enregistre chaque image (du serveur). J'ai découvert que c'est parce que JButton ne libère pas Focus jusqu'à ce que sa méthode actionPerformed se termine. Parce que JButton avait l'air d'avoir été pressé jusqu'à la fin. Donc, je ne vois que la dernière image sur la carte. D'abord, j'ai essayé JButton.setFocusable(false) etc. mais à aucun bon. Deuxièmement, j'ai essayé d'utiliser SwingWorker. Je l'ai ajouté comme ceci:

class PlayMvgmLayerWorker extends SwingWorker<Void, Void> { 

public PlayMvgmLayerWorker(String title) { 
    super(title); 
} 

@Override 
protected void done(Void aVoid) { 

} 

@Override 
protected Void doInBackground() { 
    try{ 
     BufferedImage[] image = new BufferedImage[24]; 
     for(int i=0; i<24; i++) { 

      final int value = i - 48 + 24; 
      timeSlider.setValue(value); 
      Thread.sleep(10000l); 
     } 
    } catch(Exception ex) { 
     ex.printStackTrace(); 
    } 
    return null; 
} 
} 

private JButton animation = new JButton(""); 

animation.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 

     new PlayMvgmLayerWorker("title").execute(); 
    } 
}); 

private JSlider timeSlider = new JSlider(); 
timeSlider.addChangeListener(new ChangeListener() { 
    @Override 
    public void stateChanged(ChangeEvent e) { 
     // time consuming processes (server call, add image to map, etc) 
    } 
}); 

J'ai essayé de le simplifier.

C'est beaucoup mieux qu'auparavant, mais je n'arrive toujours pas à voir les données correctement. Parfois, les données sont jouées après JSlider ticks. Se pourrait-il que mon processus fastidieux soit dans l'événement second components(JSlider)stateChanged? Dois-je utiliser un autre événement SwingWorker dans JSlider's? Des suggestions sur ce que je peux faire?

De plus, quel serait le meilleur moyen de désactiver tous les composants avant de lire des données et de les activer après avoir joué les données?

Merci beaucoup à l'avance

+0

Pour mieux aider plus tôt, poster un [ MCVE] ou [Short, Self Contained, Exemple correct] (http://www.sscce.org/). –

Répondre

1

Si vous avez deux activités Activité A et l'activité B qui doivent être exécutées simultanément, vous devez créer un fil pour la deuxième activité - la première activité sera déjà exécuté en son propre fil (le programme principal).

Le schéma est le suivant:

Program A: 

    create new Thread: Activity B 

    run allother tasks for Activity A 

En termes plus spécifiques, le programme suivant exécutera votre simulation et mettre à jour la tique du curseur:

public P() { 

animation.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     doInBackgroundImp(); 
    } 
}); 

    setSize(500, 500); 
    setLayout(new FlowLayout()); 
    add(animation); 
    add(timeSlider); 
    setVisible(true); 
} 

protected void doInBackgroundImp() { 
    Thread th=new Thread() { 
     public void run() { 
    try{ 
     for(int i=0; i<24; i++) { 

      final int value = i - 48 + 24; 
      timeSlider.setValue(i); 
      System.out.println(timeSlider.getValue()+" "+value); 
      Thread.sleep(1000); 
     } 
    } catch(Exception ex) { 
     ex.printStackTrace(); 
    } 
     } 
    }; 
    th.start(); 
} 

private JButton animation = new JButton(""); 

private JSlider timeSlider = new JSlider(); 

}