Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / August 2005

Tip: Looking for answers? Try searching our database.

Timer event appears to move window

Thread view: 
Ed - 26 Jul 2005 19:45 GMT
Hi Im new to Swing (and a lot  other Java things to be honest) s would be
grateful for any assistance.

Im writing an app that is MDI based  Ive got an JFrame MDI into which I have
a menu bar and menu items etc and a status bar (a JPanel attached to SOUTH)

One of the menu items (the only one Ive coded so far) has the following code
to create a child window (JInternalFrame) and
m
mnuNewCase.addActionListener(new java.awt.event.ActionListener() {
   public void actionPerformed(java.awt.event.ActionEvent e) {
    Caseframe newCase=new Caseframe();
    desktopPane.add(newCase);
   }
  });

which appears to open the window as expected. However whenever I grab the
window by its title bar and drag it around the MDI space (using left mouse
drag)  it seems to jump back to its start position every 1 second. If I
continue to drag it it reappears where I was expecting it and the 1 second
later its back at the start position and so it goes on. If I leave go of the
left mouse button it jups back to the start and stays there.

Given its every 1 second Im assuming its something to do with the Status Bar
Ive coded on which I have a timer updating the clock on the the bottom right
of the status bar.

The StatusBar code contains the following in the initialisation code:
 statusTimer=new Timer();
 statusTimer.schedule(new MyStatusTask(), 0,1000);

and the following class:
private class MyStatusTask extends TimerTask {
 private SimpleDateFormat formatter;  // Formats the date displayed
    private String today;
    private String now;
    private Date currentDate;            // Used to get date to display

    public void run() {

     currentDate = new Date();
     formatter = new SimpleDateFormat ("EEE MMM dd hh:mm:ss yyyy",
Locale.getDefault());

  formatter.applyPattern("dd/MMM/yyyy");
  today = formatter.format(currentDate);
        dateField.setText(today);

        formatter.applyPattern("HH:mm:ss");
        now = formatter.format(currentDate);
        timeField.setText(now);
    }
}

which to me looks ok (if a little basic etc)

any thoughts as to why the JInternalFrame jumps around ? Is it the timer
getting in the way ?
Filip Larsen - 26 Jul 2005 23:37 GMT
> The StatusBar code contains the following in the initialisation code:
>   statusTimer=new Timer();

Note that there are two standard timer implementations, java.util.Timer
and javax.swing.Timer. Whenever you use timers in Swing to update some
part of the GUI you almost always want the later one since it makes
callback from the event dispatcher thread.

If you really want to update a Swing component from the callback of a
java.util.TimerTask you must in general use something like
java.awt.EventQueue.invokeLater() to ensure Swing thread safety. See
javax.swing.Timer for documentation and links on all this.

Regards,
Signature

Filip Larsen

Andrew Thompson - 26 Jul 2005 23:38 GMT
> Hi Im new to Swing (and a lot  other Java things to be honest)....

<http://www.physci.org/codes/javafaq.jsp#cljh>

> s would be grateful for any assistance.
>
> Im writing an app that is MDI based  Ive got an JFrame MDI into which I have
> a menu bar and menu items etc and a status bar (a JPanel attached to SOUTH)

ughh..  let the code do the talking..
<http://www.physci.org/codes/sscce.jsp>

..but having said that, you might *try*..

> mnuNewCase.addActionListener(new java.awt.event.ActionListener() {
>     public void actionPerformed(java.awt.event.ActionEvent e) {

 System.out.println("ActionEvvent " + e);

>      Caseframe newCase=new Caseframe();
>      desktopPane.add(newCase);
>     }
>    });

...

>  private class MyStatusTask extends TimerTask {
>   private SimpleDateFormat formatter;  // Formats the date displayed
[quoted text clipped - 3 lines]
>
>      public void run() {

 System.out.println("Run..");

>       currentDate = new Date();
>       formatter = new SimpleDateFormat ("EEE MMM dd hh:mm:ss yyyy",
[quoted text clipped - 9 lines]
>      }
>  }
..
> any thoughts as to why the JInternalFrame jumps around ? Is it the timer
> getting in the way ?

'Getting in the way'?  Why?  How wide did you make it?  [ ;-) ]

Signature

Andrew Thompson
physci.org 1point1c.org javasaver.com lensescapes.com athompson.info
Mr Bender's Wardrobe By ROBOTANY 500

Ed - 08 Aug 2005 22:30 GMT
Still cannot see whats going on , trying to debug timer related problems was
never my strongest attribute.

Have tried stepping though (just get lost in nested calls etc), Adding
system.out debug (does what I expect, but child windws also jumps around) ,
have gone back to basic MDI/child with javax timer but still cannot past
this problem. Its going to be something simple but at this point time what?
while I continue to read up on timers / swing thread safety etc can someone
look at a cut down version of my app that I knocked up in eclipse VE and
give some more comments. dont know if it matters but Im runnin JDK 1.5 ,
eclipse 3.1 on and XP machine (but get the same problems with jdl  1.4.2 ,
eclipse 3.0 on NT4)

cheers

code made up from 2 files MDI.java and ChildWindow.java

