📄 basicparalleldisplayui.java
字号:
/*Copyright (c) 2001, 2002, 2003 Flo Ledermann <flo@subnet.at>This file is part of parvis - a parallel coordiante based data visualisationtool written in java. You find parvis and additional information on itswebsite at http://www.mediavirus.org/parvis.parvis is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.parvis is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with parvis (in the file LICENSE.txt); if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/package org.mediavirus.parvis.gui;import org.mediavirus.parvis.model.*;import java.awt.*;import java.awt.image.*;import java.awt.event.*;import java.awt.geom.*;import javax.swing.*;import javax.swing.plaf.*;import javax.swing.border.*;import java.util.*;/** * The UI Delegate, responsible for rendering the ParallelDisplay component. * * @author Flo Ledermann flo@subnet.at * @version 0.1 */public class BasicParallelDisplayUI extends ParallelDisplayUI implements MouseListener, MouseMotionListener { int numDimensions; int numRecords; int stepx; int hoverAxis = -1; int hoverRecord = -1; float axisScale[]; int borderH = 20; int borderV = 40; int width = 0, height = 0; String metaText = null; int metaX = 0, metaY = 0; boolean dragAxis = false; int dragX = 0; BufferedImage bufferImg = null; BufferedImage brushImg = null; boolean needsDeepRepaint = true; boolean renderQuality = false; int brushHoverStart = 0; int brushHoverEnd = 0; int brushHoverX = 0; boolean inBrush = false; Brush tempBrush = null; Brush dragBrush = null; /** * Default Constructor. Creates a new BasicParallelDisplayUI. */ public BasicParallelDisplayUI() { } /** * Swing method. Returns a new instance. */ public static ComponentUI createUI(JComponent c){ return new BasicParallelDisplayUI(); } /** * Installs this instance as UI delegate for the given component. * * @param c The component, a ParallelDisplay in our case. */ public void installUI(JComponent c){ ParallelDisplay pd = (ParallelDisplay)c; pd.addMouseListener(this); pd.addMouseMotionListener(this); } /** * Uninstalls this instance from its component. * * @param c The component, a ParallelDisplay in our case. */ public void uninstallUI(JComponent c){ ParallelDisplay pd = (ParallelDisplay)c; pd.removeMouseListener(this); pd.removeMouseMotionListener(this); numDimensions = 0; numRecords = 0; } /** RenderThread instance to render the dataset. */ RenderThread renderThread = null; /** RenderThread instance to render the brushed records. */ RenderThread brushThread = null; /** * Renders the component on the screen. * * @param g The graphics object to draw on. * @param c The Component, our ParallelDisplay. */ public void paint(Graphics g, JComponent c){ ParallelDisplay comp = (ParallelDisplay)c; //start our renderThread if (renderThread == null){ renderThread = new RenderThread(this); renderThread.setQuality(false, true); renderThread.setStyle(new BasicStroke(0.5f), comp.getColorPreference("recordColor")); renderThread.start(); } if (brushThread == null){ brushThread = new RenderThread(this); brushThread.setQuality(false, true); brushThread.setStyle(new BasicStroke(1.5f), comp.getColorPreference("brushColor")); brushThread.start(); } // set up the environment Graphics2D g2 = (Graphics2D)g; RenderingHints qualityHints = new RenderingHints(null); qualityHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); qualityHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2.setRenderingHints(qualityHints); //workaround flag for model change, resize,... if (comp.deepRepaint){ // throw away buffered image -> complete repaint width = c.getWidth() - 2*borderH; height = c.getHeight() - 2*borderV; numDimensions = comp.getNumAxes(); numRecords = comp.getNumRecords(); stepx = width / (numDimensions - 1); System.out.println("Setting numDimensions to " + numDimensions); needsDeepRepaint = true; bufferImg = new BufferedImage(c.getWidth(), c.getHeight(), BufferedImage.TYPE_3BYTE_BGR); Graphics2D ig = bufferImg.createGraphics(); ig.setColor(c.getBackground()); ig.fillRect(0,0,c.getWidth(),c.getHeight()); //brushImg = null; renderThread.reset(); brushThread.reset(); renderThread.setCurrentComponent(comp); brushThread.setCurrentComponent(comp); brushThread.setBrush(comp.getCurrentBrush()); if (comp.getCurrentBrush() == null) { brushImg = null; } else { renderBrush(); } renderAll(); comp.deepRepaint = false; } else if (comp.brushChanged){ if (!tempBrushSwap){ brushImg = null; brushThread.reset(); brushThread.setBrush(comp.getCurrentBrush()); renderBrush(); } else { //we just came from interactive brushing -> no need for re-rendering tempBrushSwap = false; } comp.brushChanged = false; } g2.setColor(c.getBackground()); g2.fillRect(0, 0, comp.getWidth(), comp.getHeight()); g2.translate(borderH, borderV); // save rendered image in new buffer if (renderThread.getRenderedImage() != null){ // we cant do this becase the renderedImage is only a part of the whole // bufferImg = (BufferedImage)renderThread.getRenderedImage(); Graphics2D ig = bufferImg.createGraphics(); ig.setColor(comp.getBackground()); int startAxis = renderThread.getRenderedRegionStart(); int stopAxis = renderThread.getRenderedRegionStop(); //delete area that has been rendered ig.fillRect( startAxis * stepx, 0, (stopAxis - startAxis) * stepx, comp.getHeight()); //and paint it new ig.drawImage(renderThread.getRenderedImage(), 0, 0, comp); } if (brushThread.getRenderedImage() != null){ brushImg = brushThread.getRenderedImage(); } if ((comp.getCurrentBrush() == null) && (brushImg != null) && (!inBrush)){ brushImg = null; } if ((comp.getCurrentBrush() == null) && (!inBrush)){ synchronized (bufferImg){ g2.drawImage(bufferImg, 0, 0, comp); } } else { Composite oldcomp = g2.getComposite(); AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.15f); g2.setComposite(ac); g2.drawImage(bufferImg, 0, 0, comp); g2.setComposite(oldcomp); if (brushImg != null){ g2.drawImage(brushImg, 0, 0, comp); } } // set up g2.setColor(comp.getForeground()); g2.setStroke(new BasicStroke(1.0f)); //draw all the dynamic parts on the screen: //axis labels for (int i=0; i<numDimensions; i++){ float curx = i*stepx; //hovering over Axis if (i==hoverAxis){ g2.setStroke(new BasicStroke(1.5f)); g2.draw(new Line2D.Float(curx, 0, curx, height)); g2.setStroke(new BasicStroke(1.0f)); } else { g2.draw(new Line2D.Float(curx, 0, curx, height)); } String label = comp.getAxisLabel(i); if (label != null) { g2.drawString(label, curx - 10, height + 30); } g2.drawString("" + comp.getAxisOffset(i), curx + 2, borderV / 2 - 22); g2.drawString("" + (comp.getAxisOffset(i) + comp.getAxisScale(i)), curx + 2, height + borderV / 2 - 5); drawArrow(g2, (int)curx, -20, 8, false, (comp.getAxisScale(i) < 0)); } //brush Hover if (inBrush) { g2.setColor(new Color(0.7f, 0.0f, 0.0f)); g2.setStroke(new BasicStroke(2.5f)); g2.draw(new Line2D.Float(brushHoverX, brushHoverStart, brushHoverX, brushHoverEnd)); } //angular brushing if (inAngularBrush){ if (angularPhase1){ int startx, endx, starty, endy; if (angularCurX != angularRefX) { //avoid div. by zero startx = angularRegion * stepx; endx = (angularRegion + 1) * stepx; starty = (int)(angularRefY - (angularRefX - (float)startx) / ((float)(angularCurX - angularRefX)) * (angularCurY - (float)angularRefY)); endy = (int)(angularCurY + (endx - (float)angularCurX) / ((float)(angularCurX - angularRefX)) * (angularCurY - (float)angularRefY)); } else { startx = angularCurX; endx = angularCurX; starty = 0-borderV; endy = height+borderV; } g2.setColor(comp.getForeground()); g2.setStroke(new BasicStroke(1.0f)); g2.drawLine(startx, starty, endx, endy); g2.drawRect(angularRefX - 2, angularRefY - 2, 4, 4); g2.drawRect(angularCurX - 2, angularCurY - 2, 4, 4); } else { int startx, endx, starty, endy; if (angularStartX != angularRefX) { //avoid div. by zero startx = angularRegion * stepx; endx = (angularRegion + 1) * stepx; starty = (int)(angularRefY - (angularRefX - (float)startx) / ((float)(angularStartX - angularRefX)) * (angularStartY - (float)angularRefY)); endy = (int)(angularStartY + (endx - (float)angularStartX) / ((float)(angularStartX - angularRefX)) * (angularStartY - (float)angularRefY)); } else { startx = angularStartX; endx = angularStartX; starty = 0-borderV; endy = height+borderV; } g2.setColor(comp.getForeground()); g2.setStroke(new BasicStroke(1.0f)); g2.drawLine(startx, starty, endx, endy); if (angularCurX != angularRefX) { //avoid div. by zero startx = angularRegion * stepx; endx = (angularRegion + 1) * stepx; starty = (int)(angularRefY - (angularRefX - (float)startx) / ((float)(angularCurX - angularRefX)) * (angularCurY - (float)angularRefY)); endy = (int)(angularCurY + (endx - (float)angularCurX) / ((float)(angularCurX - angularRefX)) * (angularCurY - (float)angularRefY)); } else { startx = angularCurX; endx = angularCurX; starty = 0-borderV; endy = height+borderV; } g2.drawLine(startx, starty, endx, endy); g2.drawRect(angularRefX - 2, angularRefY - 2, 4, 4); g2.drawRect(angularStartX - 2, angularStartY - 2, 4, 4); g2.drawRect(angularCurX - 2, angularCurY - 2, 4, 4); Color tc = comp.getForeground(); g2.setColor(new Color(tc.getRed(), tc.getGreen(), tc.getBlue(), 50)); g2.fillArc(angularRefX - 50, angularRefY - 50, 100, 100, (int)(angularAngle1*180.0f/Math.PI), (int)((angularAngle2 - angularAngle1)*180.0f/Math.PI)); } } //axis histograms if (comp.getBoolPreference("histogram")) { int bins = comp.getIntPreference("histogramBins"); float stepy = (float)height / bins; g2.setStroke(new BasicStroke(1.0f)); for (int i=0; i<numDimensions; i++){ float curx = i*stepx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -