-1

I have ClassA that does some processing and I want it to create a popup Jframe ClassB that shows some statistics that ClassA calculated. So I did something like this:

public class MainMenu extends javax.swing.JFrame {

public MainMenu() {
    initComponents();
}

private void initComponents() {

    calculateButton = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    calculateButton.setText("Calculate");
    calculateButton.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            calculateButtonActionPerformed(evt);
        }
    });

    pack();
}             

private void calculateButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                
    new ClassA().calculate();
}
public static void main(String args[]) {

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new MainMenu().setVisible(true);
        }
    });
}




public class ClassA {
private int i;
private ClassB classB;
public ClassA(){
    i = 3000;
    classB = new ClassB();
    classB.setVisible(true);


}

public void calculate(){
    int percentComplete;
    for (int j = 0 ; j<i ; j++){
        for (int x = 0; x<100000 ; x++)
            for (int y = 0; y<100000 ; y++)
                for (int z = 0; z<100000 ; z++);
        percentComplete = (int) (100 * (float)j/ (float) i);
        System.out.println(" "+percentComplete);
        classB.setProgress(percentComplete);
    }
}   

}

public class ClassB extends javax.swing.JFrame {

public ClassB() {
    initComponents();
}

private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    jProgressBar1 = new javax.swing.JProgressBar();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jProgressBar1.setStringPainted(true);
    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addComponent(jProgressBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 370, Short.MAX_VALUE)
            .addContainerGap())
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(39, 39, 39)
            .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(52, Short.MAX_VALUE))
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(181, Short.MAX_VALUE))
    );

    pack();
}

public void setProgress(int x){
    jProgressBar1.setValue ( x );
}


private javax.swing.JPanel jPanel1;
private javax.swing.JProgressBar jProgressBar1;

}

The problem I'm facing is that the JFrame of ClassB appears as an empty window and doesn't show anything until all the processes/calculations of ClassA have finished. Then it shows its contents but with the last updates from the data of ClassA. Any ideas or solutions?

Pokopik
  • 23
  • 3
  • 1
    for better help sooner post an SSCCE / MCVE, short, runnable, compilable – mKorbel Jun 19 '15 at 14:54
  • 1
    Brief explained: Swing/AWT does GUI on a single thread. If you have other threads working (processes/calculations of ClassA in your main thread) the GUI thread is "paused". Reading this may help you: http://stackoverflow.com/questions/7217013/java-event-dispatching-thread-explanation – PeterMmm Jun 19 '15 at 14:56

1 Answers1

3

You didn't show how you call those methods of ClassA that make various calculations. I can only guess that you call all of them in an event dispatch thread (see The Event Dispatch Thread for details) and Java cannot render anything until ClassA completes its processing.

If that is the case you should run those calculation in other thread. The most convenient way of doing this is using SwingWorker.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • ClassA is called from another JFrame (main menu) – Pokopik Jun 19 '15 at 15:11
  • 1
    *"another JFrame"* 1) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) 2) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). – Andrew Thompson Jun 19 '15 at 15:13