Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Triggering of two event handlers problem

Status
Not open for further replies.

TheObserver

Programmer
Mar 26, 2002
91
US
I'm doing development in Forte/Studio One, and I keep hitting this problem...I keep trying to work around it, but it's getting harder to do so due to the subsequent methods I need to have called.

Basically, I have an application with a JDesktopPane and several JInternalFrames within it. I need to detect both when the JInternalFrames are moved, and when they are removed (closed) from the JDesktopPane. However, if an event of "moved" (componentMoved, if I remember correctly) occurs, the "removed" (componentRemoved) event is also triggered, and vice versa. I can't trigger one without triggering the other. Filtering one from the other can be done in some use cases, but in others there's no way to avoid it, codewise.

As I mentioned, I'm using Suns' Studio One for dev work, and as such, when an event is added to the code, the listeners are also automatically added. I've given the listeners a glance and they appear okay, but haven't felt the need, as of yet, to look much deeper than I have.

What could be causing this double-triggering problem, and how can it be solved?
 
Your internal frame can implement InternalFrameListener and ComponentListener
try my code
Code:
import javax.swing.JInternalFrame;
import javax.swing.JDesktopPane;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JMenuBar;
import javax.swing.JFrame;

import java.awt.event.*;
import java.awt.*;

public class ifr extends JFrame {
    JDesktopPane desktop;
    int taskNo=1;

    public ifr() {
        super("InternalFrameDemo");

        //Make the big window be indented 50 pixels from each edge 
        //of the screen.
        int inset = 50;
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds(inset, inset, 
                  screenSize.width - inset*2, 
                  screenSize.height-inset*2);

        //Quit this app when the big window closes.
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        //Set up the GUI.
        desktop = new JDesktopPane(); //a specialized layered pane
        createFrame(1); //Create first window
        setContentPane(desktop);
        setJMenuBar(createMenuBar());

        //Make dragging faster:
        desktop.putClientProperty("JDesktopPane.dragMode", "outline");
    }

    protected JMenuBar createMenuBar() {
        JMenuBar menuBar = new JMenuBar();

        JMenu menu = new JMenu("Document");
        menu.setMnemonic(KeyEvent.VK_D);
        JMenuItem menuItem = new JMenuItem("New");
        menuItem.setMnemonic(KeyEvent.VK_N);
        menuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                taskNo++;
                createFrame(taskNo);
            }
        });
        menu.add(menuItem);
        menuBar.add(menu);

        return menuBar;
    }

    protected void createFrame(int myChoice) {

    if (myChoice==1)
       {
               task1 frame2 = new task1();
	       frame2.setVisible(true); //necessary as of kestrel
               desktop.add(frame2);
               try {
                    frame2.setSelected(true);
                   }
               catch (java.beans.PropertyVetoException e) {}
       }  
    else
       {
               task1 frame2 = new task1();
	       frame2.setVisible(true); //necessary as of kestrel
               desktop.add(frame2);
               try {
                    frame2.setSelected(true);
                   }
               catch (java.beans.PropertyVetoException e) {}
       }  
    }

    public static void main(String[] args) {
        ifr frame = new ifr();
        frame.setVisible(true);
    }
}
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

class task1 extends JInternalFrame implements InternalFrameListener, ComponentListener {
    static int openFrameCount = 0;
    static final int xOffset = 30, yOffset = 30;
        JTextField myJText;
        JTextField myJText2;
        JTextField myJText3;

    public task1() {
        super("Document #" + (++openFrameCount), 
              true, //resizable
              true, //closable
              true, //maximizable
              true);//iconifiable
        addInternalFrameListener(this);
        addComponentListener(this);
        getContentPane().setLayout(new GridLayout(3,2));
        myJText = new JTextField("25.0");
        myJText2 = new JTextField("12.0");
        myJText3 = new JTextField("0.0");

        JLabel myJLab = new JLabel("+");
        JLabel myJLab2 = new JLabel("=");
        JButton processBtn = new JButton("process");
        ActionListener myListener = new ActionListener()
                                    {
                                     public void actionPerformed(ActionEvent e) 
                                            {
                                             myJText3.setText(String.valueOf( Double.parseDouble(myJText.getText())+Double.parseDouble(myJText2.getText()) ));
                                            }

                                    };
        processBtn.addActionListener(myListener);
    
        getContentPane().add(myJText);
        getContentPane().add(myJLab);
        getContentPane().add(myJText2);
        getContentPane().add(myJLab2);
        getContentPane().add(myJText3);
        getContentPane().add(processBtn);
        //...Create the GUI and put it in the window...

        //...Then set the window size or call pack...
        setSize(300,300);

        //Set the window's location.
        setLocation(xOffset*openFrameCount, yOffset*openFrameCount);
    }

    public void internalFrameClosing(InternalFrameEvent e) {
	System.out.println("Internal frame closing");
    }

    public void internalFrameClosed(InternalFrameEvent e) {
	System.out.println("Internal frame closed");
    }

    public void internalFrameOpened(InternalFrameEvent e) {
	System.out.println("Internal frame opened");
    }

    public void internalFrameIconified(InternalFrameEvent e) {
	System.out.println("Internal frame iconified");
    }

    public void internalFrameDeiconified(InternalFrameEvent e) {
	System.out.println("Internal frame deiconified");
    }

    public void internalFrameActivated(InternalFrameEvent e) {
	System.out.println("Internal frame activated");
    }

    public void internalFrameDeactivated(InternalFrameEvent e) {
	System.out.println("Internal frame deactivated");
    }

 public void componentHidden(ComponentEvent e) 
        {System.out.println("Mya");} 
 public void componentMoved(ComponentEvent e) 
        {System.out.println("MyInternal frame is moved");} 
 public void componentResized(ComponentEvent e) 
        {System.out.println("Myinternal frame is created, resized or closed");}
 public void componentShown(ComponentEvent e) 
        {System.out.println("Myd");}

}
 
consider method public void internalFrameClosing(InternalFrameEvent e)
and
public void componentMoved(ComponentEvent e)
 
I may not be able to go the route you're suggesting without almost as much overhead as the one I'm currently pursuing. I don't know for sure.

Right now, I have methods in the class (let's call it X) which creates the JDesktopPane that need to be called when one of the JInternalFrame classes (let's call it Y) that X creates is moved, closed, etc. I really can't embed the methods related to Y, currently in X, into Y because Y is more of a generic class - meaning it will be used by several apps. So customizing it for functionality within class X is a very last resort option.

As such, the need to figure out why both the ComponentMoved and ComponentRemoved are firing at the same time in X when an instance of Y is interacted with is a preferred way of dealing with this. I have two distinct methods in X which need to be called based on which of those two events (Moved or Removed) is called. I've tried filtering on the event type, setting up boolean variables to try and keep the wrong method from being called, etc, but nothing seems to work.

Alternately, if this approach isn't feasible, your approach of using events in Y would probably need to be implemented. However, I would need some way to call the methods in X from Y when the events are triggered. As such, I haven't figured out a way to do this...it seems like an easy thing to do, since X instantiates Y, but I haven't gotten anything to work yet.
 
if you does not remove(JInternalFrame) and the frame becomes invisible, unselected, or closed, you can access the value of isClosed of JInternalFrame.
If isClosed is false, and the event should be ComponentMoved and not ComponentRemoved .

If you can add this method in your JInternalFrame, you get get the value of isClosed by myJInternalFrame.checkClose()

public boolean checkClose()
{
return isClosed;
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top