Results 1 to 11 of 11
  1. #1
    FezKazi is offline Member
    Join Date
    Feb 2009
    Posts
    6
    Rep Power
    0

    Default [SOLVED] Gui becomes unresponsive!

    note: I have two classes that extend the JFrame class.

    my Main calls DisplayQueryResults, which offers a GUI interface for the user to interact with my Database.
    Display Query results give the user the option to insert, delete and update rows. So far I have only implemented Insertion.

    When the user chooses to insert a row, a RowEntryFormat object is created and its update function is called.

    This in turn creates an InputWindow object (which calls its own createGUI method from its constructor)

    Using debug mode and stepping thru everything i found that when we step into the RowEntryFormat.insertion() method, the InputWindow GUI becomes completely unresponsive, and RowEntryFormat keeps sleeping, waiting on the user to enter data in the InputWindow and click ok or cancel, but this won't happen because the GUI doesnt respond. The only thread that seems to be actively running is RowEntryFormat.insertion()

    Heres my output to the console:
    *******
    AWT-EventQueue-0 is about to sleep!!
    AWT-EventQueue-0 is about to sleep!!
    AWT-EventQueue-0 is about to sleep!!
    AWT-EventQueue-0 is about to sleep!!
    AWT-EventQueue-0 is about to sleep!!
    AWT-EventQueue-0 is about to sleep!!
    AWT-EventQueue-0 is about to sleep!!
    AWT-EventQueue-0 is about to sleep!!

    AND SO ON.............
    *******
    These printed lines are all from RowEntryFormat.insertion()

    why does the GUI become unresponsive? why is RowEntryFormat taking up all the CPU time?

    Heres my code... Ive left out a LOT of the details, but included all the important stuff (i hope)

    Java Code:
    public class DisplayQueryResults extends JFrame {
    	//default constructor initializes some variables and sets up the GUI
    	DisplayQueryResults() { 
    		.......... blah blah 
    		RowEntryFormat rowEntry = new RowEntryFormat();
    		..... blah blah
    		//if the user selects the Insert Row options the ActionListener is activated and:
    		{
    			insertRow();
    		}
    	}
    	private void insertRow() {
    		rowEntry.insertion();
    		...... blah blah
    	}
    }
    Java Code:
    public class RowEntryFormat {
    	//default constructor initializes variables
    	RowEntryFormat () {
    		InputWindow myInputWindow = new InputWindow();
    		...... blah blah
    	}
    	protected void insertion () {
    		while (!myInputWindow.quit()){
    			try {
    				System.out.println(Thread.currentThread().getName() + " is about to sleep!!");
    				Thread.sleep(2000);				
    				// myInputWindow becomes unresponsive!! this thread seems to take all priority!
    				// it just keeps looping and looping, waiting for the user to enter the info and quit
    			} 
    			catch (InterruptedException e) {
    				DialogBox.showDialog("Row Entry Format thread could not be put to sleep");
    				e.printStackTrace();
    			}
    			
    			//when it gets down here it will collect 
    			//gathered information from myInputWindow 
    			//and insert a new row in the database
    		}
    	}
    }
    Java Code:
    public class InputWindow extends JFrame implements WindowListener{
    	public InputWindow() {
    		super("Data Input Window");
    		javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
    	}
    	
    	private void createAndShowGUI() {
    		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            
            //set up grid bad layout
    		//Create the fields and set them up
            firstName = new JTextField(20);
            JLabel firstNameLabel = new JLabel("First Name:");
            firstNameLabel.setDisplayedMnemonic('N');
            firstNameLabel.setLabelFor(firstNameLabel);
            lastName = new JTextField(20);
            JLabel lastNameLabel = new JLabel("Last Name:");
            lastNameLabel.setDisplayedMnemonic('N');
            lastNameLabel.setLabelFor(lastNameLabel);
                  
            display = new JTextArea(5,20);
            display.setEditable(false);
            JScrollPane scrollPane = new JScrollPane(display);
            scrollPane.setPreferredSize(new Dimension(400, 200));
    
            JButton okButton = new JButton("OK");
            okButton.setPreferredSize(new Dimension(100,
                    (int) okButton.getPreferredSize().getHeight()));
            okButton.addActionListener(new ActionListener() {
    			@Override
    			public void actionPerformed(ActionEvent arg0) {
    				//SUBMIT DATA
    				FirstName = firstName.getText();
    				LastName = lastName.getText();
    				//System.out.println("Name entered was:\t" + FirstName + "\t" + LastName );
    				quit = true;
    				frame.dispose();
    				//this.notifyAll();
    			}
            });
            JButton cancelButton = new JButton("Cancel");
            cancelButton.addActionListener(new ActionListener(){
    			@Override
    			public void actionPerformed(ActionEvent arg0) {
    				quit = true;
    				frame.dispose();
    			}
            });
            cancelButton.setPreferredSize(new Dimension(100,
                    (int) cancelButton.getPreferredSize().getHeight()));
    
            JPanel panel = new JPanel(new GridBagLayout());
            panel.setBorder(BorderFactory.createEmptyBorder(4, 10, 10, 10));
    
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.anchor = GridBagConstraints.WEST;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(6, 6, 0, 0);
            gbc.gridx = GridBagConstraints.RELATIVE;
            gbc.gridy = 0;
    
            panel.add(firstNameLabel, gbc);
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            panel.add(firstName, gbc);
            
            gbc.gridy++;
            gbc.gridwidth = 1;
            
            panel.add(lastNameLabel, gbc);
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            panel.add(lastName, gbc);    
            
            gbc.gridy++;
            gbc.gridwidth = 2;    
            
            panel.add(scrollPane, gbc);
            gbc.gridwidth = GridBagConstraints.REMAINDER;
    
            JPanel buttonPanel = new JPanel(new GridBagLayout());
            gbc.gridwidth = 1;
            gbc.gridy = 0;
            buttonPanel.add(okButton, gbc);
            buttonPanel.add(cancelButton, gbc);
    
            panel.add(buttonPanel,
                    new GridBagConstraints(1, 3, 4, 1, 0, 0,
                            GridBagConstraints.EAST, GridBagConstraints.NONE,
                            new Insets(0, 0, 0, 0), 0, 0));
    
            panel.add(Box.createGlue(),
                    new GridBagConstraints(0, 4, 4, 1, 0, 1,
                            GridBagConstraints.EAST, GridBagConstraints.NONE,
                            new Insets(0, 0, 0, 0), 0, 0));
            
            //Set up the content pane.
        	//myPanel = buildGridBagLayout();
        	panel.setOpaque(true); //content panes must be opaque
        	panel.repaint();
            frame.setContentPane(panel);
            addWindowListener(this);    
            
            //Display the window.
            //frame.setSize( 300, 250 );
            frame.pack();
            frame.setVisible(true);
            System.out.println("Win_TF_Layout GUI method is finishing up");
    	}
    	
    	//All the window listeners are implemented down here
    }

  2. #2
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    20

    Default

    Do you know about threads. If not, best thing is work on some examples on thread before carry on.

    Using threads you can handle multiple process at the same time. In your case, UI interactions of users in one thread and process the DB in another thread. Once you read more about Threads, you can clear up more what I say here.

  3. #3
    FezKazi is offline Member
    Join Date
    Feb 2009
    Posts
    6
    Rep Power
    0

    Default

    I was using a separate thread for each class until I hit this problem. to make everything simpler i got rid of all the thread code, but it didnt help me...
    the problem is exactly the same now with, or without the thread code that I had put in.
    so once i fix this problem, i'll put all the threading back in.

    somehow, i think the problem is that when i run either of my GUI's they run on the EDT and keep sitting on it... rather than "sharing". thus one is blocking the other.
    I suppose i can double check it with : javax.swing.SwingUtilities.isEventDispatchThread()
    but im fairly certain theyre just hogging it, by looking at the console output

    any ideas?
    I am reading all the material at: java.sun.com/ docs /books /tutorial /uiswing /concurrency (Lesson: Concurrency in Swing (The Java™ Tutorials > Creating a GUI with JFC/Swing), but a couple hints would be much appreciated! :)


    Quote Originally Posted by Eranga View Post
    Do you know about threads. If not, best thing is work on some examples on thread before carry on.

    Using threads you can handle multiple process at the same time. In your case, UI interactions of users in one thread and process the DB in another thread. Once you read more about Threads, you can clear up more what I say here.

  4. #4
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    20

    Default

    Thread prioritizing is one of the solution you can workout.

    Anyway, all what you need is here. Just check with examples there.

  5. #5
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    I can't tell exactly what you are doing, but I noticed a Thread.sleep(2000). In addition, your remarks about threads seem suspicious.

    *Never* run *any* GUI related code on your own thread. Swing has its own Event Dispatcher Thread (EDT), where *all* GUI code is supposed to run. In addition, you can run your own code in response to GUI events on the EDT, as long as they don't take forever.

    *Never* do a Thread.sleep() on the EDT. That prevents the GUI from responding.

    A JFrame represents a window. How many applications do you see that have more than one main window? Instead of creating multiple JFrame's, create one and create multiple JPanel's instead. Add the JPanel's to the JFrame, and control their visibility.

    Get rid of the threads. I doubt you need them, and they are adding a huge amount of complexity to your code. Updating GUI components from outside the EDT requires special code involving EventQueue.InvokeLater().

    Keep your existing code, but start a new source file. Rebuild your application, keeping things as simple as possible.

  6. #6
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,184
    Rep Power
    19

    Default

    Jsut another cross poster.
    Swing - Gui becomes unresponsive!

    db

  7. #7
    FezKazi is offline Member
    Join Date
    Feb 2009
    Posts
    6
    Rep Power
    0

    Default

    You are right.I shouldnt be messing with the EDT thread. i was causing the EDT to sleep, because I allowed a long-running process to take over the EDT (in the insert method, which waits on user input)

    I fixed it by adding a new thread... strangely enough threads saved the day.
    the new thread went into the insertion function, so that it caused this new thread to sleep and wait on input rather than causing the EDT to sleep and wait. therefore preventing my GUI from becoming unresponsive. wasn't my idea, but some thread friendly guy on another forum gave me this advice and it worked :)

    I shall try using multiple Jpanels like you said, it seems like a much neater solution.

    also, thanks for informing me about EventQueue.InvokeLater(). im sure ill find that useful.


    Quote Originally Posted by Steve11235 View Post
    I can't tell exactly what you are doing, but I noticed a Thread.sleep(2000). In addition, your remarks about threads seem suspicious.

    *Never* run *any* GUI related code on your own thread. Swing has its own Event Dispatcher Thread (EDT), where *all* GUI code is supposed to run. In addition, you can run your own code in response to GUI events on the EDT, as long as they don't take forever.

    *Never* do a Thread.sleep() on the EDT. That prevents the GUI from responding.

    A JFrame represents a window. How many applications do you see that have more than one main window? Instead of creating multiple JFrame's, create one and create multiple JPanel's instead. Add the JPanel's to the JFrame, and control their visibility.

    Get rid of the threads. I doubt you need them, and they are adding a huge amount of complexity to your code. Updating GUI components from outside the EDT requires special code involving EventQueue.InvokeLater().

    Keep your existing code, but start a new source file. Rebuild your application, keeping things as simple as possible.

  8. #8
    FezKazi is offline Member
    Join Date
    Feb 2009
    Posts
    6
    Rep Power
    0

    Default

    Thanks for the link! its awesome documentation!

    Quote Originally Posted by Eranga View Post
    Thread prioritizing is one of the solution you can workout.

    Anyway, all what you need is nicolas.blancpain.free.fr /Documents/Java/online/ Chapter14.html. Just check with examples there.

  9. #9
    Steve11235's Avatar
    Steve11235 is offline Senior Member
    Join Date
    Dec 2008
    Posts
    1,046
    Rep Power
    7

    Default

    Two things.

    If it ain't broke, don't fix it.

    Waiting for input *should* (has to?) happen on the EDT. Is your thread examining the content of a JComponent and acting when the content changes? If so, at least declare the component with the "volatile" keyword. That makes sure that both threads are looking at the same values.

    The "right" way to handle content changes in a JTextComponent or one of its children is to create a custom model object and handle changes through the model. Start in the API for JTextComponent, read the summary information, and then look at getDocument and setDocument.

    Or don't, if it ain't broke...

  10. #10
    FezKazi is offline Member
    Join Date
    Feb 2009
    Posts
    6
    Rep Power
    0

    Default

    hahha, well, now that youve mentioned some new interesting details, i won't "fix it", ill just create a new project and try out what youre saying.

    yes, the thread is waiting on user input, and by extension, we can say that is it waiting on the content of a JComponent to change. I shall try to declare it volatile in my next revision. :)
    Although, I have structured it such that the thread that waits on the object is the ONLY thread that actually accesses that object later, so my data is safe.

    ive worked with custom models before, and i should probably do that again, taking it slow for now, because im new to threading and database stuff.

    thanks, ill look up the documentation :)

  11. #11
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    20

    Default

    Quote Originally Posted by FezKazi View Post
    Thanks for the link! its awesome documentation!
    You are welcome. Try to learn something new from there. That make me happy :p

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •