-1

I need to close all the children and parent windows when I close one window in the hierarchy.

I have three lines of windows:

My windows hierarchy - All lines start in one MainWindow. Only LoadPlayers and CreatePlayers are dialogs. All other windows are frames.

E.g. I close TablesOverview in the first line - I need to close all other windows in this line.

But windows in other lines must stay open.

Notice that TablesOverview is in two lines.

I can write the code, where I named every window that must close. But I need cleaner solution.

This code give me all opened windows - I don't know how to take only windows in one line.

Window[] windows = Window.getWindows();

This codes give me nothing.

Window[] windows = frame.getOwnedWindows();
Component comp = frame.getParent();
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Cato
  • 1
  • 1
  • Possible duplicate of [Close all Java child windows](https://stackoverflow.com/questions/29859469/close-all-java-child-windows) – Ebrahim Poursadeqi Jul 05 '17 at 07:06
  • Welcome to Stack Overflow! Please [take the tour](http://stackoverflow.com/tour) to see how the site works and what questions are on topic here, and edit your question accordingly. See also: [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) – Joe C Jul 05 '17 at 07:07
  • Even from the description, this GUI seems to be a mess. See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) The use of two dialogs might be one step in the right direction, but there are many strategies to redesigning (to remove extra frames) which can be combined. See my answer to that question for a brief overview of the alternatives. – Andrew Thompson Jul 05 '17 at 09:10

1 Answers1

-1

Java don't provides this support implicitly. So, you have to use some work around:

Solution:

  • Create a new class which extends JFrame
  • Create a data member children of type ArrayList<Your class name>. This holds the instance created by current window
  • Create an member method createChildWindow(). This method will create a child window and add it in to variable children
  • Register for event on closing the window. For this use addWindowListener() and override public void windowClosing(java.awt.event.WindowEvent windowEvent) method. In this method traverse throw the children collection and close each child(This will eventually close its subsequent children also).

Following is the complete working code

WindowTracker.java

package com.cse.test.awt;

import java.awt.FlowLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class WindowTracker extends JFrame
{
    ArrayList<WindowTracker> children;
    JLabel childrenCount;

    public WindowTracker()
    {
        children = new ArrayList<>();
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent arg0) {
                System.out.println("Closing..." + this.hashCode());
                for(WindowTracker child:children)
                {
                    child.dispatchEvent(new WindowEvent(child, WindowEvent.WINDOW_CLOSING));
                }
                System.out.println("Closed..." + this.hashCode());
            }
        });

        this.setLayout(new FlowLayout(FlowLayout.RIGHT));
        childrenCount = new JLabel("Children count: 0");
        this.add(childrenCount);
        JButton btn = new JButton("Create new child");
        btn.addActionListener(e -> {WindowTracker child = getNewChild();});
        this.add(btn);

        this.setSize(300, 300);
        this.setTitle("" + this.hashCode());
        this.setVisible(true);
    }

    public WindowTracker getNewChild()
    {
        WindowTracker child = new WindowTracker();
        children.add(child);
        childrenCount.setText("Children count: " + children.size());
        return child;
    }
}

Executer.java

package com.cse.test.common;

import com.cse.test.awt.WindowTracker;

public class Executer {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new WindowTracker();

    }

}
cse
  • 4,066
  • 2
  • 20
  • 37
  • You don't need the new class, or the `ArrayList` data member, or the extra method. You only need `JFrame.getContentPane().getComponents()`. – user207421 Jul 05 '17 at 08:21
  • @EJP It will not return child windows. It will return `component` held by container. See here: [getComponents()](https://docs.oracle.com/javase/7/docs/api/java/awt/Container.html#getComponents()) and [getContentPane()](https://docs.oracle.com/javase/7/docs/api/javax/swing/JFrame.html#getContentPane()). So keep track of child windows, we need `ArrayList`. – cse Jul 05 '17 at 08:52