/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Array.java * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */ package com.sun.electric.tool.user.dialogs; import com.sun.electric.Main; import com.sun.electric.database.change.DatabaseChangeEvent; import com.sun.electric.database.change.DatabaseChangeListener; import com.sun.electric.database.geometry.Dimension2D; import com.sun.electric.database.geometry.Orientation; import com.sun.electric.database.hierarchy.Cell; import com.sun.electric.database.hierarchy.Export; import com.sun.electric.database.text.Name; import com.sun.electric.database.text.Pref; import com.sun.electric.database.text.TextUtils; import com.sun.electric.database.topology.ArcInst; import com.sun.electric.database.topology.Geometric; import com.sun.electric.database.topology.NodeInst; import com.sun.electric.database.topology.PortInst; import com.sun.electric.database.variable.ElectricObject; import com.sun.electric.technology.Technology; import com.sun.electric.tool.Job; import com.sun.electric.tool.JobException; import com.sun.electric.tool.drc.DRC; import com.sun.electric.tool.drc.Quick; import com.sun.electric.tool.user.*; import com.sun.electric.tool.user.ui.EditWindow; import com.sun.electric.tool.user.ui.MeasureListener; import com.sun.electric.tool.user.ui.ToolBar; import com.sun.electric.tool.user.ui.WindowFrame; import java.awt.Cursor; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Collections; import java.util.EventListener; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.JOptionPane; /** * Class to handle the "Array" dialog. */ public class Array extends EModelessDialog implements HighlightListener, DatabaseChangeListener { /** Space by edge overlap. */ private static final int SPACING_EDGE = 1; /** Space by centerline distance. */ private static final int SPACING_CENTER = 2; /** Space by characteristic distance. */ private static final int SPACING_ESSENTIALBND = 3; /** Space by measured distance. */ private static final int SPACING_MEASURED = 4; private static Cursor drawArrayCursor = ToolBar.readCursor("CursorArray.gif", 8, 8); private static Pref.Group prefs = Pref.groupForPackage(Array.class); private static Pref prefLinearDiagonal = Pref.makeBooleanPref("Array_LinearDiagonal", prefs, false), prefAddNames = Pref.makeBooleanPref("Array_AddNames", prefs, false), prefDRCGood = Pref.makeBooleanPref("Array_DRCGood", prefs, false), prefTranspose = Pref.makeBooleanPref("Array_Transpose", prefs, false), prefXFlip = Pref.makeBooleanPref("Array_XFlip", prefs, false), prefYFlip = Pref.makeBooleanPref("Array_YFlip", prefs, false), prefXStagger = Pref.makeBooleanPref("Array_XStagger", prefs, false), prefYStagger = Pref.makeBooleanPref("Array_YStagger", prefs, false), prefXCenter = Pref.makeBooleanPref("Array_XCenter", prefs, false), prefYCenter = Pref.makeBooleanPref("Array_YCenter", prefs, false), prefSpacingType = Pref.makeIntPref("Array_SpacingType", prefs, SPACING_EDGE), prefXRepeat = Pref.makeIntPref("Array_XRepeat", prefs, 1), prefYRepeat = Pref.makeIntPref("Array_YRepeat", prefs, 1); private static Double lastEdgeOverlapX = null, lastEdgeOverlapY = null; private static Double lastCenterlineX = null, lastCenterlineY = null; /** amount when spacing by edge overlap */ private double spacingOverX, spacingOverY; /** amount when spacing by centerline distance */ private double spacingCenterlineX, spacingCenterlineY; /** amount when spacing by characteristic distance */ private double essentialBndX, essentialBndY; /** amount when spacing by measured distance */ private double spacingMeasuredX, spacingMeasuredY; /** the selected objects */ private Set<Geometric> selected; /** the selected objects including connecting nodes */ private Set<Geometric> selectedAll; /** the bounds of the selected objects */ private Rectangle2D bounds; /** the technology of the cell where arraying is done */private Technology tech; /** * Method to display a dialog for arraying the selected circuitry. */ public static void showArrayDialog() { // first make sure something is selected EditWindow wnd = EditWindow.needCurrent(); if (wnd == null) return; Highlighter highlighter = wnd.getHighlighter(); if (highlighter == null) { JOptionPane.showMessageDialog(Main.getCurrentJFrame(), "Cannot array: nothing is highlighted in this window."); return; } List highs = highlighter.getHighlightedEObjs(true, true); if (highs.size() == 0) { JOptionPane.showMessageDialog(Main.getCurrentJFrame(), "Select some objects before arraying them."); return; } Array dialog = new Array(Main.getCurrentJFrame()); dialog.setVisible(true); } /** Creates new form Array */ private Array(Frame parent) { super(parent, false); initComponents(); getRootPane().setDefaultButton(ok); UserInterfaceMain.addDatabaseChangeListener(this); Highlighter.addHighlightListener(this); // make all text fields select-all when entered EDialog.makeTextFieldSelectAllOnTab(xRepeat); EDialog.makeTextFieldSelectAllOnTab(yRepeat); EDialog.makeTextFieldSelectAllOnTab(xSpacing); EDialog.makeTextFieldSelectAllOnTab(ySpacing); // load the repeat factors xRepeat.setText(Integer.toString(prefXRepeat.getInt())); flipAlternateColumns.setSelected(prefXFlip.getBoolean()); staggerAlternateColumns.setSelected(prefXStagger.getBoolean()); centerXAboutOriginal.setSelected(prefXCenter.getBoolean()); yRepeat.setText(Integer.toString(prefYRepeat.getInt())); flipAlternateRows.setSelected(prefYFlip.getBoolean()); staggerAlternateRows.setSelected(prefYStagger.getBoolean()); centerYAboutOriginal.setSelected(prefYCenter.getBoolean()); // load the other factors linearDiagonalArray.setSelected(prefLinearDiagonal.getBoolean()); generateArrayIndices.setSelected(prefAddNames.getBoolean()); onlyDRCCorrect.setSelected(prefDRCGood.getBoolean()); transposePlacement.setSelected(prefTranspose.getBoolean()); spaceByEdgeOverlap.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { newSpacingSelected(); } }); spaceByCenterlineDistance.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { newSpacingSelected(); } }); spaceByEssentialBnd.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { newSpacingSelected(); } }); spaceByMeasuredDistance.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { newSpacingSelected(); } }); updateDialogForSelection(); finishInitialization(); pack(); } protected void escapePressed() { cancel(null); } /** * Reloads the dialog when Highlights change */ public void highlightChanged(Highlighter which) { if (!isVisible()) return; updateDialogForSelection(); } /** * Called when by a Highlighter when it loses focus. The argument * is the Highlighter that has gained focus (may be null). * @param highlighterGainedFocus the highlighter for the current window (may be null). */ public void highlighterLostFocus(Highlighter highlighterGainedFocus) { if (!isVisible()) return; updateDialogForSelection(); } /** * Respond to database changes * @param e database change event */ public void databaseChanged(DatabaseChangeEvent e) { if (!isVisible()) return; updateDialogForSelection(); } private void updateDialogForSelection() { // do not update if drawing the array interactively EventListener oldListener = WindowFrame.getListener(); if (oldListener != null && oldListener instanceof DrawArrayListener) return; // see what is highlighted EditWindow wnd = EditWindow.getCurrent(); if (wnd == null || wnd.getCell() == null) return; // invalid window or cell tech = wnd.getCell().getTechnology(); List<Geometric> highs = wnd.getHighlighter().getHighlightedEObjs(true, true); // if a single cell instance is selected, enable DRC-guided placement onlyDRCCorrect.setEnabled(false); if (highs.size() == 1) { ElectricObject eObj = highs.get(0); if (eObj instanceof NodeInst) onlyDRCCorrect.setEnabled(true); } // see if essential bounds are defined essentialBndX = essentialBndY = 0; boolean haveEB = false; for(Geometric eObj : highs) { if (!(eObj instanceof NodeInst)) continue; NodeInst ni = (NodeInst)eObj; if (!ni.isCellInstance()) continue; Cell subCell = (Cell)ni.getProto(); Rectangle2D spacing = subCell.findEssentialBounds(); if (spacing == null) continue; double thisDistX = spacing.getWidth(); double thisDistY = spacing.getHeight(); if (ni.getAngle() == 900 || ni.getAngle() == 2700) { double swap = thisDistX; thisDistX = thisDistY; thisDistY = swap; } if (haveEB) { if (essentialBndX != thisDistX || essentialBndY != thisDistY) { haveEB = false; break; } } essentialBndX = thisDistX; essentialBndY = thisDistY; haveEB = true; } spaceByEssentialBnd.setEnabled(haveEB); if (prefSpacingType.getInt() == SPACING_ESSENTIALBND && !haveEB) prefSpacingType.setInt(SPACING_EDGE); // see if there was a measured distance Dimension2D dim = MeasureListener.getLastMeasuredDistance(); if (dim.getWidth() > 0 || dim.getHeight() > 0) { spaceByMeasuredDistance.setEnabled(true); spacingMeasuredX = dim.getWidth(); spacingMeasuredY = dim.getHeight(); } else { spaceByMeasuredDistance.setEnabled(false); if (prefSpacingType.getInt() == SPACING_MEASURED) prefSpacingType.setInt(SPACING_EDGE); } // mark the list of nodes and arcs in the cell that will be arrayed selected = new HashSet<Geometric>(); selectedAll = new HashSet<Geometric>(); for(Geometric eObj : highs) { selected.add(eObj); selectedAll.add(eObj); if (eObj instanceof ArcInst) { ArcInst ai = (ArcInst)eObj; NodeInst niHead = ai.getHeadPortInst().getNodeInst(); selectedAll.add(niHead); NodeInst niTail = ai.getTailPortInst().getNodeInst(); selectedAll.add(niTail); } } // determine size of arrayed objects boolean first = true; bounds = new Rectangle2D.Double(); for(Geometric geom : selected) { if (first) { bounds.setRect(geom.getBounds()); first = false; } else { Rectangle2D.union(bounds, geom.getBounds(), bounds); } } spacingCenterlineX = bounds.getWidth(); spacingCenterlineY = bounds.getHeight(); if (lastCenterlineX != null && lastCenterlineY != null) { spacingCenterlineX = lastCenterlineX.doubleValue(); spacingCenterlineY = lastCenterlineY.doubleValue(); } // determine default edge overlap value spacingOverX = spacingOverY = 0; if (lastEdgeOverlapX != null && lastEdgeOverlapY != null) { spacingOverX = lastEdgeOverlapX.doubleValue(); spacingOverY = lastEdgeOverlapY.doubleValue(); } // load the spacing distances switch (prefSpacingType.getInt()) { case SPACING_EDGE: spaceByEdgeOverlap.setSelected(true); xSpacing.setText(TextUtils.formatDistance(spacingOverX, tech)); ySpacing.setText(TextUtils.formatDistance(spacingOverY, tech)); break; case SPACING_CENTER: spaceByCenterlineDistance.setSelected(true); xSpacing.setText(TextUtils.formatDistance(spacingCenterlineX, tech)); ySpacing.setText(TextUtils.formatDistance(spacingCenterlineY, tech)); break; case SPACING_ESSENTIALBND: spaceByEssentialBnd.setSelected(true); xSpacing.setText(TextUtils.formatDistance(essentialBndX, tech)); ySpacing.setText(TextUtils.formatDistance(essentialBndY, tech)); break; case SPACING_MEASURED: spaceByMeasuredDistance.setSelected(true); xSpacing.setText(TextUtils.formatDistance(spacingMeasuredX, tech)); ySpacing.setText(TextUtils.formatDistance(spacingMeasuredY, tech)); break; } if (prefSpacingType.getInt() == SPACING_EDGE) { xOverlapLabel.setText("X edge overlap:"); yOverlapLabel.setText("Y edge overlap:"); } else { xOverlapLabel.setText("X centerline distance:"); yOverlapLabel.setText("Y centerline distance:"); } } private void newSpacingSelected() { double x = TextUtils.atofDistance(xSpacing.getText(), tech); double y = TextUtils.atofDistance(ySpacing.getText(), tech); switch (prefSpacingType.getInt()) { case SPACING_EDGE: spacingOverX = x; spacingOverY = y; break; case SPACING_CENTER: spacingCenterlineX = x; spacingCenterlineY = y; break; case SPACING_ESSENTIALBND: essentialBndX = x; essentialBndY = y; break; case SPACING_MEASURED: spacingMeasuredX = x; spacingMeasuredY = y; break; } if (spaceByEdgeOverlap.isSelected()) prefSpacingType.setInt(SPACING_EDGE); else if (spaceByCenterlineDistance.isSelected()) prefSpacingType.setInt(SPACING_CENTER); else if (spaceByEssentialBnd.isSelected()) prefSpacingType.setInt(SPACING_ESSENTIALBND); else if (spaceByMeasuredDistance.isSelected()) prefSpacingType.setInt(SPACING_MEASURED); if (prefSpacingType.getInt() == SPACING_EDGE) { xOverlapLabel.setText("X edge overlap:"); yOverlapLabel.setText("Y edge overlap:"); } else { xOverlapLabel.setText("X centerline distance:"); yOverlapLabel.setText("Y centerline distance:"); } switch (prefSpacingType.getInt()) { case SPACING_EDGE: x = spacingOverX; y = spacingOverY; break; case SPACING_CENTER: x = spacingCenterlineX; y = spacingCenterlineY; break; case SPACING_ESSENTIALBND: x = essentialBndX; y = essentialBndY; break; case SPACING_MEASURED: x = spacingMeasuredX; y = spacingMeasuredY; break; } xSpacing.setText(TextUtils.formatDistance(x, tech)); ySpacing.setText(TextUtils.formatDistance(y, tech)); } private void rememberFields() { // gather all "last" values prefXRepeat.setInt((int)TextUtils.getValueOfExpression(xRepeat.getText())); prefXFlip.setBoolean(flipAlternateColumns.isSelected()); prefXStagger.setBoolean(staggerAlternateColumns.isSelected()); prefXCenter.setBoolean(centerXAboutOriginal.isSelected()); prefYRepeat.setInt((int)TextUtils.getValueOfExpression(yRepeat.getText())); prefYFlip.setBoolean(flipAlternateRows.isSelected()); prefYStagger.setBoolean(staggerAlternateRows.isSelected()); prefYCenter.setBoolean(centerYAboutOriginal.isSelected()); prefLinearDiagonal.setBoolean(linearDiagonalArray.isSelected()); prefAddNames.setBoolean(generateArrayIndices.isSelected()); prefDRCGood.setBoolean(onlyDRCCorrect.isSelected()); prefTranspose.setBoolean(transposePlacement.isSelected()); if (prefSpacingType.getInt() == SPACING_EDGE) { lastEdgeOverlapX = new Double(TextUtils.atofDistance(xSpacing.getText())); lastEdgeOverlapY = new Double(TextUtils.atofDistance(ySpacing.getText())); } else { lastCenterlineX = new Double(TextUtils.atofDistance(xSpacing.getText())); lastCenterlineY = new Double(TextUtils.atofDistance(ySpacing.getText())); } } private void makeArray() { // check for nonsense int xRepeat = Math.abs(prefXRepeat.getInt()); int yRepeat = Math.abs(prefYRepeat.getInt()); if (xRepeat <= 1 && yRepeat <= 1) { JOptionPane.showMessageDialog(Main.getCurrentJFrame(), "One dimension of the array must be greater than 1"); return; } if (prefLinearDiagonal.getBoolean() && xRepeat != 1 && yRepeat != 1) { JOptionPane.showMessageDialog(Main.getCurrentJFrame(), "Diagonal arrays need one dimension to be 1"); return; } // make lists of nodes and arcs that will be arrayed Set<NodeInst> nodeSet = new HashSet<NodeInst>(); List<ArcInst> arcList = new ArrayList<ArcInst>(); List<Export> exportList = new ArrayList<Export>(); Cell cell = null; for(Geometric geom : selected) { cell = geom.getParent(); if (geom instanceof NodeInst) { nodeSet.add((NodeInst)geom); if (User.isDupCopiesExports()) { NodeInst ni = (NodeInst)geom; for(Iterator<Export> eIt = ni.getExports(); eIt.hasNext(); ) exportList.add(eIt.next()); } } else { ArcInst ai = (ArcInst)geom; arcList.add(ai); nodeSet.add(ai.getHead().getPortInst().getNodeInst()); nodeSet.add(ai.getTail().getPortInst().getNodeInst()); } } List<NodeInst> nodeList = new ArrayList<NodeInst>(); for(NodeInst ni : nodeSet) nodeList.add(ni); Collections.sort(nodeList); Collections.sort(arcList); Collections.sort(exportList); // determine the distance between arrayed entries double xOverlap = TextUtils.atofDistance(xSpacing.getText()); double yOverlap = TextUtils.atofDistance(ySpacing.getText()); if (prefSpacingType.getInt() == SPACING_EDGE) { xOverlap = bounds.getWidth() - xOverlap; yOverlap = bounds.getHeight() - yOverlap; } double cX = bounds.getCenterX(); double cY = bounds.getCenterY(); // disallow arraying if lock is on for(NodeInst ni : nodeList) { if (CircuitChangeJobs.cantEdit(cell, ni, true, false, false) != 0) return; } // create the array new ArrayStuff(cell, nodeList, arcList, exportList, xRepeat, yRepeat, xOverlap, yOverlap, cX, cY, User.isArcsAutoIncremented()); } /** * Class to create an array in a new thread. */ private static class ArrayStuff extends Job { private List<NodeInst> nodeList; private List<ArcInst> arcList; private List<Export> exportList; private int xRepeat, yRepeat; private double xOverlap, yOverlap, cX, cY; private boolean arcsAutoIncrement, fromRight; private Cell cell; private DRC.DRCPreferences dp; private IconParameters iconParameters = IconParameters.makeInstance(true); protected ArrayStuff(Cell c, List<NodeInst> nodeList, List<ArcInst> arcList, List<Export> exportList, int xRepeat, int yRepeat, double xOverlap, double yOverlap, double cX, double cY, boolean arcsAutoIncrement) { super("Make Array", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER); this.cell = c; this.nodeList = nodeList; this.arcList = arcList; this.exportList = exportList; this.xRepeat = xRepeat; this.yRepeat = yRepeat; this.xOverlap = xOverlap; this.yOverlap = yOverlap; this.cX = cX; this.cY = cY; this.arcsAutoIncrement = arcsAutoIncrement; this.fromRight = User.isIncrementRightmostIndex(); this.dp = new DRC.DRCPreferences(false); startJob(); } public boolean doIt() throws JobException { assert(cell != null); // if only arraying where DRC clean, make an array of newly created nodes Geometric [] geomsToCheck = null; boolean [] validity = null; int checkNodeCount = 0; if (prefDRCGood.getBoolean()) { geomsToCheck = new NodeInst[xRepeat * yRepeat]; validity = new boolean[xRepeat * yRepeat]; if (nodeList.size() == 1) geomsToCheck[checkNodeCount++] = nodeList.get(0); } // create the array int originalX = 0, originalY = 0; int total = yRepeat * xRepeat; for(int index = 0; index < total; index++) { int x = index % xRepeat; int y = index / xRepeat; if (prefTranspose.getBoolean()) { y = index % yRepeat; x = index / yRepeat; } int xIndex = x; int yIndex = y; if (prefXCenter.getBoolean()) xIndex = x - (xRepeat-1)/2; if (prefYCenter.getBoolean()) yIndex = y - (yRepeat-1)/2; if (prefXRepeat.getInt() < 0) xIndex = -xIndex; if (prefYRepeat.getInt() < 0) yIndex = -yIndex; if (xIndex == 0 && yIndex == 0) { originalX = x; originalY = y; continue; } // first replicate the nodes boolean firstNode = true; Map<NodeInst,NodeInst> nodeMap = new HashMap<NodeInst,NodeInst>(); for(NodeInst ni : nodeList) { double xPos = cX + xOverlap * xIndex; if (prefLinearDiagonal.getBoolean() && xRepeat == 1) xPos = cX + xOverlap * yIndex; double yPos = cY + yOverlap * yIndex; if (prefLinearDiagonal.getBoolean() && yRepeat == 1) yPos = cY + yOverlap * xIndex; double xOff = ni.getAnchorCenterX() - cX; double yOff = ni.getAnchorCenterY() - cY; if ((xIndex&1) != 0 && prefXStagger.getBoolean()) yPos += yOverlap/2; if ((yIndex&1) != 0 && prefYStagger.getBoolean()) xPos += xOverlap/2; boolean flipX = false, flipY = false; if ((xIndex&1) != 0 && prefXFlip.getBoolean()) { flipX = true; xOff = -xOff; } if ((yIndex&1) != 0 && prefYFlip.getBoolean()) { flipY = true; yOff = -yOff; } Orientation orient = Orientation.fromJava(0, flipX, flipY).concatenate(ni.getOrient()); xPos += xOff; yPos += yOff; NodeInst newNi = NodeInst.makeInstance(ni.getProto(), new Point2D.Double(xPos, yPos), ni.getXSize(), ni.getYSize(), cell, orient, null); if (newNi == null) continue; newNi.copyTextDescriptorFrom(ni, NodeInst.NODE_PROTO); newNi.copyTextDescriptorFrom(ni, NodeInst.NODE_NAME); newNi.setExpanded(ni.isExpanded()); if (ni.isHardSelect()) newNi.setHardSelect(); else newNi.clearHardSelect(); newNi.setTechSpecific(ni.getTechSpecific()); newNi.copyVarsFrom(ni); if (prefAddNames.getBoolean()) { setNewName(newNi, x, y); } else { Name nodeNameKey = ni.getNameKey(); if (!nodeNameKey.isTempname()) { newNi.setName(ElectricObject.uniqueObjectName(ni.getName(), cell, NodeInst.class, false, fromRight)); newNi.copyTextDescriptorFrom(ni, NodeInst.NODE_NAME); } } nodeMap.put(ni, newNi); if (prefDRCGood.getBoolean() && firstNode) { geomsToCheck[checkNodeCount++] = newNi; firstNode = false; } } // next replicate the arcs for(ArcInst ai : arcList) { double cX0 = ai.getHeadPortInst().getNodeInst().getAnchorCenterX(); double cY0 = ai.getHeadPortInst().getNodeInst().getAnchorCenterY(); double xOff0 = ai.getHeadLocation().getX() - cX0; double yOff0 = ai.getHeadLocation().getY() - cY0; double cX1 = ai.getTailPortInst().getNodeInst().getAnchorCenterX(); double cY1 = ai.getTailPortInst().getNodeInst().getAnchorCenterY(); double xOff1 = ai.getTailLocation().getX() - cX1; double yOff1 = ai.getTailLocation().getY() - cY1; if ((xIndex&1) != 0 && prefXFlip.getBoolean()) { xOff0 = -xOff0; xOff1 = -xOff1; } if ((yIndex&1) != 0 && prefYFlip.getBoolean()) { yOff0 = -yOff0; yOff1 = -yOff1; } NodeInst ni0 = nodeMap.get(ai.getHeadPortInst().getNodeInst()); if (ni0 == null) continue; NodeInst ni1 = nodeMap.get(ai.getTailPortInst().getNodeInst()); if (ni1 == null) continue; cX0 = ni0.getAnchorCenterX(); cY0 = ni0.getAnchorCenterY(); cX1 = ni1.getAnchorCenterX(); cY1 = ni1.getAnchorCenterY(); PortInst pi0 = ni0.findPortInstFromProto(ai.getHeadPortInst().getPortProto()); PortInst pi1 = ni1.findPortInstFromProto(ai.getTailPortInst().getPortProto()); ArcInst newAi = ArcInst.makeInstanceBase(ai.getProto(), ai.getLambdaBaseWidth(), pi0, pi1, new Point2D.Double(cX0+xOff0, cY0+yOff0), new Point2D.Double(cX1+xOff1, cY1+yOff1), null); if (newAi == null) continue; newAi.copyPropertiesFrom(ai); if (prefAddNames.getBoolean()) { setNewName(newAi, x, y); } else { Name arcNameKey = ai.getNameKey(); if (!arcNameKey.isTempname()) { String newName = ai.getName(); if (arcsAutoIncrement) newName = ElectricObject.uniqueObjectName(newName, cell, ArcInst.class, false, fromRight); newAi.setName(newName); newAi.copyTextDescriptorFrom(ai, ArcInst.ARC_NAME); } } } // copy the exports, too List<PortInst> portInstsToExport = new ArrayList<PortInst>(); Map<PortInst,Export> originalExports = new HashMap<PortInst,Export>(); for(Export pp : exportList) { PortInst oldPI = pp.getOriginalPort(); NodeInst newNI = nodeMap.get(oldPI.getNodeInst()); if (newNI == null) continue; PortInst pi = newNI.findPortInstFromProto(oldPI.getPortProto()); portInstsToExport.add(pi); originalExports.put(pi, pp); } ExportChanges.reExportPorts(cell, portInstsToExport, false, true, true, false, fromRight, originalExports, iconParameters); } // rename the replicated objects if (prefAddNames.getBoolean()) { for(NodeInst ni : nodeList) { setNewName(ni, originalX, originalY); } for(ArcInst ai : arcList) { setNewName(ai, originalX, originalY); } } // if only arraying where DRC valid, check them now and delete what is not valid if (prefDRCGood.getBoolean()) { Quick.checkDesignRules(dp, cell, geomsToCheck, validity).termLogging(true); for(int i=1; i<checkNodeCount; i++) { if (!validity[i]) { // delete the node ((NodeInst)geomsToCheck[i]).kill(); } } } return true; } private void setNewName(Geometric geom, int x, int y) { String objName = ""; Name geomNameKey = geom instanceof NodeInst ? ((NodeInst)geom).getNameKey() : ((ArcInst)geom).getNameKey(); String geomName = geomNameKey.toString(); if (geomNameKey.isTempname()) geomName = null; if (geomName != null) { if (!geomName.equals("0") && !geomName.equals("0-0")) objName = geomName.toString(); } String totalName = objName + x + "-" + y; if (Math.abs(prefXRepeat.getInt()) <= 1 || Math.abs(prefYRepeat.getInt()) <= 1) totalName = objName + (x+y); if (geom instanceof NodeInst) { NodeInst ni = (NodeInst)geom; ni.setName(totalName); if (ni.isCellInstance()) ni.setOff(NodeInst.NODE_NAME, 0, ni.getYSize() / 4); } else { ((ArcInst)geom).setName(totalName); } } } private class DrawArrayListener implements MouseMotionListener, MouseListener, MouseWheelListener, KeyListener { EventListener oldListener; Cursor oldCursor; public void mousePressed(MouseEvent evt) { determineArrayAmount(evt); showHighlight(evt, (EditWindow)evt.getSource()); } public void mouseDragged(MouseEvent evt) { determineArrayAmount(evt); showHighlight(evt, (EditWindow)evt.getSource()); } public void mouseReleased(MouseEvent evt) { // restore the highlighting EditWindow wnd = (EditWindow)evt.getSource(); Highlighter highlighter = wnd.getHighlighter(); Cell cell = wnd.getCell(); highlighter.clear(); for(Geometric geom : selected) highlighter.addElectricObject(geom, cell); highlighter.finished(); // restore the listener to the former state restoreOriginalSetup(); makeArray(); } public void keyPressed(KeyEvent evt) { // ESCAPE for abort int chr = evt.getKeyCode(); if (chr == KeyEvent.VK_ESCAPE) { restoreOriginalSetup(); System.out.println("Array drawing aborted"); } } private void restoreOriginalSetup() { // restore the listener to the former state WindowFrame.setListener(oldListener); Main.setCurrentCursor(oldCursor); } private void determineArrayAmount(MouseEvent evt) { EditWindow wnd = (EditWindow)evt.getSource(); int x = evt.getX(); int y = evt.getY(); Point2D pt = wnd.screenToDatabase(x, y); double xOverlap = TextUtils.atofDistance(xSpacing.getText()); double yOverlap = TextUtils.atofDistance(ySpacing.getText()); if (prefSpacingType.getInt() == SPACING_EDGE) { xOverlap = bounds.getWidth() - xOverlap; yOverlap = bounds.getHeight() - yOverlap; } double dX = pt.getX() - bounds.getCenterX(); if (dX > 0) dX -= bounds.getWidth()/2; else dX += bounds.getWidth()/2; int xRep = (int)(dX / xOverlap); if (xRep == 0) xRep = 1; else { if (xRep < 0) xRep--; else xRep++; } if (prefXCenter.getBoolean()) xRep = (Math.abs(xRep) - 1) * 2 + 1; double dY = pt.getY() - bounds.getCenterY(); if (dY > 0) dY -= bounds.getHeight()/2; else dY += bounds.getHeight()/2; int yRep = (int)(dY / yOverlap); if (yRep == 0) yRep = 1; else { if (yRep < 0) yRep--; else yRep++; } if (prefYCenter.getBoolean()) yRep = (Math.abs(yRep) - 1) * 2 + 1; if (prefLinearDiagonal.getBoolean()) { if (Math.abs(xRep) > Math.abs(yRep)) xRep = 1; else yRep = 1; } // show current repeat factors prefXRepeat.setInt(xRep); xRepeat.setText(Integer.toString(xRep)); prefYRepeat.setInt(yRep); yRepeat.setText(Integer.toString(yRep)); } private void showHighlight(MouseEvent evt, EditWindow wnd) { double xOverlap = TextUtils.atofDistance(xSpacing.getText()); double yOverlap = TextUtils.atofDistance(ySpacing.getText()); if (prefSpacingType.getInt() == SPACING_EDGE) { xOverlap = bounds.getWidth() - xOverlap; yOverlap = bounds.getHeight() - yOverlap; } Highlighter highlighter = wnd.getHighlighter(); Cell cell = wnd.getCell(); highlighter.clear(); int xRepeat = Math.abs(prefXRepeat.getInt()); int yRepeat = Math.abs(prefYRepeat.getInt()); double cX = bounds.getCenterX(); double cY = bounds.getCenterY(); int total = yRepeat * xRepeat; for(int index = 0; index < total; index++) { int x = index % xRepeat; int y = index / xRepeat; if (prefTranspose.getBoolean()) { y = index % yRepeat; x = index / yRepeat; } int xIndex = x; int yIndex = y; if (prefXCenter.getBoolean()) xIndex = x - (xRepeat-1)/2; if (prefYCenter.getBoolean()) yIndex = y - (yRepeat-1)/2; if (prefXRepeat.getInt() < 0) xIndex = -xIndex; if (prefYRepeat.getInt() < 0) yIndex = -yIndex; double xPos = cX + xOverlap * xIndex; if (prefLinearDiagonal.getBoolean() && xRepeat == 1) xPos = cX + xOverlap * yIndex; double yPos = cY + yOverlap * yIndex; if (prefLinearDiagonal.getBoolean() && yRepeat == 1) yPos = cY + yOverlap * xIndex; if ((xIndex&1) != 0 && prefXStagger.getBoolean()) yPos += yOverlap/2; if ((yIndex&1) != 0 && prefYStagger.getBoolean()) xPos += xOverlap/2; double lX = xPos - bounds.getWidth()/2; double hX = lX + bounds.getWidth(); double lY = yPos - bounds.getHeight()/2; double hY = lY + bounds.getHeight(); Rectangle2D area = new Rectangle2D.Double(lX, lY, hX-lX, hY-lY); highlighter.addArea(area, cell); double headSize = Math.min(bounds.getWidth(), bounds.getHeight()) / 5; if ((xIndex&1) != 0 && prefXFlip.getBoolean()) { Point2D head = new Point2D.Double(lX, yPos); Point2D head1 = new Point2D.Double(lX+headSize, yPos+headSize); Point2D head2 = new Point2D.Double(lX+headSize, yPos-headSize); Point2D tail = new Point2D.Double(hX, yPos); Point2D tail1 = new Point2D.Double(hX-headSize, yPos+headSize); Point2D tail2 = new Point2D.Double(hX-headSize, yPos-headSize); highlighter.addLine(head, tail, cell); highlighter.addLine(head, head1, cell); highlighter.addLine(head, head2, cell); highlighter.addLine(tail, tail1, cell); highlighter.addLine(tail, tail2, cell); } if ((yIndex&1) != 0 && prefYFlip.getBoolean()) { Point2D head = new Point2D.Double(xPos, lY); Point2D head1 = new Point2D.Double(xPos+headSize, lY+headSize); Point2D head2 = new Point2D.Double(xPos-headSize, lY+headSize); Point2D tail = new Point2D.Double(xPos, hY); Point2D tail1 = new Point2D.Double(xPos+headSize, hY-headSize); Point2D tail2 = new Point2D.Double(xPos-headSize, hY-headSize); highlighter.addLine(head, tail, cell); highlighter.addLine(head, head1, cell); highlighter.addLine(head, head2, cell); highlighter.addLine(tail, tail1, cell); highlighter.addLine(tail, tail2, cell); } } highlighter.finished(); } public void mouseClicked(MouseEvent evt) {} public void mouseMoved(MouseEvent evt) {} public void mouseEntered(MouseEvent evt) {} public void mouseExited(MouseEvent evt) {} public void mouseWheelMoved(MouseWheelEvent evt) {} public void keyReleased(KeyEvent evt) {} public void keyTyped(KeyEvent evt) {} } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; spacing = new javax.swing.ButtonGroup(); cancel = new javax.swing.JButton(); ok = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); xRepeat = new javax.swing.JTextField(); flipAlternateColumns = new javax.swing.JCheckBox(); staggerAlternateColumns = new javax.swing.JCheckBox(); centerXAboutOriginal = new javax.swing.JCheckBox(); jLabel2 = new javax.swing.JLabel(); yRepeat = new javax.swing.JTextField(); flipAlternateRows = new javax.swing.JCheckBox(); staggerAlternateRows = new javax.swing.JCheckBox(); centerYAboutOriginal = new javax.swing.JCheckBox(); jSeparator1 = new javax.swing.JSeparator(); xOverlapLabel = new javax.swing.JLabel(); xSpacing = new javax.swing.JTextField(); spaceByEdgeOverlap = new javax.swing.JRadioButton(); spaceByCenterlineDistance = new javax.swing.JRadioButton(); yOverlapLabel = new javax.swing.JLabel(); ySpacing = new javax.swing.JTextField(); spaceByEssentialBnd = new javax.swing.JRadioButton(); spaceByMeasuredDistance = new javax.swing.JRadioButton(); linearDiagonalArray = new javax.swing.JCheckBox(); generateArrayIndices = new javax.swing.JCheckBox(); onlyDRCCorrect = new javax.swing.JCheckBox(); transposePlacement = new javax.swing.JCheckBox(); apply = new javax.swing.JButton(); draw = new javax.swing.JButton(); getContentPane().setLayout(new java.awt.GridBagLayout()); setTitle("Array"); setName(""); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { closeDialog(evt); } }); cancel.setText("Cancel"); cancel.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { cancel(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 13; gridBagConstraints.gridheight = 2; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(cancel, gridBagConstraints); ok.setText("OK"); ok.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { ok(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 3; gridBagConstraints.gridy = 13; gridBagConstraints.gridheight = 2; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(ok, gridBagConstraints); jLabel1.setText("X repeat factor:"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.gridheight = 3; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(jLabel1, gridBagConstraints); xRepeat.setColumns(6); xRepeat.setText(" "); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.gridheight = 3; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(xRepeat, gridBagConstraints); flipAlternateColumns.setText("Flip alternate columns"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 4); getContentPane().add(flipAlternateColumns, gridBagConstraints); staggerAlternateColumns.setText("Stagger alternate columns"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4); getContentPane().add(staggerAlternateColumns, gridBagConstraints); centerXAboutOriginal.setText("Center about original"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 2; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 4, 4, 4); getContentPane().add(centerXAboutOriginal, gridBagConstraints); jLabel2.setText("Y repeat factor:"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 3; gridBagConstraints.gridheight = 3; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(jLabel2, gridBagConstraints); yRepeat.setColumns(6); yRepeat.setText(" "); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 3; gridBagConstraints.gridheight = 3; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(yRepeat, gridBagConstraints); flipAlternateRows.setText("Flip alternate rows"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 3; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 4); getContentPane().add(flipAlternateRows, gridBagConstraints); staggerAlternateRows.setText("Stagger alternate rows"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 4; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 4); getContentPane().add(staggerAlternateRows, gridBagConstraints); centerYAboutOriginal.setText("Center about original"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 5; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 4, 4, 4); getContentPane().add(centerYAboutOriginal, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 6; gridBagConstraints.gridwidth = 4; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(jSeparator1, gridBagConstraints); xOverlapLabel.setText("X edge overlap:"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 7; gridBagConstraints.gridheight = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(xOverlapLabel, gridBagConstraints); xSpacing.setColumns(6); xSpacing.setText(" "); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 7; gridBagConstraints.gridheight = 2; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(xSpacing, gridBagConstraints); spacing.add(spaceByEdgeOverlap); spaceByEdgeOverlap.setText("Space by edge overlap"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 7; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; getContentPane().add(spaceByEdgeOverlap, gridBagConstraints); spacing.add(spaceByCenterlineDistance); spaceByCenterlineDistance.setText("Space by centerline distance"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 8; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; getContentPane().add(spaceByCenterlineDistance, gridBagConstraints); yOverlapLabel.setText("Y edge overlap:"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 9; gridBagConstraints.gridheight = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(yOverlapLabel, gridBagConstraints); ySpacing.setColumns(6); ySpacing.setText(" "); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 9; gridBagConstraints.gridheight = 2; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(ySpacing, gridBagConstraints); spacing.add(spaceByEssentialBnd); spaceByEssentialBnd.setText("Space by cell essential bound"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 9; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; getContentPane().add(spaceByEssentialBnd, gridBagConstraints); spacing.add(spaceByMeasuredDistance); spaceByMeasuredDistance.setText("Space by last measured distance"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 10; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; getContentPane().add(spaceByMeasuredDistance, gridBagConstraints); linearDiagonalArray.setText("Linear diagonal array"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 11; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(4, 4, 2, 4); getContentPane().add(linearDiagonalArray, gridBagConstraints); generateArrayIndices.setText("Generate array indices"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 12; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4); getContentPane().add(generateArrayIndices, gridBagConstraints); onlyDRCCorrect.setText("Only place entries that are DRC correct"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 13; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4); getContentPane().add(onlyDRCCorrect, gridBagConstraints); transposePlacement.setText("Transpose placement ordering"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 14; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(2, 4, 4, 4); getContentPane().add(transposePlacement, gridBagConstraints); apply.setText("Apply"); apply.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { applyActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 3; gridBagConstraints.gridy = 11; gridBagConstraints.gridheight = 2; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(apply, gridBagConstraints); draw.setText("Draw"); draw.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { drawActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 11; gridBagConstraints.gridheight = 2; gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4); getContentPane().add(draw, gridBagConstraints); pack(); }// </editor-fold>//GEN-END:initComponents private void drawActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_drawActionPerformed rememberFields(); EventListener oldListener = WindowFrame.getListener(); Cursor oldCursor = Main.getCurrentCursor(); if (oldListener == null || !(oldListener instanceof DrawArrayListener)) { DrawArrayListener newListener = new DrawArrayListener(); WindowFrame.setListener(newListener); newListener.oldListener = oldListener; newListener.oldCursor = oldCursor; } Main.setCurrentCursor(drawArrayCursor); System.out.println("Click to draw the array"); }//GEN-LAST:event_drawActionPerformed private void applyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyActionPerformed rememberFields(); makeArray(); }//GEN-LAST:event_applyActionPerformed private void cancel(java.awt.event.ActionEvent evt)//GEN-FIRST:event_cancel {//GEN-HEADEREND:event_cancel closeDialog(null); }//GEN-LAST:event_cancel private void ok(java.awt.event.ActionEvent evt)//GEN-FIRST:event_ok {//GEN-HEADEREND:event_ok rememberFields(); makeArray(); closeDialog(null); }//GEN-LAST:event_ok /** Closes the dialog */ private void closeDialog(java.awt.event.WindowEvent evt)//GEN-FIRST:event_closeDialog { rememberFields(); setVisible(false); dispose(); }//GEN-LAST:event_closeDialog // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton apply; private javax.swing.JButton cancel; private javax.swing.JCheckBox centerXAboutOriginal; private javax.swing.JCheckBox centerYAboutOriginal; private javax.swing.JButton draw; private javax.swing.JCheckBox flipAlternateColumns; private javax.swing.JCheckBox flipAlternateRows; private javax.swing.JCheckBox generateArrayIndices; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JSeparator jSeparator1; private javax.swing.JCheckBox linearDiagonalArray; private javax.swing.JButton ok; private javax.swing.JCheckBox onlyDRCCorrect; private javax.swing.JRadioButton spaceByCenterlineDistance; private javax.swing.JRadioButton spaceByEdgeOverlap; private javax.swing.JRadioButton spaceByEssentialBnd; private javax.swing.JRadioButton spaceByMeasuredDistance; private javax.swing.ButtonGroup spacing; private javax.swing.JCheckBox staggerAlternateColumns; private javax.swing.JCheckBox staggerAlternateRows; private javax.swing.JCheckBox transposePlacement; private javax.swing.JLabel xOverlapLabel; private javax.swing.JTextField xRepeat; private javax.swing.JTextField xSpacing; private javax.swing.JLabel yOverlapLabel; private javax.swing.JTextField yRepeat; private javax.swing.JTextField ySpacing; // End of variables declaration//GEN-END:variables }