📄 display.java
字号:
package prefuse;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
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.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolTip;
import javax.swing.KeyStroke;
import javax.swing.text.JTextComponent;
import prefuse.activity.Activity;
import prefuse.activity.SlowInSlowOutPacer;
import prefuse.controls.Control;
import prefuse.data.expression.AndPredicate;
import prefuse.data.expression.BooleanLiteral;
import prefuse.data.expression.Predicate;
import prefuse.data.expression.parser.ExpressionParser;
import prefuse.render.Renderer;
import prefuse.util.ColorLib;
import prefuse.util.StringLib;
import prefuse.util.UpdateListener;
import prefuse.util.collections.CopyOnWriteArrayList;
import prefuse.util.display.BackgroundPainter;
import prefuse.util.display.Clip;
import prefuse.util.display.DebugStatsPainter;
import prefuse.util.display.ExportDisplayAction;
import prefuse.util.display.ItemBoundsListener;
import prefuse.util.display.PaintListener;
import prefuse.util.display.RenderingQueue;
import prefuse.visual.VisualItem;
import prefuse.visual.expression.VisiblePredicate;
import prefuse.visual.sort.ItemSorter;
/**
* <p>User interface component that provides an interactive view onto
* a visualization. The Display is responsible for drawing items to the
* screen and providing callbacks for user interface actions such as
* mouse and keyboard events. A Display must be associated with an
* {@link prefuse.Visualization} from which it pulls the items to visualize.
* </p>
*
* <p>To control which {@link prefuse.visual.VisualItem} instances are
* drawn, the Display also maintains an optional
* {@link prefuse.data.expression.Predicate} for filtering items. The
* drawing order of items is
* controlled by an {@link prefuse.visual.sort.ItemSorter} instance,
* which calculates a score for each item. Items with higher scores
* are drawn later, and hence on top of lower scoring items.
* </p>
*
* <p>The {@link prefuse.controls.Control Control}
* interface provides the user interface callbacks for supporting
* interaction. The {@link prefuse.controls} package contains a number
* of pre-built <code>Control</code> implementations for common
* interactions.</p>
*
* <p>The Display class also supports arbitrary graphics transforms through
* the <code>java.awt.geom.AffineTransform</code> class. The
* {@link #setTransform(java.awt.geom.AffineTransform) setTransform} method
* allows arbitrary transforms to be applied, while the
* {@link #pan(double,double) pan} and
* {@link #zoom(java.awt.geom.Point2D,double) zoom}
* methods provide convenience methods that appropriately update the current
* transform to achieve panning and zooming of the presentation space.</p>
*
* <p>Additionally, each Display instance also supports use of a text editor
* to facilitate direct editing of text. See the various
* {@link #editText(prefuse.visual.VisualItem, String)} methods.</p>
*
* @version 1.0
* @author <a href="http://jheer.org">jeffrey heer</a>
* @see Visualization
* @see prefuse.controls.Control
* @see prefuse.controls
*/
public class Display extends JComponent {
private static final Logger s_logger
= Logger.getLogger(Display.class.getName());
// visual item source
protected Visualization m_vis;
protected AndPredicate m_predicate = new AndPredicate();
// listeners
protected CopyOnWriteArrayList m_controls = new CopyOnWriteArrayList();
protected CopyOnWriteArrayList m_painters;
protected CopyOnWriteArrayList m_bounders;
// display
protected BufferedImage m_offscreen;
protected Clip m_clip = new Clip();
protected Clip m_screen = new Clip();
protected Clip m_bounds = new Clip();
protected Rectangle2D m_rclip = new Rectangle2D.Double();
protected boolean m_damageRedraw = true;
protected boolean m_highQuality = false;
// optional background image
protected BackgroundPainter m_bgpainter = null;
// rendering queue
protected RenderingQueue m_queue = new RenderingQueue();
protected int m_visibleCount = 0;
// transform variables
protected AffineTransform m_transform = new AffineTransform();
protected AffineTransform m_itransform = new AffineTransform();
protected TransformActivity m_transact = new TransformActivity();
protected Point2D m_tmpPoint = new Point2D.Double();
// frame count and debugging output
protected double frameRate;
protected int nframes = 0;
private int sampleInterval = 10;
private long mark = -1L;
/* Custom tooltip, null to use regular tooltip mechanisms */
protected JToolTip m_customToolTip = null;
// text editing variables
private JTextComponent m_editor;
private boolean m_editing;
private VisualItem m_editItem;
private String m_editAttribute;
/**
* Creates a new Display instance. You will need to associate this
* Display with a {@link Visualization} for it to display anything.
*/
public Display() {
this(null);
}
/**
* Creates a new Display associated with the given Visualization.
* By default, all {@link prefuse.visual.VisualItem} instances in the
* {@link Visualization} will be drawn by the Display.
* @param visualization the {@link Visualization} backing this Display
*/
public Display(Visualization visualization) {
this(visualization, (Predicate)null);
}
/**
* Creates a new Display associated with the given Visualization that
* draws all VisualItems in the visualization that pass the given
* Predicate. The predicate string will be parsed by the
* {@link prefuse.data.expression.parser.ExpressionParser} to get a
* {@link prefuse.data.expression.Predicate} instance.
* @param visualization the {@link Visualization} backing this Display
* @param predicate a predicate expression in the prefuse expression
* language. This expression will be parsed; if the parsing fails or does
* not result in a Predicate instance, an exception will result.
*/
public Display(Visualization visualization, String predicate) {
this(visualization,
(Predicate)ExpressionParser.parse(predicate, true));
}
/**
* Creates a new Display associated with the given Visualization that
* draws all VisualItems in the visualization that pass the given
* Predicate.
* @param visualization the {@link Visualization} backing this Display
* @param predicate the filtering {@link prefuse.data.expression.Predicate}
*/
public Display(Visualization visualization, Predicate predicate) {
setDoubleBuffered(false);
setBackground(Color.WHITE);
// initialize text editor
m_editing = false;
m_editor = new JTextField();
m_editor.setBorder(null);
m_editor.setVisible(false);
this.add(m_editor);
// register input event capturer
InputEventCapturer iec = new InputEventCapturer();
addMouseListener(iec);
addMouseMotionListener(iec);
addMouseWheelListener(iec);
addKeyListener(iec);
registerDefaultCommands();
// invalidate the display when the filter changes
m_predicate.addExpressionListener(new UpdateListener() {
public void update(Object src) { damageReport(); }
});
setVisualization(visualization);
setPredicate(predicate);
setSize(400,400); // set a default size
}
/**
* Resets the display by clearing the offscreen buffer and flushing the
* internal rendering queue. This method can help reclaim memory when a
* Display is not visible.
*/
public void reset() {
m_offscreen = null;
m_queue.clean();
}
/**
* Registers default keystroke commands on the Display. The default
* commands are
* <ul><li><b>ctrl D</b> - Toggle debug info display</li>
* <li><b>ctrl H</b> - Toggle high quality rendering</li>
* <li><b>ctrl E</b> - Export display view to an image file</li></ul>
* Subclasses can override this method to prevent these commands from
* being set. Additional commands can be registered using the
* <code>registerKeyboardAction</code> method.
*/
protected void registerDefaultCommands() {
// add debugging output control
registerKeyboardAction(new ActionListener() {
private PaintListener m_debug = null;
public void actionPerformed(ActionEvent e) {
if (m_debug == null) {
m_debug = new DebugStatsPainter();
addPaintListener(m_debug);
} else {
removePaintListener(m_debug);
m_debug = null;
}
repaint();
}
}, "debug info", KeyStroke.getKeyStroke("ctrl D"), WHEN_FOCUSED);
// add quality toggle
registerKeyboardAction(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setHighQuality(!isHighQuality());
repaint();
}
}, "toggle high-quality drawing", KeyStroke.getKeyStroke("ctrl H"),
WHEN_FOCUSED);
// add image output control, if this is not an applet
try {
registerKeyboardAction(new ExportDisplayAction(this),
"export display", KeyStroke.getKeyStroke("ctrl E"), WHEN_FOCUSED);
} catch (SecurityException se) {
}
}
/**
* Set the size of the Display.
* @param width the width of the Display in pixels
* @param height the height of the Display in pixels
* @see java.awt.Component#setSize(int, int)
*/
public void setSize(int width, int height) {
m_offscreen = null;
setPreferredSize(new Dimension(width, height));
super.setSize(width, height);
}
/**
* Set the size of the Display.
* @param d the dimensions of the Display in pixels
* @see java.awt.Component#setSize(java.awt.Dimension)
*/
public void setSize(Dimension d) {
m_offscreen = null;
setPreferredSize(d);
super.setSize(d);
}
/**
* Invalidates this component. Overridden to ensure that an
* internal damage report is generated.
* @see java.awt.Component#invalidate()
*/
public void invalidate() {
damageReport();
super.invalidate();
}
/**
* @see java.awt.Component#setBounds(int, int, int, int)
*/
public void setBounds(int x, int y, int w, int h) {
m_offscreen = null;
super.setBounds(x,y,w,h);
}
/**
* Sets the font used by this Display. This determines the font used
* by this Display's text editor and in any debugging text.
* @param f the Font to use
*/
public void setFont(Font f) {
super.setFont(f);
m_editor.setFont(f);
}
/**
* Returns the running average frame rate for this Display.
* @return the frame rate
*/
public double getFrameRate() {
return frameRate;
}
/**
* Determines if the Display uses a higher quality rendering, using
* anti-aliasing. This causes drawing to be much slower, however, and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -