/* * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com), * modifications by Nikolaus Moll * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list * of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this * list of conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * Neither the name of the MiG InfoCom AB nor the names of its contributors may be * used to endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ package org.jowidgets.impl.layout.miglayout; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; /** */ final class LinkHandlerCommon { public static final int X = 0; public static final int Y = 1; public static final int WIDTH = 2; public static final int HEIGHT = 3; public static final int X2 = 4; public static final int Y2 = 5; private final ArrayList<WeakReference<Object>> layouts = new ArrayList<WeakReference<Object>>(4); private final ArrayList<HashMap<String, int[]>> valuesMap = new ArrayList<HashMap<String, int[]>>(4); private final ArrayList<HashMap<String, int[]>> valuesTemp = new ArrayList<HashMap<String, int[]>>(4); LinkHandlerCommon() {} public synchronized Integer getValue(final Object layout, final String key, final int type) { Integer ret = null; boolean cont = true; for (int i = layouts.size() - 1; i >= 0; i--) { final Object l = layouts.get(i).get(); if (ret == null && l == layout) { int[] rect = valuesTemp.get(i).get(key); if (cont && rect != null && rect[type] != LayoutUtilCommon.NOT_SET) { ret = rect[type]; } else { rect = valuesMap.get(i).get(key); ret = (rect != null && rect[type] != LayoutUtilCommon.NOT_SET) ? rect[type] : null; } cont = false; } if (l == null) { layouts.remove(i); valuesMap.remove(i); valuesTemp.remove(i); } } return ret; } /** * Sets a key that can be linked to from any component. * * @param layout The MigLayout instance * @param key The key to link to. This is the same as the ID in a component constraint. * @param x x * @param y y * @param width Width * @param height Height * @return If the value was changed */ public synchronized boolean setBounds( final Object layout, final String key, final int x, final int y, final int width, final int height) { return setBounds(layout, key, x, y, width, height, false, false); } synchronized boolean setBounds( final Object layout, final String key, final int x, final int y, final int width, final int height, final boolean temporary, final boolean incCur) { for (int i = layouts.size() - 1; i >= 0; i--) { final Object l = layouts.get(i).get(); if (l != layout) { continue; } final HashMap<String, int[]> map = (temporary ? valuesTemp : valuesMap).get(i); final int[] old = map.get(key); if (old == null || old[X] != x || old[Y] != y || old[WIDTH] != width || old[HEIGHT] != height) { if (old == null || incCur == false) { map.put(key, new int[] {x, y, width, height, x + width, y + height}); return true; } boolean changed = false; if (x != LayoutUtilCommon.NOT_SET) { if (old[X] == LayoutUtilCommon.NOT_SET || x < old[X]) { old[X] = x; old[WIDTH] = old[X2] - x; changed = true; } if (width != LayoutUtilCommon.NOT_SET) { final int x2 = x + width; if (old[X2] == LayoutUtilCommon.NOT_SET || x2 > old[X2]) { old[X2] = x2; old[WIDTH] = x2 - old[X]; changed = true; } } } if (y != LayoutUtilCommon.NOT_SET) { if (old[Y] == LayoutUtilCommon.NOT_SET || y < old[Y]) { old[Y] = y; old[HEIGHT] = old[Y2] - y; changed = true; } if (height != LayoutUtilCommon.NOT_SET) { final int y2 = y + height; if (old[Y2] == LayoutUtilCommon.NOT_SET || y2 > old[Y2]) { old[Y2] = y2; old[HEIGHT] = y2 - old[Y]; changed = true; } } } return changed; } return false; } layouts.add(new WeakReference<Object>(layout)); final int[] bounds = new int[] {x, y, width, height, x + width, y + height}; HashMap<String, int[]> values = new HashMap<String, int[]>(4); if (temporary) { values.put(key, bounds); } valuesTemp.add(values); values = new HashMap<String, int[]>(4); if (temporary == false) { values.put(key, bounds); } valuesMap.add(values); return true; } /** * This method clear any weak references right away instead of waiting for the GC. This might be advantageous * if lots of layout are created and disposed of quickly to keep memory consumption down. * * @since 3.7.4 */ public synchronized void clearWeakReferencesNow() { layouts.clear(); } public synchronized boolean clearBounds(final Object layout, final String key) { for (int i = layouts.size() - 1; i >= 0; i--) { final Object l = layouts.get(i).get(); if (l == layout) { return valuesMap.get(i).remove(key) != null; } } return false; } synchronized void clearTemporaryBounds(final Object layout) { for (int i = layouts.size() - 1; i >= 0; i--) { final Object l = layouts.get(i).get(); if (l == layout) { valuesTemp.get(i).clear(); return; } } } }