📄 panel.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Panel.java * * Copyright (c) 2004 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.waveform;import com.sun.electric.database.geometry.GenMath;import com.sun.electric.database.geometry.Poly;import com.sun.electric.database.geometry.PolyBase;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.variable.TextDescriptor;import com.sun.electric.technology.technologies.Artwork;import com.sun.electric.tool.simulation.AnalogAnalysis;import com.sun.electric.tool.simulation.AnalogSignal;import com.sun.electric.tool.simulation.Analysis;import com.sun.electric.tool.simulation.DigitalAnalysis;import com.sun.electric.tool.simulation.DigitalSignal;import com.sun.electric.tool.simulation.Signal;import com.sun.electric.tool.simulation.Simulation;import com.sun.electric.tool.simulation.Stimuli;import com.sun.electric.tool.simulation.Waveform;import com.sun.electric.tool.user.Highlight2;import com.sun.electric.tool.user.Resources;import com.sun.electric.tool.user.User;import com.sun.electric.tool.user.dialogs.WaveformZoom;import com.sun.electric.tool.user.ui.ClickZoomWireListener;import com.sun.electric.tool.user.ui.ToolBar;import com.sun.electric.tool.user.ui.TopLevel;import com.sun.electric.tool.user.ui.ZoomAndPanListener;import java.awt.BasicStroke;import java.awt.Color;import java.awt.Component;import java.awt.Cursor;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.GridBagConstraints;import java.awt.GridBagLayout;import java.awt.Image;import java.awt.Insets;import java.awt.Point;import java.awt.Rectangle;import java.awt.RenderingHints;import java.awt.datatransfer.StringSelection;import java.awt.datatransfer.Transferable;import java.awt.dnd.DnDConstants;import java.awt.dnd.DragGestureEvent;import java.awt.dnd.DragGestureListener;import java.awt.dnd.DragSource;import java.awt.dnd.DragSourceDragEvent;import java.awt.dnd.DragSourceDropEvent;import java.awt.dnd.DragSourceEvent;import java.awt.dnd.DragSourceListener;import java.awt.dnd.DropTarget;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.font.GlyphVector;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.awt.image.BufferedImage;import java.awt.image.VolatileImage;import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedHashMap;import java.util.List;import java.util.Set;import javax.swing.BoxLayout;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JComboBox;import javax.swing.JLabel;import javax.swing.JMenuItem;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JPopupMenu;import javax.swing.JScrollPane;import javax.swing.JSeparator;import javax.swing.JTable;import javax.swing.SwingConstants;/** * This class defines a single panel of WaveSignals with an associated list of signal names. */public class Panel extends JPanel implements MouseMotionListener, MouseListener, MouseWheelListener, KeyListener{ /** Use VolatileImage for offscreen buffer */ private static final boolean USE_VOLATILE_IMAGE = true; /** Use anti-aliasing for lines */ private static final boolean USE_ANTIALIASING = false; /** the main waveform window this is part of */ private WaveformWindow waveWindow; /** the size of the window (in pixels) */ private Dimension sz; /** true if the size field is valid */ private boolean szValid; /** the signal on the X axis (null for time) */ private Signal xAxisSignal; /** maps signal buttons to the actual Signal */ private LinkedHashMap<JButton,WaveSignal> waveSignals = new LinkedHashMap<JButton,WaveSignal>(); /** the list of signal name buttons on the left */ private JPanel signalButtons; /** the JScrollPane with of signal name buttons */ private JScrollPane signalButtonsPane; /** the left side: with signal names etc. */ private JPanel leftHalf; /** the right side: with signal traces */ private JPanel rightHalf; /** the button to close this panel. */ private JButton close; /** the button to hide this panel. */ private JButton hide; /** the button to delete selected signal (analog). */ private JButton deleteSignal; /** the button to delete all signals (analog). */ private JButton deleteAllSignals; /** the signal name button (digital). */ private JButton digitalSignalButton; /** for selecting the type of data in this panel */ private JComboBox analysisCombo; /** displayed range along horozintal axis */ private double minXPosition, maxXPosition; /** low value displayed in this panel (analog) */ private double analogLowValue; /** high value displayed in this panel (analog) */ private double analogHighValue; /** vertical range displayed in this panel (analog) */ private double analogRange; /** true if an X axis cursor is being dragged */ private boolean draggingMain, draggingExt, draggingVertAxis; /** true if an area is being dragged */ private boolean draggingArea; /** list of measurements being displayed */ private List<Rectangle2D> measurementList; /** current measurement being displayed */ private Rectangle2D curMeasurement; /** true if this waveform panel is selected */ private boolean selected; /** true if this waveform panel is hidden */ private boolean hidden; /** the type of analysis shown in this panel */ private Analysis.AnalysisType analysisType; /** true for analog panel; false for digital */ private boolean analog; /** the horizontal ruler at the top of this panel. */ private HorizRuler horizRulerPanel; /** true if the horizontal ruler is logarithmic */ private boolean horizRulerPanelLogarithmic; /** true if this panel is logarithmic in Y */ private boolean vertPanelLogarithmic; /** the number of this panel. */ private int panelNumber; /** extent of area dragged-out by cursor */ private double dragStartXD, dragStartYD; /** extent of area dragged-out by cursor */ private double dragEndXD, dragEndYD; /** the location of the Y axis vertical line */ private int vertAxisPos; /** the smallest nonzero X value (for log drawing) */ private double smallestXValue; /** the smallest nonzero Y value (for log drawing) */ private double smallestYValue; /** the background color of a button */ private static Color background = null; /** The color of the grid (a gray) */ private static Color gridColor = new Color(0x808080); /** the panel numbering index */ private static int nextPanelNumber = 1; /** for determining double-clicks */ private static long lastClick = 0; /** current panel */ private static Panel curPanel; /** current X coordinate in the panel */ private static int curXPos; /** for drawing far-dotted lines */ private static final BasicStroke farDottedLine = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[] {4,12}, 0); /** the size of control point squares */ private static final int CONTROLPOINTSIZE = 6; /** the width of the panel label on the left */ private static final int VERTLABELWIDTH = 60; private static final ImageIcon iconHidePanel = Resources.getResource(WaveformWindow.class, "ButtonSimHide.gif"); private static final ImageIcon iconClosePanel = Resources.getResource(WaveformWindow.class, "ButtonSimClose.gif"); private static final ImageIcon iconDeleteSignal = Resources.getResource(WaveformWindow.class, "ButtonSimDelete.gif"); private static final ImageIcon iconDeleteAllSignals = Resources.getResource(WaveformWindow.class, "ButtonSimDeleteAll.gif"); private static final Cursor dragXPositionCursor = ToolBar.readCursor("CursorDragTime.gif", 8, 8); /** * Constructor creates a panel in a WaveformWindow. * @param waveWindow the WaveformWindow in which to place this Panel. * @param analysisType the type of data shown in this Panel. */ public Panel(WaveformWindow waveWindow, boolean analog, Analysis.AnalysisType analysisType) { // remember state this.waveWindow = waveWindow; setAnalysisType(analysisType); this.analog = analog; selected = false; panelNumber = nextPanelNumber++; vertAxisPos = VERTLABELWIDTH; horizRulerPanelLogarithmic = false; vertPanelLogarithmic = false; xAxisSignal = null; measurementList = new ArrayList<Rectangle2D>(); curMeasurement = null; // setup this panel window int height = User.getWaveformDigitalPanelHeight(); if (analog) height = User.getWaveformAnalogPanelHeight(); sz = new Dimension(50, height); szValid = false; setSize(sz.width, sz.height); setPreferredSize(sz); setLayout(new FlowLayout()); // add listeners --> BE SURE to remove listeners in finished() addKeyListener(this); addMouseListener(this); addMouseMotionListener(this); addMouseWheelListener(this); setXAxisRange(waveWindow.getLowDefaultHorizontalRange(), waveWindow.getHighDefaultHorizontalRange()); // the left side with signal names leftHalf = new WaveformWindow.OnePanel(this, waveWindow); leftHalf.setLayout(new GridBagLayout()); leftHalf.setPreferredSize(new Dimension(100, height)); // a drop target for the signal panel new DropTarget(leftHalf, DnDConstants.ACTION_LINK, WaveformWindow.waveformDropTarget, true); // a separator at the top JSeparator sep = new JSeparator(SwingConstants.HORIZONTAL); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 5; gbc.gridheight = 1; gbc.weightx = 1; gbc.weighty = 0; gbc.anchor = GridBagConstraints.NORTH; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(4, 0, 4, 0); leftHalf.add(sep, gbc); // the name of this panel if (analog) { // analog panel JLabel label = new DragLabel(Integer.toString(panelNumber)); label.setToolTipText("Identification number of this waveform panel (drag the number to rearrange panels)"); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; gbc.weightx = 0.2; gbc.weighty = 0; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(4, 4, 4, 4); leftHalf.add(label, gbc); } else { // digital panel digitalSignalButton = new DragButton(Integer.toString(panelNumber), panelNumber); digitalSignalButton.setBorderPainted(false); digitalSignalButton.setForeground(Color.BLACK); digitalSignalButton.setToolTipText("Identification number of this waveform panel (drag the number to rearrange panels)"); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; gbc.weightx = 1; gbc.weighty = 1; gbc.anchor = GridBagConstraints.CENTER; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(0, 4, 0, 4); leftHalf.add(digitalSignalButton, gbc); digitalSignalButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { digitalSignalNameClicked(evt); } }); } // the close button for this panel close = new JButton(iconClosePanel); close.setBorderPainted(false); close.setDefaultCapable(false); close.setToolTipText("Close this waveform panel"); Dimension minWid = new Dimension(iconClosePanel.getIconWidth()+4, iconClosePanel.getIconHeight()+4); close.setMinimumSize(minWid); close.setPreferredSize(minWid); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 1; gbc.weightx = 0.2; gbc.weighty = 0; if (analog) gbc.anchor = GridBagConstraints.NORTH; else gbc.anchor = GridBagConstraints.CENTER; gbc.fill = GridBagConstraints.NONE; leftHalf.add(close, gbc); close.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { closePanel(); } }); // the hide button for this panel hide = new JButton(iconHidePanel); hide.setBorderPainted(false); hide.setDefaultCapable(false); hide.setToolTipText("Hide this waveform panel"); minWid = new Dimension(iconHidePanel.getIconWidth()+4, iconHidePanel.getIconHeight()+4); hide.setMinimumSize(minWid); hide.setPreferredSize(minWid); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 1; gbc.weightx = 0.2; gbc.weighty = 0; if (analog) gbc.anchor = GridBagConstraints.NORTH; else gbc.anchor = GridBagConstraints.CENTER; gbc.fill = GridBagConstraints.NONE; leftHalf.add(hide, gbc); hide.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { hidePanel(); } }); if (analog) { // the "delete signal" button for this panel (analog only) deleteSignal = new JButton(iconDeleteSignal); deleteSignal.setBorderPainted(false); deleteSignal.setDefaultCapable(false); deleteSignal.setToolTipText("Remove selected signals from this panel"); minWid = new Dimension(iconDeleteSignal.getIconWidth()+4, iconDeleteSignal.getIconHeight()+4); deleteSignal.setMinimumSize(minWid); deleteSignal.setPreferredSize(minWid); gbc = new GridBagConstraints(); gbc.gridx = 3; gbc.gridy = 1; gbc.weightx = 0.2; gbc.weighty = 0; gbc.anchor = GridBagConstraints.NORTH; gbc.fill = GridBagConstraints.NONE; leftHalf.add(deleteSignal, gbc); deleteSignal.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { deleteSignalFromPanel(); } }); // the "delete all signal" button for this panel (analog only) deleteAllSignals = new JButton(iconDeleteAllSignals); deleteAllSignals.setBorderPainted(false); deleteAllSignals.setDefaultCapable(false); deleteAllSignals.setToolTipText("Remove all signals from this panel"); minWid = new Dimension(iconDeleteAllSignals.getIconWidth()+4, iconDeleteAllSignals.getIconHeight()+4); deleteAllSignals.setMinimumSize(minWid); deleteAllSignals.setPreferredSize(minWid); gbc = new GridBagConstraints(); gbc.gridx = 4; gbc.gridy = 1; gbc.weightx = 0.2; gbc.weighty = 0; gbc.anchor = GridBagConstraints.NORTH; gbc.fill = GridBagConstraints.NONE; leftHalf.add(deleteAllSignals, gbc); deleteAllSignals.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { deleteAllSignalsFromPanel(); } }); // the "signal type" selector for this panel (analog only) boolean hasACData = waveWindow.getSimData().findAnalysis(Analysis.ANALYSIS_AC) != null; boolean hasDCData = waveWindow.getSimData().findAnalysis(Analysis.ANALYSIS_DC) != null; boolean hasMeasData = waveWindow.getSimData().findAnalysis(Analysis.ANALYSIS_MEAS) != null; if (hasACData || hasDCData || hasMeasData) { analysisCombo = new JComboBox(); analysisCombo.addItem(Analysis.ANALYSIS_TRANS.toString()); if (hasACData) analysisCombo.addItem(Analysis.ANALYSIS_AC.toString()); if (hasDCData) analysisCombo.addItem(Analysis.ANALYSIS_DC.toString()); if (hasMeasData) analysisCombo.addItem(Analysis.ANALYSIS_MEAS.toString()); analysisCombo.setToolTipText("Sets the type of data seen in this panel"); analysisCombo.setSelectedItem(analysisType.toString()); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth = 5; gbc.gridheight = 1; gbc.anchor = GridBagConstraints.CENTER; gbc.fill = GridBagConstraints.HORIZONTAL; leftHalf.add(analysisCombo, gbc); analysisCombo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { setPanelSignalType(); } }); } // the list of signals in this panel (analog only) signalButtons = new JPanel(); signalButtons.setLayout(new BoxLayout(signalButtons, BoxLayout.Y_AXIS)); signalButtonsPane = new JScrollPane(signalButtons);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -