/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Metal.java * * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. * * 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.tecEditWizard2; import com.sun.electric.tool.Job; import com.sun.electric.tool.user.Resources; import com.sun.electric.util.TextUtils; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; /** * Class to handle the "Metal" tab of the Numeric Technology Editor dialog. */ public class Metal extends TechEditWizardPanel { private JPanel metal; private JScrollPane metalPane; private MetalContainer[] metalContainers; private int numMetals; private TechEditWizard parent; private class MetalContainer { JLabel widthLabel, spacingLabel; JTextField spacing, spacingRule; JTextField width, widthRule; } /** Creates new form Metal */ public Metal(TechEditWizard parent, boolean modal) { super(parent, modal); this.parent = parent; setTitle("Metal"); setName(""); metal = new JPanel(); metal.setLayout(new GridBagLayout()); metalPane = new javax.swing.JScrollPane(); JLabel heading = new JLabel("Metal Parameters"); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 3; gbc.insets = new Insets(4, 4, 4, 4); metal.add(heading, gbc); JLabel image = new JLabel(); image.setIcon(Resources.getResource(getClass(), "Metal.png")); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 3; gbc.insets = new Insets(4, 4, 4, 4); metal.add(image, gbc); JButton addMetal = new JButton("Add Metal"); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 2; gbc.insets = new Insets(4, 4, 4, 4); addMetal.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { addMetal(); } }); metal.add(addMetal, gbc); JButton removeMetal = new JButton("Remove Metal"); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 2; gbc.insets = new Insets(4, 4, 4, 4); removeMetal.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { removeMetal(); } }); metal.add(removeMetal, gbc); JLabel l1 = new JLabel("Distance"); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 3; metal.add(l1, gbc); JLabel l2 = new JLabel("Rule Name"); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 3; metal.add(l2, gbc); metalPane.setViewportView(metal); getContentPane().setLayout(new java.awt.GridBagLayout()); getContentPane().add(metalPane, new java.awt.GridBagConstraints()); JLabel nano = new JLabel("Distances are in nanometers"); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 99; gbc.gridwidth = 3; gbc.insets = new Insets(4, 4, 4, 4); metal.add(nano, gbc); } /** return the panel to use for this Numeric Technology Editor tab. */ public Component getComponent() { return metalPane; } /** return the name of this Numeric Technology Editor tab. */ public String getName() { return "Metal"; } /** * Method called at the start of the dialog. * Caches current values and displays them in the Metal tab. */ public void init() { TechEditWizardData data = wizard.getTechEditData(); numMetals = data.getNumMetalLayers(); metalContainers = new MetalContainer[numMetals]; for(int i=0; i<numMetals; i++) { metalContainers[i] = addMetalLayer(i, data); } } /** * Method to create the dialog fields for a metal layer. * @param i the metal layer to fill-in. */ private MetalContainer addMetalLayer(int i, TechEditWizardData data) { MetalContainer mc = new MetalContainer(); mc.widthLabel = new JLabel("Metal-" + (i+1) + " width (A):"); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 4+i*2; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(4, 4, 1, 0); metal.add(mc.widthLabel, gbc); mc.width = new JTextField(); mc.width.setColumns(8); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 4+i*2; gbc.insets = new Insets(4, 0, 1, 2); metal.add(mc.width, gbc); mc.widthRule = new JTextField(); mc.widthRule.setColumns(8); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 4+i*2; gbc.insets = new Insets(4, 0, 1, 2); metal.add(mc.widthRule, gbc); mc.spacingLabel = new JLabel("Metal-" + (i+1) + " spacing (B):"); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 5+i*2; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(1, 4, 4, 0); metal.add(mc.spacingLabel, gbc); mc.spacing = new JTextField(); mc.spacing.setColumns(8); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 5+i*2; gbc.insets = new Insets(1, 0, 4, 2); metal.add(mc.spacing, gbc); mc.spacingRule = new JTextField(); mc.spacingRule.setColumns(8); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 5+i*2; gbc.insets = new Insets(1, 0, 4, 2); metal.add(mc.spacingRule, gbc); if (data != null) { mc.width.setText(TextUtils.formatDouble(data.getMetalWidth()[i].value)); mc.widthRule.setText(data.getMetalWidth()[i].rule); mc.spacing.setText(TextUtils.formatDouble(data.getMetalSpacing()[i].value)); mc.spacingRule.setText(data.getMetalSpacing()[i].rule); } return mc; } /** * Method called when the user clicks "Add Metal" */ private void addMetal() { numMetals++; MetalContainer[] newMetalContainers = new MetalContainer[numMetals]; System.arraycopy(metalContainers, 0, newMetalContainers, 0, numMetals-1); metalContainers = newMetalContainers; metalContainers[numMetals-1] = addMetalLayer(numMetals-1, null); parent.pack(); } /** * Method called when the user clicks "Remove Metal" */ private void removeMetal() { if (numMetals <= 1) { Job.getUserInterface().showErrorMessage("Cannot delete the last metal layer: must be at least one", "Illegal Operation"); return; } numMetals--; MetalContainer mc = metalContainers[numMetals]; metalContainers[numMetals] = null; metal.remove(mc.widthLabel); metal.remove(mc.width); metal.remove(mc.widthRule); metal.remove(mc.spacingLabel); metal.remove(mc.spacing); metal.remove(mc.spacingRule); parent.pack(); } /** * Method called when the "OK" panel is hit. * Updates any changed fields in the Metal tab. */ public void term() { TechEditWizardData data = wizard.getTechEditData(); data.setNumMetalLayers(numMetals); for(int i=0; i<numMetals; i++) { MetalContainer mc = metalContainers[i]; data.setMetalWidth(i, new WizardField(TextUtils.atof(mc.width.getText()), mc.widthRule.getText())); data.setMetalSpacing(i, new WizardField(TextUtils.atof(mc.spacing.getText()), mc.spacingRule.getText())); } } }