JDiagram panning and scrolling (fixes #1)
parent
1753db1ef9
commit
f38b9ce93a
|
@ -5,11 +5,24 @@ import java.awt.Dimension;
|
|||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import javax.swing.BoundedRangeModel;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import org.hwo.ui.diagram.DiagramListener;
|
||||
import org.hwo.ui.diagram.DiagramViewEvent;
|
||||
import org.hwo.ui.diagram.LinePlotPainter;
|
||||
import org.hwo.ui.diagram.LinearScaler;
|
||||
import org.hwo.ui.diagram.PlotLabeler;
|
||||
|
@ -20,7 +33,12 @@ import org.hwo.ui.diagram.Scaler;
|
|||
import org.hwo.ui.diagram.SimplePlotLabeler;
|
||||
import org.hwo.ui.diagram.SimplePlotProvider;
|
||||
|
||||
public class JDiagram extends JComponent implements PlotProviderListener {
|
||||
public class JDiagram extends JComponent implements PlotProviderListener, BoundedRangeModel {
|
||||
|
||||
private enum DDragMode { NONE, PAN }
|
||||
|
||||
private LinkedList<DiagramListener> diagramListeners = new LinkedList<>();
|
||||
private LinkedList<ChangeListener> changeListeners = new LinkedList<>();
|
||||
|
||||
private PlotProvider2
|
||||
plotProvider;
|
||||
|
@ -49,7 +67,6 @@ public class JDiagram extends JComponent implements PlotProviderListener {
|
|||
plotWidth;
|
||||
|
||||
private double abszissMinimum,
|
||||
abszissMaximum,
|
||||
abszissWindow;
|
||||
|
||||
|
||||
|
@ -74,7 +91,15 @@ public class JDiagram extends JComponent implements PlotProviderListener {
|
|||
|
||||
private Integer selectedPlot;
|
||||
|
||||
|
||||
private DDragMode dragMode;
|
||||
private Point2D dragPoint;
|
||||
private Point dragMousePoint;
|
||||
|
||||
private double dragPanStart;
|
||||
|
||||
private double mouseWheelZoom = 1.03;
|
||||
|
||||
|
||||
public JDiagram(){
|
||||
setMinimumSize(new Dimension(80, 80));
|
||||
setDoubleBuffered(true);
|
||||
|
@ -93,10 +118,95 @@ public class JDiagram extends JComponent implements PlotProviderListener {
|
|||
drawHorizontalGrid = true;
|
||||
|
||||
verticalGridColor = new Color(192, 192, 192);
|
||||
setBackground(Color.black);
|
||||
setForeground(Color.WHITE);
|
||||
|
||||
setPlotProvider(new SimplePlotProvider(1, 0));
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
switch (e.getButton()) {
|
||||
case MouseEvent.BUTTON2:
|
||||
dragMode = DDragMode.PAN;
|
||||
dragMousePoint = e.getPoint();
|
||||
dragPoint = mapMouseToDiagram(dragMousePoint);
|
||||
dragPanStart = getAbszissMinimum();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
dragMode = DDragMode.NONE;
|
||||
}
|
||||
});
|
||||
|
||||
addMouseMotionListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
Point2D p = mapMouseToDiagram(dragMousePoint);
|
||||
Point2D np = mapMouseToDiagram(e.getPoint());
|
||||
double dx = np.getX() - p.getX();
|
||||
|
||||
switch (dragMode) {
|
||||
case PAN:
|
||||
double nmin = dragPanStart - dx;
|
||||
|
||||
nmin = limitAbszissMinimum(nmin);
|
||||
|
||||
setAbszissMinimum(nmin);
|
||||
repaint();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addMouseWheelListener(new MouseWheelListener() {
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
|
||||
double newwindow = getAbszissWindow() * Math.pow(mouseWheelZoom,e.getPreciseWheelRotation());
|
||||
Point2D mp = mapMouseToDiagram(e.getPoint());
|
||||
|
||||
double pmin = plotProvider.getPositionMinimum();
|
||||
double pmax = plotProvider.getPositionMaximum();
|
||||
|
||||
double maxwindow = pmax - pmin;
|
||||
|
||||
newwindow = newwindow > maxwindow ? maxwindow : newwindow;
|
||||
|
||||
setAbszissWindow(newwindow);
|
||||
|
||||
Point2D mp2 = mapMouseToDiagram(e.getPoint());
|
||||
double nmin = getAbszissMinimum() + mp.getX() - mp2.getX();
|
||||
|
||||
nmin = limitAbszissMinimum(nmin);
|
||||
setAbszissMinimum( nmin );
|
||||
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void fireViewWindowChanged(){
|
||||
for (DiagramListener l: diagramListeners) {
|
||||
l.ViewWindowChanged(new DiagramViewEvent(this));
|
||||
}
|
||||
for (ChangeListener l: changeListeners) {
|
||||
l.stateChanged(new ChangeEvent(this));
|
||||
}
|
||||
}
|
||||
|
||||
public void addDiagramListener(DiagramListener l) {
|
||||
this.diagramListeners.add(l);
|
||||
}
|
||||
public void removeDiagramListener(DiagramListener l) {
|
||||
this.diagramListeners.remove(l);
|
||||
}
|
||||
|
||||
public void setPlotProvider(PlotProvider2 plotProvider) {
|
||||
if (this.plotProvider != null)
|
||||
this.plotProvider.removePlotProviderListener(this);
|
||||
|
@ -415,9 +525,10 @@ public class JDiagram extends JComponent implements PlotProviderListener {
|
|||
nMarker = plotWidth / (w*8/7);
|
||||
}
|
||||
|
||||
abszissMinimum = this.plotProvider.getPositionMinimum();
|
||||
abszissMaximum = this.plotProvider.getPositionMaximum();
|
||||
abszissWindow = abszissMaximum - abszissMinimum;
|
||||
// TODO change for zoom
|
||||
//abszissMinimum = this.plotProvider.getPositionMinimum();
|
||||
//abszissMaximum = this.plotProvider.getPositionMaximum();
|
||||
//abszissWindow = abszissMaximum - abszissMinimum;
|
||||
|
||||
g.setColor(getForeground());
|
||||
|
||||
|
@ -464,6 +575,8 @@ public class JDiagram extends JComponent implements PlotProviderListener {
|
|||
Color graphColor;
|
||||
Color[] graphColors = this.plotProvider.getColors();
|
||||
|
||||
double amax = this.getAbszissMaximum();
|
||||
|
||||
for (int graph=0; graph < this.plotProvider.getNumGraphs(); graph++){
|
||||
boolean isSelected = ((selectedPlot != null) && selectedPlot.equals(graph));
|
||||
|
||||
|
@ -483,19 +596,110 @@ public class JDiagram extends JComponent implements PlotProviderListener {
|
|||
Float value = this.plotProvider.getValue(n, graph);
|
||||
Float position = this.plotProvider.getPosition(n, graph);
|
||||
|
||||
if ((value != null) && (position != null) )
|
||||
if ((value != null) && (position != null) && (position >= this.abszissMinimum) && (position <= amax))
|
||||
{
|
||||
x = getWidth() - bRight - plotWidth + (int)((position - abszissMinimum) * plotWidth / abszissWindow);
|
||||
y = bTop + plotHeight - this.ordinateViews[ ordinate ].scaler.getPosition(value);
|
||||
|
||||
this.plotPainters[ graph ].paintPoint(g, graphColor, x, y, isSelected);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Pan and Zoom
|
||||
*/
|
||||
|
||||
public double getAbszissWindow() {
|
||||
return this.abszissWindow;
|
||||
}
|
||||
|
||||
public void setAbszissWindow(double width){
|
||||
setAbszissWindow(width, true);
|
||||
}
|
||||
private void setAbszissWindow(double width,boolean fireEvent){
|
||||
this.abszissWindow = width;
|
||||
if (fireEvent) {
|
||||
fireViewWindowChanged();
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
public double getAbszissMinimum() {
|
||||
return this.abszissMinimum;
|
||||
}
|
||||
public void setAbszissMinimum(double x) {
|
||||
this.abszissMinimum = x;
|
||||
fireViewWindowChanged();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public double getAbszissMaximum() {
|
||||
return this.abszissMinimum + this.abszissWindow;
|
||||
}
|
||||
public void setAbszissMaximum(double x) {
|
||||
this.abszissWindow = x - this.abszissMinimum;
|
||||
fireViewWindowChanged();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public double getMouseWheelZoom() {
|
||||
return mouseWheelZoom;
|
||||
}
|
||||
public void setMouseWheelZoom(double mouseWheelZoom) {
|
||||
this.mouseWheelZoom = mouseWheelZoom;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tool methods
|
||||
*/
|
||||
|
||||
public Point2D mapMouseToDiagram(Point p) {
|
||||
return this.mapMouseToDiagram(p,0);
|
||||
}
|
||||
public Point2D mapMouseToDiagram(Point p,int ordinate) {
|
||||
double x,y;
|
||||
|
||||
int xl = (getWidth() - bRight - plotWidth);
|
||||
|
||||
|
||||
x = this.abszissMinimum + (((p.getX() - xl) / plotWidth) * this.abszissWindow);
|
||||
// TODO implement reverse mapping into scaler interface ??!!
|
||||
y = this.ordinateViews[ ordinate ].scaler.getMinValue() - ((p.getY() - bTop - plotHeight) / plotHeight * this.ordinateViews[ ordinate ].scaler.getWindow());
|
||||
|
||||
return new Point2D.Double(x, y);
|
||||
}
|
||||
|
||||
public Point mapDiagramToMouse(Point2D p){
|
||||
return mapDiagramToMouse(p, 0);
|
||||
}
|
||||
public Point mapDiagramToMouse(Point2D p,int ordinate) {
|
||||
int x,y;
|
||||
|
||||
x = getWidth() - bRight - plotWidth + (int)((p.getX() - abszissMinimum) * plotWidth / abszissWindow);
|
||||
y = bTop + plotHeight - this.ordinateViews[ ordinate ].scaler.getPosition(p.getY());
|
||||
|
||||
return new Point(x, y);
|
||||
}
|
||||
|
||||
public double limitAbszissMinimum(double nmin) {
|
||||
double pmin,pmax;
|
||||
|
||||
pmin = plotProvider.getPositionMinimum();
|
||||
pmax = plotProvider.getPositionMaximum();
|
||||
|
||||
nmin = nmin < pmin ? pmin : nmin;
|
||||
nmin = (nmin + getAbszissWindow()) > pmax ? pmax - getAbszissWindow() : nmin;
|
||||
|
||||
return nmin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class OrdinateView {
|
||||
|
||||
|
@ -533,4 +737,69 @@ public class JDiagram extends JComponent implements PlotProviderListener {
|
|||
fundamentalsChanged();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinimum() {
|
||||
return (int)(plotProvider.getPositionMinimum() * 1000.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinimum(int newMinimum) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaximum() {
|
||||
return (int)(plotProvider.getPositionMaximum() * 1000.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaximum(int newMaximum) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getValue() {
|
||||
return (int)(getAbszissMinimum() * 1000.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(int newValue) {
|
||||
setAbszissMinimum( ((double)newValue / 1000.0f) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueIsAdjusting(boolean b) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getValueIsAdjusting() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExtent() {
|
||||
return (int)(getAbszissWindow() * 1000.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtent(int newExtent) {
|
||||
setAbszissWindow( ((double)newExtent / 1000.0f) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRangeProperties(int value, int extent, int min, int max, boolean adjusting) {
|
||||
setMinimum(min);
|
||||
setMaximum(max);
|
||||
setExtent(extent);
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChangeListener(ChangeListener x) {
|
||||
this.changeListeners.add(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeChangeListener(ChangeListener x) {
|
||||
this.changeListeners.remove(x);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package org.hwo.ui.diagram;
|
||||
|
||||
public interface DiagramListener {
|
||||
|
||||
void ViewWindowChanged(DiagramViewEvent e);
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.hwo.ui.diagram;
|
||||
|
||||
import org.hwo.ui.JDiagram;
|
||||
|
||||
public class DiagramViewEvent {
|
||||
|
||||
private JDiagram diagram;
|
||||
|
||||
public DiagramViewEvent(JDiagram d) {
|
||||
this.diagram = d;
|
||||
}
|
||||
|
||||
public JDiagram getDiagram() {
|
||||
return diagram;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue