1

For some reason, when I run the code in the main it works but currently I have the code only run when a JButton is

enter link description here

import java.awt.Color;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JProgressBar;


public class JavaCompilingJOP {

    private JFrame framed = new JFrame();
    private JProgressBar bar = new JProgressBar(0,100); //0 through 100 is the compiling until reaches that number
    private Color startProgress = Color.RED;
    private int loadingPercent = 0;

    public JavaCompilingJOP(){
        framed.setLayout(null);
        framed.setSize(500, 200);
        framed.setTitle("Compiling JOptionPane...");
        framed.setLocationRelativeTo(null);
        //Ok now lets make the GUI happen boys!
        framed.getContentPane().setBackground(Color.BLACK); //Because startProgress is ze theme of ze game!

        bar.setForeground(startProgress);
        bar.setStringPainted(true);
        bar.setValue(loadingPercent);
        bar.setString(loadingPercent + "%");
        bar.setBounds(50, 50, 400, 100);
        framed.add(bar);

        System.out.println("Make visible an run!");

        framed.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        framed.setResizable(false);

        framed.setVisible(true);

        doTimer();
    }

    private void doTimer(){
        Random obj = new Random();
        for(int i = 0; i < 100; i++){
            loadingPercent++;
            bar.setValue(loadingPercent); //Updates counter
            bar.setString(loadingPercent + "%"); //Updates progressbar
            startProgress = new Color(startProgress.getRed()-2,startProgress.getGreen()+2,startProgress.getBlue());
            bar.setForeground(startProgress);
            try{Thread.sleep(100 + obj.nextInt(200));}catch(Exception E){}

        }
        System.out.println("Java compiled!");
        framed.setVisible(false);
    }
}

For some reason all I am getting though when called is a white screen that seems to neglect disposing on close because when I hit to close it.. it doesn't either. Keep in mind that when I run it in the main it works but when inside the ActionListener of the button, it gives me a blank screen that still performs it's progressbar stuff. Im stuck on this.

  • Can you post a screenshot – CMPS Dec 06 '15 at 16:01
  • @CMPS Just added one, its a direct link but it shows the GUI. I could add another one showing the GUI correctly running in the main if needed – ghostbuzzer7 Dec 06 '15 at 16:07
  • 3
    `framed.setLayout(null);` 1) Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). 2) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Dec 06 '15 at 16:26
  • 2
    3) Swing/AWT GUIs should be constructed on the EDT. See [Concurrency in Swing: Initial Threads](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html) for details. (But concentrate on: layout the components then `pack()` the container.) – Andrew Thompson Dec 06 '15 at 16:28
  • 4
    4) It appears the `doTimer()` method is also blocking the EDT - which is probably the root cause of the observed behavior. Don't block the EDT (Event Dispatch Thread). The GUI will 'freeze' when that happens. See [Concurrency in Swing](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for details and the fix. – Andrew Thompson Dec 06 '15 at 16:33

1 Answers1

1

Your JButton's actionPerformed() code gets executed on the Java event dispatch thread (EDT) and this is why the GUI "freezes" and you see a black screen.
Doing so, also blocks the "close" event from being executed as well as any other swing event.
Important:
The EDT is a special thread which should be handled very carefully.
Please take the time and read on EDT and how to properly use it here.

Correct method:
doTimer() should never run on Java event dispatch thread (EDT) since it simulates (I hope) some long-running task.
To make sure we handle the EDT correctly we use a SwingWorker.
SwingWorkers are special constructs designed to perform lengthy GUI-interaction tasks in a background thread.
Since this is kinda tricky to handle for the first time, I added the following code for you:

@Override
public void actionPerformed(ActionEvent e) {
    SwingWorker<Object, Object> sw = new SwingWorker<Object, Object>() {
        @Override
        protected Object doInBackground() throws Exception {
            // Code here will be executed in a background thread
            // This is where all background activities should happen.
            doTimer();
            return null;
        }
    };
    sw.execute();
    //  doTimer(); Bad Idea as this will execute on EDT!
}
Leet-Falcon
  • 2,107
  • 2
  • 15
  • 23