2017-09-05 6 views
0

J'ai rencontré un problème avec mon code ici que je ne suis pas en mesure d'expliquer. J'ai deux Jframes, le premier a un bouton qui, lorsqu'il est cliqué, conduit à la deuxième image. Cela fonctionne bien. Mais un problème est ici: la deuxième image est d'abord apparue comme skeleton, sans le JComponents que j'ai ajouté à elle. Il attend jusqu'à ce que toutes les instructions soient exécutées, c'est-à-dire paintsJComponents sur le JFrame affiché skeleton.Pourquoi Swing tarde-t-il à «peindre complètement» le JFrame ici?

Pourquoi est-ce ainsi? Comment puis-je faire "afficher/peindre" tous les composants avant d'exécuter la prochaine ligne de code?

Ci-dessous est mon code

import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.event.ActionEvent; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 

/** 
* 
* @author JWizard 
*/ 
public class Test { 

    private JFrame frame; 
    private JButton button; 

    public Test() { 
     initGUI(); 
     button.addActionListener((ActionEvent e) -> { 
      JFrame frame1 = new JFrame("Second Jframe"); 
      frame1.setPreferredSize(new Dimension(300, 300)); 
      frame1.getContentPane().add(new JLabel("Swing Component")); 
      frame1.pack(); 
      frame1.setVisible(true); 
      frame1.setLocationRelativeTo(null); 
      /** 
      * After executing the above line, 
      * 'frame1.setLocationRelativeTo(null);', I am expecting the program 
      * to have fully "painted" my fame1 GUI, showing the label. 
      */ 
      try { 
       Thread.sleep(7000); 
       System.out.println("statement 1"); 
       Thread.sleep(7000); 
       System.out.println("statement 2");//after executing this statment thats when 
       //the program paints the components of frame1 
      } catch (InterruptedException ex) { 
       Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     }); 

    } 

    private void initGUI() { 
     frame = new JFrame("Frame 1"); 
     button = new JButton("Go to Frame 2"); 
     frame.setLayout(new FlowLayout(FlowLayout.LEADING)); 
     frame.setPreferredSize(new Dimension(300, 300)); 
     frame.getContentPane().add(button); 
     frame.pack(); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 

    } 

    public static void main(String[] args) { 
     Test text = new Test(); 
    } 

} 
+0

Vous bloquer le thread de distribution d'événements qui gère la remise en peinture de l'interface utilisateur, etc. – Thomas

+0

@Thomas Où suis-je le bloquer? – JWizard

+3

"Où est-ce que je le bloque?" 'Thread.sleep (7000);' Ici. – Fildor

Répondre

1

pour cette solution:

public Test() { 
     initGUI(); 
     button.addActionListener((ActionEvent e) -> { 
      JFrame frame1 = new JFrame("Second Jframe"); 
      frame1.setPreferredSize(new Dimension(300, 300)); 
      frame1.getContentPane().add(new JLabel("Swing Component")); 
      frame1.pack(); 
      frame1.setVisible(true); 
      frame1.setLocationRelativeTo(null); 

      new SwingWorker<Void, Void>() { 
       @Override 
       protected Void doInBackground() throws Exception { 
        try { 
         Thread.sleep(7000); 
         System.out.println("statement 1"); 
         Thread.sleep(7000); 
         System.out.println("statement 2"); 
        } catch (InterruptedException ex) { 
         Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); 
        } 
        return null; 
       } 
      }.execute(); 
     }); 

} 
+0

Merci votre solution répond à ma deuxième question. J'ai eu le concept. – JWizard