0

I have troubles with my application. The concept is that i want to creat a window which display the progress of java commands. Here is the code of this:

import java.awt.*;

import javax.swing.*;

class DosCommandsWindow extends JFrame{

    JLabel firstMsg, progressMsg, enFolderMsg, dbMsg, shortcutMsg, finishedMsg;//koina JLabel.Etiketes host, port, dbName, user kai password

    public DosCommandsWindow()//arxikh dhmiourgia tou frame
    {
        super("Endocrino Installation");
        this.setSize(400,200);
        this.setMinimumSize(new Dimension(400,200));
        this.setMaximumSize(new Dimension(400,200));
        this.setResizable(true);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }//constractor

    public void createForm(int rows,int columns,int vgap,int hgap)//orizei sto panel tou frame topothethsh sumfwna me to GridLayout
    {
        JPanel panel=new JPanel();
        GridLayout g=new GridLayout(rows,columns,vgap,hgap);
        panel.setLayout(g);
        this.setContentPane(panel);

        this.addElements();
    }//createForm

    public void addProgressMsg()//prosthetei to minima "Plese wait.."
    {
        Container c=this.getContentPane();
        this.progressMsg=new JLabel("Progress");
        c.add(this.progressMsg);
    }


    public void addFirstMsg()//prosthetei to minima "Plese wait.."
    {
        Container c=this.getContentPane();
        this.firstMsg=new JLabel("Please wait...");
        c.add(this.firstMsg);
    }//addFirstMsg

    public void addEnFolderMsg()//prosthetei to label gia tin dimiourgia tou fakelou C:/Endocrino
    {
        Container c=this.getContentPane();
        this.enFolderMsg=new JLabel("jju");
        c.add(this.enFolderMsg);
    }//addEnFolderMsg

    public void addDBMsg()//prosthetei to label gia tin dimiourgia tis basis
    {
        Container c=this.getContentPane();
        this.dbMsg=new JLabel("jbj");
        c.add(this.dbMsg);
    }//addDBMsg

    public void addShortcutMsg()//prosthetei to label gia tin dimiourgia tou shortcut sto Desktop
    {
        Container c=this.getContentPane();
        this.shortcutMsg=new JLabel("jbgj");
        c.add(this.shortcutMsg);
    }//addShortcutMsg

    public void addFinishedMsg()//prosthetei to label gia tin dimiourgia tou minimatos "finished"
    {
        Container c=this.getContentPane();
        this.finishedMsg=new JLabel("jg");
        c.add(this.finishedMsg);
    }//addFinishedMsg

    public void showForm()//emfanizei to frame
    {
        this.setVisible(true);  
    }//showFrame

    public void addElements(){
        this.addProgressMsg();
        this.addFirstMsg();
        this.addEnFolderMsg();
        this.addDBMsg();
        this.addShortcutMsg();
        this.addFinishedMsg();
    }//addElements

    public void close(){
        this.dispose();
        System.exit(0);
    }

    public void dosCommands(){
        this.enFolderMsg.setText("Creating Endocrino Folder...");
        java.lang.Thread.sleep(1000);
        revalidate();repaint();
        this.dbMsg.setText("Creating Data Base...");
        java.lang.Thread.sleep(1000);
        revalidate();repaint();
        this.shortcutMsg.setText("Creating shortcut...");
        java.lang.Thread.sleep(1000);
        revalidate();repaint();
        this.finishedMsg.setText("Finished");
        JOptionPane.showMessageDialog(null,"Now you can delete the Endocrino folder from your Desktop");
        close();
    }//dosCommands
}//DosCOmmandsWindow

The problem is that when i run this class it goes well but when call it from another jframe it doesn't. This is the frame which call the DosCommandsWindow

import java.awt.*;

import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;

class SettingsForm extends JFrame{

    JButton submit,defaultOption;//koumpia kataxwrhshs-akurwshs
    JLabel host;//koina JLabel.Etiketes host, port, dbName, user kai password
    JTextField hostT;//koina JTextField.perioxh egrafhs twn host, port, dbName, user kai password

    public SettingsForm()//arxikh dhmiourgia tou frame
    {
        super("Data Base Information");
        this.setSize(300,300);
        this.setMinimumSize(new Dimension(300,300));
        this.setMaximumSize(new Dimension(300,300));
        this.setResizable(true);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

    }//constractor