MDI.java

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.BorderLayout;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.swing.JPanel;
import javax.swing.JMenuItem;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

public class MDI extends JFrame implements ActionListener{

static final int ONE_SECOND=1000;
private JPanel jContentPane = null;
private JMenuBar jJMenuBar = null;
private JMenu fileMenu = null;
private JMenu launchMenu = null;
private JMenuItem exitMenuItem = null;
private JMenuItem childjMenuItem = null;
private JLabel lblTime = null;
private Timer statusTimer;

private JMenuItem getChildjMenuItem() {
 if (childjMenuItem == null) {
  childjMenuItem = new JMenuItem();
  childjMenuItem.setText("launch Child");
  childjMenuItem.addActionListener(new java.awt.event.ActionListener() {
   public void actionPerformed(java.awt.event.ActionEvent e) {

    System.out.println("ActionEvent " + e);

    ChildWindow myChild=new ChildWindow();

    getContentPane().add(myChild);
   }
  });
 }
 return childjMenuItem;
}

public static void main(String[] args) {
       javax.swing.SwingUtilities.invokeLater(new Runnable() {
           public void run() {
             System.out.println("Running my MDI");
               createAndShowGUI();
           }
       });
}

   private static void createAndShowGUI() {
    MDI myMDI = new MDI();
    myMDI.setVisible(true);
   }

public MDI() {
 super();
 initialize();
}

private void initialize() {
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 this.setJMenuBar(getJJMenuBar());
 this.setSize(400, 200);
 this.setContentPane(getJContentPane());
 this.setTitle("Application");

 statusTimer=new Timer(ONE_SECOND * 3, this);
 statusTimer.start();
}

private JPanel getJContentPane() {
 if (jContentPane == null) {
  lblTime = new JLabel();
  lblTime.setText("Time");
  jContentPane = new JPanel();
  jContentPane.setLayout(new BorderLayout());
  jContentPane.add(lblTime, java.awt.BorderLayout.SOUTH);
 }
 return jContentPane;
}

private JMenuBar getJJMenuBar() {
 if (jJMenuBar == null) {
  jJMenuBar = new JMenuBar();
  jJMenuBar.add(getFileMenu());
  jJMenuBar.add(getEditMenu());
 }
 return jJMenuBar;
}

private JMenu getFileMenu() {
 if (fileMenu == null) {
  fileMenu = new JMenu();
  fileMenu.setText("File");
  fileMenu.add(getExitMenuItem());
 }
 return fileMenu;
}

private JMenu getEditMenu() {
 if (launchMenu == null) {
  launchMenu = new JMenu();
  launchMenu.setText("Launch");
  launchMenu.add(getChildjMenuItem());
 }
 return launchMenu;
}

private JMenuItem getExitMenuItem() {
 if (exitMenuItem == null) {
  exitMenuItem = new JMenuItem();
  exitMenuItem.setText("Exit");
  exitMenuItem.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
    System.exit(0);
   }
  });
 }
 return exitMenuItem;
}

public void actionPerformed (ActionEvent e) {
 System.out.println("actionPerformed for my clock:" + e);
     Date currentDate = new Date();
    final SimpleDateFormat formatter = new SimpleDateFormat ("EEE MMM dd
hh:mm:ss yyyy", Locale.getDefault());
     formatter.applyPattern("HH:mm:ss");
       String now = formatter.format(currentDate);
       lblTime.setText(now);
   }
}

Childwindow.java

import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JInternalFrame;
import javax.swing.JButton;

public class ChildWindow extends JInternalFrame {

private JPanel jContentPane = null;
private JButton btnClose = null;

public ChildWindow() {
 super();
 initialize();
}

private void initialize() {
 this.setSize(300, 100);
 this.setResizable(true);
 this.setMaximizable(true);
 this.setTitle("Drag me around");
 this.setVisible(true);
 this.setContentPane(getJContentPane());
}

private JPanel getJContentPane() {
 if (jContentPane == null) {
  jContentPane = new JPanel();
  jContentPane.setLayout(new BorderLayout());
  jContentPane.add(getBtnClose(), java.awt.BorderLayout.CENTER);
 }
 return jContentPane;
}

private JButton getBtnClose() {
 if (btnClose == null) {
  btnClose = new JButton();
  btnClose.setText("Close Me");
  btnClose.addActionListener(new java.awt.event.ActionListener() {
   public void actionPerformed(java.awt.event.ActionEvent e) {
    dispose();
   }
  });
 }
 return btnClose;
}
}

==============================================================

>> Hi Im new to Swing (and a lot  other Java things to be honest)....
>
[quoted text clipped - 52 lines]
>
> 'Getting in the way'?  Why?  How wide did you make it?  [ ;-) ]
Filip Larsen - 13 Aug 2005 22:34 GMT
> Still cannot see whats going on , trying to debug timer related problems was
> never my strongest attribute.

I haven't tried to compile or run your code, but it looks like you add
the JInternalFrame instances to the content pane of the top JFrame,
which in your case is a JPanel and not a JDesktopPane. You probably want
to add a JDesktopPane as the center component on the panel, and then add
the JInternalFrame instances to that JDesktopPane instead.

