All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.webswing.toolkit.extra.WindowHierarchyTree Maven / Gradle / Ivy
package org.webswing.toolkit.extra;
import java.awt.Dialog;
import java.awt.Dialog.ModalExclusionType;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.util.*;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import org.webswing.toolkit.WebToolkit;
import org.webswing.toolkit.WebWindowPeer;
import org.webswing.toolkit.util.Logger;
import org.webswing.toolkit.util.Util;
public class WindowHierarchyTree {
private Map lookup = new HashMap();
private LinkedList rootWindowNodes = new LinkedList();
private LinkedList alwaysOnTopZOrder = new LinkedList();
private LinkedList regularZOrder = new LinkedList();
private LinkedList zOrder = new LinkedList();
private ArrayDeque modalsStack = new ArrayDeque<>();
protected void bringToFront(Window w) {
if (w != null && !w.isEnabled()) {
return;
}
if (lookup.containsKey(w)) {
WindowHierarchyNode node = lookup.get(w);
if (node.getParent() == null) {
if (rootWindowNodes.indexOf(node) != 0) {
rootWindowNodes.remove(node);
rootWindowNodes.addFirst(node);
}
rebuildZOrder(true);
} else {
LinkedList parentChildren = node.getParent().getChildren();
if (parentChildren.indexOf(node) != 0) {
parentChildren.remove(node);
parentChildren.addFirst(node);
}
bringToFront(node.getParent().getW());
}
} else {
Logger.error("Window not registered. Not able to bring to front.", w);
}
}
protected void addWindow(Window window) {
if (!lookup.containsKey(window)) {
WindowHierarchyNode parentNode = lookup.get(window.getParent());
if((window instanceof Dialog) && ((Dialog) window).isModal()){
modalsStack.push(window);
}
if (window.getParent() == null || parentNode == null) {
//window without parent
WindowHierarchyNode thisNode = new WindowHierarchyNode(window);
lookup.put(window, thisNode);
rootWindowNodes.add(thisNode);
rebuildZOrder(false);
} else {
//window with parent
WindowHierarchyNode thisNode = new WindowHierarchyNode(window, parentNode);
lookup.put(window, thisNode);
parentNode.addChild(thisNode);
rebuildZOrder(false);
}
window.repaint();
} else {
Logger.error("Window already registered in hierarchy tree", window);
}
}
protected void removeWindow(Window window) {
if (lookup.containsKey(window)) {
WindowHierarchyNode node = lookup.get(window);
int index = zOrder.indexOf(node);
modalsStack.remove(window);
Window successor = findSuccessor(window);
lookup.remove(window);
WindowHierarchyNode parent = node.getParent();
LinkedList children = node.getChildren();
if (parent != null) {
parent.getChildren().remove(node);
for (WindowHierarchyNode child : children) {
child.setParent(parent);
}
parent.getChildren().addAll(children);
} else {
rootWindowNodes.remove(node);
rootWindowNodes.addAll(children);
for (WindowHierarchyNode child : children) {
child.setParent(null);
}
}
rebuildZOrder(false);
requestRepaintUnderlying(index, window.getBounds());
if (successor != null && Util.getWebToolkit().getWindowManager().isWindowActive(window)) {
WindowManager.getInstance().activateWindow(successor);
}
} else {
Logger.debug("Window not registered. Could not remove.", window);
}
}
private Window findSuccessor(Window window) {
WindowHierarchyNode node = lookup.get(window);
if (modalsStack.size()>0){
Window modalWindow = modalsStack.peek();
if(modalWindow instanceof Dialog && !((Dialog) modalWindow).getModalityType().equals(ModalityType.DOCUMENT_MODAL)) {
return modalWindow;
}
}
if (node.getParent() != null) {
return node.getParent().getW();
} else {
int index = rootWindowNodes.indexOf(node);
if (rootWindowNodes.size() > index + 1) {
return rootWindowNodes.get(index + 1).getW();
}
}
return null;
}
private void rebuildZOrder(boolean repaintChildren) {
WindowHierarchyNode lastWindowAlwaysOnTop = alwaysOnTopZOrder.size() > 0 ? alwaysOnTopZOrder.get(0) : null;
WindowHierarchyNode lastWindowRegular = regularZOrder.size() > 0 ? regularZOrder.get(0) : null;
alwaysOnTopZOrder.clear();
regularZOrder.clear();
zOrder.clear();
for (WindowHierarchyNode window : rootWindowNodes) {
buildAlwaysOnTopZOrderList(alwaysOnTopZOrder, false, window);
}
for (WindowHierarchyNode window : rootWindowNodes) {
buildRegularZOrderList(regularZOrder, window);
}
zOrder.addAll(alwaysOnTopZOrder);
zOrder.addAll(regularZOrder);
if (repaintChildren) {
repaintChildren(lastWindowAlwaysOnTop, alwaysOnTopZOrder);
repaintChildren(lastWindowRegular, regularZOrder);
}
}
private void repaintChildren(WindowHierarchyNode lastWindow, LinkedList zOrder) {
if (lastWindow != null) {
for (WindowHierarchyNode node : zOrder) {
if (node == lastWindow) {
break;
} else {
Util.getWebToolkit().getPaintDispatcher().notifyWindowZOrderChanged(node.getW());
}
}
}
}
private void buildAlwaysOnTopZOrderList(List resultList, boolean inheritedAlwaysOnTop, WindowHierarchyNode currentNode) {
for (WindowHierarchyNode window : currentNode.getChildren()) {
buildAlwaysOnTopZOrderList(resultList, inheritedAlwaysOnTop, window);
}
if (currentNode.getW().isAlwaysOnTop() || inheritedAlwaysOnTop) {
resultList.add(currentNode);
inheritedAlwaysOnTop = true;
}
}
private void buildRegularZOrderList(List resultList, WindowHierarchyNode currentNode) {
if (!currentNode.getW().isAlwaysOnTop()) {
for (WindowHierarchyNode window : currentNode.getChildren()) {
buildRegularZOrderList(resultList, window);
}
resultList.add(currentNode);
}
}
protected boolean contains(Window w) {
return lookup.containsKey(w);
}
private class WindowHierarchyNode {
private Window w;
private WindowHierarchyNode parent;
private LinkedList children = new LinkedList();
public WindowHierarchyNode(Window w) {
this.w = w;
}
public WindowHierarchyNode(Window w, WindowHierarchyNode parent) {
this.w = w;
this.parent = parent;
}
public Window getW() {
return w;
}
public void addChild(WindowHierarchyNode child) {
children.add(child);
}
public WindowHierarchyNode getParent() {
return parent;
}
public void setParent(WindowHierarchyNode parent) {
this.parent = parent;
}
public LinkedList getChildren() {
return children;
}
public String toString() {
return w.toString();
}
}
@SuppressWarnings("unchecked")
protected Window getVisibleWindowOnPosition(int x, int y) {
List clonedZOrder = (List) zOrder.clone();//to avoid concurrent modification exception
for (WindowHierarchyNode w : clonedZOrder) {
if (w.getW().getBounds().contains(x,y)) {
return w.getW();
}
}
return null;
}
@SuppressWarnings("restriction")
protected Map> extractNonVisibleAreas() {
Map> result = new HashMap>();
if (zOrder.size() > 0) {
for (int i = 1; i < zOrder.size() + 1; i++) {
String id = i == zOrder.size() ? WebToolkit.BACKGROUND_WINDOW_ID : ((WebWindowPeer) WebToolkit.targetToPeer(zOrder.get(i).getW())).getGuid();
Rectangle current = i == zOrder.size() ? new Rectangle(Util.getWebToolkit().getScreenSize()) : zOrder.get(i).getW().getBounds();
List currentDifferences = new ArrayList();
for (int j = i - 1; j >= 0; j--) {
Rectangle previousBounds = zOrder.get(j).getW().getBounds();
Rectangle intersect = SwingUtilities.computeIntersection(current.x, current.y, current.width, current.height, (Rectangle) previousBounds.clone());
if (!intersect.isEmpty()) {
intersect.setLocation(intersect.x - current.x, intersect.y - current.y);
currentDifferences.add(intersect);
}
}
if (currentDifferences.size() != 0) {
result.put(id, currentDifferences);
}
}
}
return result;
}
public List getZOrder() {
List zorder = new ArrayList<>();
for (int i = 0; i < zOrder.size(); i++) {
String id = ((WebWindowPeer) WebToolkit.targetToPeer(zOrder.get(i).getW())).getGuid();
zorder.add(id);
}
return zorder;
}
public void requestRepaintAfterMove(Window w, Rectangle originalPosition) {
requestRepaintUnderlying(zOrder.indexOf(lookup.get(w)) + 1, originalPosition);
Rectangle newPosition = w.getBounds();
if (originalPosition.x != newPosition.x || originalPosition.y != newPosition.y) {
Util.getWebToolkit().getPaintDispatcher().notifyWindowMoved(w,zOrder.indexOf(lookup.get(w)), originalPosition, newPosition);
}
}
private void requestRepaintUnderlying(int index, Rectangle bounds) {
for (int i = index; i < zOrder.size(); i++) {
Window underlying = zOrder.get(i).getW();
Rectangle uBounds = underlying.getBounds();
Rectangle boundsCopy = new Rectangle(bounds);
SwingUtilities.computeIntersection(uBounds.x, uBounds.y, uBounds.width, uBounds.height, boundsCopy);
WebWindowPeer peer = (WebWindowPeer) WebToolkit.targetToPeer(underlying);
Util.getWebToolkit().getPaintDispatcher().notifyWindowAreaVisible(peer.getGuid(), new Rectangle(boundsCopy.x - uBounds.x, boundsCopy.y - uBounds.y, boundsCopy.width, boundsCopy.height));
}
Rectangle boundsCopy = new Rectangle(bounds);
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
SwingUtilities.computeIntersection(0, 0, screensize.width, screensize.height, boundsCopy);
Util.getWebToolkit().getPaintDispatcher().notifyBackgroundAreaVisible(boundsCopy);
}
protected boolean isInSameModalBranch(Window active, Window current) {
if (active == null) {
return true;
}
Window modalParentofActive = getModalParent(active);
Window modalParentofCurrent = getModalParent(current);
boolean isActiveParentOfCurrent = isParent(modalParentofActive, modalParentofCurrent);
if (modalParentofActive == null || modalParentofActive == modalParentofCurrent || (current == modalParentofCurrent && isActiveParentOfCurrent)) {
return true;
} else {
return false;
}
}
public boolean isParent(Window parent, Window child) {
if (parent != null && child != null) {
if (child.getParent() != null) {
return child.getParent() == parent || isParent(parent, (Window) child.getParent());
} else {
return false;
}
} else {
return false;
}
}
private Window getModalParent(Window w) {
WindowHierarchyNode window = lookup.get(w);
if (window != null) {
if ((window.getW() instanceof Dialog) && ((Dialog) window.getW()).isModal()) {
return window.getW();
} else if (window.getW().getParent() != null) {
return getModalParent((Window) window.getW().getParent());
} else {
return null;
}
} else {
return null;
}
}
public boolean isInModalBranch(Window w){
return getModalParent(w) != null;
}
public boolean isInFullModalBranch(Window w) {
WindowHierarchyNode window = lookup.get(w);
if (window != null) {
if ((window.getW() instanceof Dialog) && ((Dialog) window.getW()).isModal() && ((Dialog) window.getW()).getModalityType()!=ModalityType.DOCUMENT_MODAL) {
return true;
} else if (window.getW().getParent() != null) {
return isInFullModalBranch((Window) window.getW().getParent());
} else {
return false;
}
} else {
return false;
}
}
}