    public void createForm(int rows,int columns,int vgap,int hgap)//orizei sto panel tou frame topothethsh sumfwna me to GridLayout
    {
        JPanel panel=new JPanel();
        GridLayout g=new GridLayout(rows,columns,vgap,hgap);
        panel.setLayout(g);
        this.setContentPane(panel);

        this.addElements();

        submit.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                if (hostT.getText().length()!=0)
                {
                    try {
                    CreateSettings s = new CreateSettings("Endocrino\\settings.txt");
                    s.write(hostT.getText());
                    close();
                    } catch (FileNotFoundException e1) {
                        e1.printStackTrace();
                    } catch (Exception e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
                else{
                    JOptionPane.showMessageDialog(null,"All items must be filled","Warning",JOptionPane.ERROR_MESSAGE);
                }
            }
        });

        defaultOption.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {   hostT.setText("localhost");
            }
        });
    }//createForm


    public void addButtons()//prosthetei to koumpi kataxwrhshs sto panel
    {
        Container c=this.getContentPane();
        this.submit=new JButton("OK");
        this.defaultOption=new JButton("Set Default");

        c.add(submit);
        c.add(defaultOption);
    }//addButtons

    public void addHost()//prosthetei to label kai text field gia egrafh tou host apo ton xrhsth
    {
        Container c=this.getContentPane();
        this.host=new JLabel("Host");
        this.hostT=new JTextField();
        c.add(host);
        c.add(hostT);
    }//addHost

    public void showForm()//emfanizei to frame
    {
        this.setVisible(true);
    }//showFrame

    public void addElements(){
        this.addHost();
        this.addButtons();
    }//addElements

    public void close(){
        this.dispose();
        DosCommandsWindow d=new DosCommandsWindow();
        d.createForm(6,1,3,3);
        d.showForm();
        d.dosCommands();
    }//close
}//SettingsForm
xarlap
  • 157
  • 1
  • 2
  • 14
  • 3
    Never use `Thread.sleep(1000);` in swing application instead have a look at **Swing Timer**. – Braj Jul 14 '14 at 23:02
  • 2
    Try to avoid `setMinimumSize()`, `setMaximumSize()` and `setSize()` and leave it for Layout Manager to set the size and position based on component's preferred size. Use `JFrame#pack()` instead of `setSize()` – Braj Jul 14 '14 at 23:03
  • 1
    1+ on @Braj's recommendations. Your code ignores Java Swing threading rules. Also, you know that Java is case sensitive and spelling matters, that dosComandsWindow is not the same as DosCommandsWindow. Your SettingsForm window declares a DosCommandsWindow, and your class posted above is called dosComandsWindow which is spelled and capitalized differently. Your code also seems to have a lot of unnecessary cyclomatic complexity. – Hovercraft Full Of Eels Jul 14 '14 at 23:09
  • OK, you fixed a capitalization issue, but still have spelling problems. Comands != Commands. But more importantly, Braj is right, don't call `Thread.sleep(...)` inside of the Swing event thread, not unless you want to put your entire GUI to sleep. Google and read up on `Concurrency in Swing` to see why this is important. – Hovercraft Full Of Eels Jul 14 '14 at 23:16
  • Sorry "Hovercraft Full Of Eels" dosCommandsWindow was spelling mistake. What did you mean by Swing threading rules. I think tha this is the clue... – xarlap Jul 14 '14 at 23:16
  • 2
    adding one more recommendation to the ones given by @Braj is [the use of multiple JFrames Good / Bad practice?](http://stackoverflow.com/questions/9554636/the-use-of-multiple-jframes-good-bad-practice). Instead of using multiple JFrames I would recommend using [Card Layout](http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) and some other [Layout Managers](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) + as Braj also said, use [Swing Timer](http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html) instead of `Thread.sleep()` method. – Frakcool Jul 15 '14 at 00:22
  • You may also consider having a look at SwingWorker – MadProgrammer Jul 15 '14 at 00:32

1 Answers1

2

The threading rules for Swing is that all the updates of the GUI runs on a thread called EDT, aka Event Dispatcher Thread. Therefore, if you make the thread go to sleep, it kinda halts all the GUI updating processes and freezes or something generate unpredictable results.

The suggestions are using worker threads,
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

or Swing Timers as Braj mentioned in his comment
http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html

I'm giving a rough guess that the reason your application isn't working as predicted has something to do with the threads.

Also I would suggest writing swing apps with MVC structure, so you can dispose one frame and show the other with the controller.

Here's a good tutorial of the basics:
http://www.newthinktank.com/2013/02/mvc-java-tutorial/

and also a great example written by Hovercraft Full Of Eels which gave me great insipiration:
https://stackoverflow.com/a/15729267/3610291

Community
  • 1
  • 1
George Chou
  • 187
  • 10