After your initial post I got curious and made a small test example, but
I could not reproduce the problem you say you have (neither using
javax.swing.Timer or java.util.Timer calling from outside the EDT which
I at the time thought may cause the effect you observe). If your problem
persists perhaps you can use the example code below as a starting point
to figure out where you go wrong.

===== TimerDragTest.java =====
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TimerDragTest extends JFrame implements Runnable {

public static void main(String[] args) {
 SwingUtilities.invokeLater(new TimerDragTest());
}

private int windows = 0;

public TimerDragTest() {
 setTitle("Timer Drag Test");
 setDefaultCloseOperation(EXIT_ON_CLOSE);
 Container content = getContentPane();
 final JDesktopPane dt = new JDesktopPane();
 content.add(dt,BorderLayout.CENTER);
 JPanel sb = new JPanel();
 content.add(sb,BorderLayout.SOUTH);
 JMenuBar mb = new JMenuBar();
 content.add(mb,BorderLayout.NORTH);

 JMenu fileMenu = new JMenu("File");
 mb.add(fileMenu);

 JMenuItem newWindowItem = new JMenuItem("New Window");
 fileMenu.add(newWindowItem);
 newWindowItem.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
   JInternalFrame frame = new JInternalFrame("Window " +
(++windows),true,true,true,true);
   frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
   frame.getContentPane().add(new JLabel(new Date().toString()));
   frame.pack();
   dt.add(frame);
   frame.setVisible(true);
  }
 });

 final JLabel date = new JLabel();
 sb.add(date);
 final Format dateFormat = new SimpleDateFormat("EEE MMM dd hh:mm:ss
yyyy");

 new javax.swing.Timer(1000,new ActionListener() {
  public void actionPerformed(ActionEvent e) {
   date.setText(dateFormat.format(new Date()));
  }
 }).start();

//  java.util.Timer tt = new java.util.Timer();
//  tt.schedule(new TimerTask() {
//   public void run() {
//    date.setText(dateFormat.format(new Date()));
//   }
//  }, 0, 1000);

}

public void run() {
 setSize(300,300);
 setVisible(true);
}
}

=====

Regards,

Signature

Filip Larsen

Babu Kalakrishnan - 14 Aug 2005 06:19 GMT
> Still cannot see whats going on , trying to debug timer related problems was
> never my strongest attribute.

As Filip pointed out, your problem lies in the fact that you've added
the JInternalFrame to a plain JPanel instead of a JDesktopPane which is
the recommended practice. The JDesktopPane knows how to handle multiple
child internal frames that can be positioned arbitrarily in it, but a
JPanel doesn't.

Since you use a BorderLayout as the LayoutManager of the panel and add
the JInternalFrame without specifying a constraint, it ends up becoming
the CENTER component of that Layout. So everytime the panel does a
layout, it expands the child component to its own width (and height
equal to its own height minus that of the label placed as its SOUTH
component).

You see the "jumping" only when the timer fires because the timer
changes the text on the label causing a revalidation to occur. The
LayoutManager kicks in then, and forces the child frame to become a
proper "CENTER" component regardless of where you'd dragged it to.

Using a JDesktopPane whould solve your problem. Check out :

http://java.sun.com/docs/books/tutorial/uiswing/components/internalframe.html

BK
Ed - 24 Aug 2005 21:26 GMT
Thanks in advance to Filip and Babu

Havent tried what you said yet as Ive only just returned from Holiday
(Turkey - can recommend) but will do so in the next few days. Sounds like I
ned to be careful of GUI editors like the VE one in eclipse as the Im sure
it was VE that autogenerated the JPanel rather than a JDesktopPane. Oh well
will see whats what this weekend.

Thanks again
Ed

>> Still cannot see whats going on , trying to debug timer related problems
>> was never my strongest attribute.
[quoted text clipped - 21 lines]
>
> BK
Ed - 27 Aug 2005 00:12 GMT
Got it , instead of putting a JDesktopPane in the centre of the default
contentPane (getContentPane) I was creating my own pane and setting it using
setContentPane() and also giving it a Border Layout. still sounds  like it
should have worked (to me anyway) but the combination seems to mess things
up.

Thanks to Filip for the sample code which helped a lot, now off for some
sleep before I re-read up on internal panes etc to understand things better
for the next times.

thanks again
Ed

> Thanks in advance to Filip and Babu
>
[quoted text clipped - 32 lines]
>>
>> BK
Thomas Hawtin - 27 Jul 2005 01:00 GMT
> which appears to open the window as expected. However whenever I grab the
> window by its title bar and drag it around the MDI space (using left mouse
[quoted text clipped - 6 lines]
> Ive coded on which I have a timer updating the clock on the the bottom right
> of the status bar.

Without debugging anything I would guess that you update (which should
be done on the AWT Event Dispatch Thread, btw) is causing an invalidate.
That is causing, probably, the DesktopManager to put the internal frame
back to the original position. When the cursor moves again
BasicInternalFrameUI.BorderListener continues to drag.

Get your debugger out and have a look.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.