package view.panels; import model.Line; import model.Point; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.data.time.DateRange; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.util.ShapeUtilities; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.util.LinkedList; /** * Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden. * * @Author: Armin Wolf * @Email: a_wolf28@uni-muenster.de * @Date: 28.05.2017. */ public class DualityPanel extends JPanel { private LinkedList lines; private LinkedList points; private JFreeChart chart; private ChartPanel panel; private XYSeriesCollection dataset; private JScrollPane scrollPane; private double domainMin, domainMax; private double rangeMin, rangeMax; private ValueAxis domain; private ValueAxis range; private Double delta = 1d; private Boolean ctrlPressed = false; private Boolean shiftPressed = false; public DualityPanel() { super(); this.setPreferredSize(new Dimension(800, 800)); this.setMinimumSize(new Dimension(800, 800)); this.setLayout(new BorderLayout()); } public void setPrameters(LinkedList lines, LinkedList points, Double xmin, Double xmax, Double ymin, Double ymax) { this.lines = new LinkedList<>(lines); this.points = new LinkedList<>(points); this.domainMin = xmin; this.domainMax = xmax; this.rangeMin = ymin; this.rangeMax = ymax; } public void createArrangement() { dataset = new XYSeriesCollection(); for (Line p : lines) { XYSeries series = new XYSeries(p.getId() + "#" + p.getX1() + "---" + p.getY1()); series.add(p.getX1(), p.getY1()); series.add(p.getX2(), p.getY2()); dataset.addSeries(series); } XYSeries intersections = new XYSeries("intersections"); for (Point p : points) { intersections.add(p.getX(), p.getY()); } dataset.addSeries(intersections); chart = ChartFactory.createXYLineChart(null, null, null, dataset, PlotOrientation.HORIZONTAL, false, false, false); chart.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)); chart.setAntiAlias(true); final XYPlot plot = chart.getXYPlot(); domain = plot.getDomainAxis(); range = plot.getRangeAxis(); domain.setRange(domainMin - 1, domainMax + 1); range.setRange(rangeMin - 1, rangeMax + 1); plot.setBackgroundPaint(Color.WHITE); plot.setDomainGridlinePaint(Color.white); plot.setRangeGridlinePaint(Color.white); final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); renderer.setSeriesLinesVisible(dataset.indexOf(intersections), false); plot.setRenderer(renderer); for (int i = 0; i < lines.size(); i++) { // Setze die Shapes für die Schnittpunkte renderer.setSeriesPaint(i, Color.BLUE); renderer.setBaseSeriesVisible(true); } Shape shape = ShapeUtilities.createDiagonalCross(4, 1); renderer.setSeriesPaint(lines.size(), Color.BLACK); renderer.setSeriesShape(lines.size(), shape); panel = new ChartPanel(chart); panel.setPreferredSize(new Dimension(800, 800)); addKeyListener(this); addZooming(panel); this.setFocusable(true); JTextArea info = new JTextArea(); info.setText("Um in dem Plot hineinzuzoomen kann das Mausrad verwendett werden. \nUm sich anschließen vertikal bzw. horizontal zu bewegen kann die Kombination (Umschalt/Steuerung)\nund Mausrad verwendett werden."); Font font = new Font("Serif", Font.ITALIC, 12); info.setFont(font); info.setForeground(Color.DARK_GRAY); info.setEditable(false); info.setWrapStyleWord(true); this.add(info, BorderLayout.SOUTH); this.add(panel, BorderLayout.CENTER); } public void addKeyListener(JComponent component) { component.addKeyListener(new KeyListener() { @Override public void keyReleased(KeyEvent e) { ctrlPressed = false; shiftPressed = false; } @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { if (e.isControlDown()) { ctrlPressed = true; } if (e.isShiftDown()) { shiftPressed = true; } } }); } protected void addZooming(ChartPanel chartPanel) { chartPanel.addMouseWheelListener(new MouseWheelListener() { public void mouseWheelMoved(MouseWheelEvent e) { Double min; Double max; Double val = e.getPreciseWheelRotation() * -1; if (ctrlPressed == true) { //System.out.println("CTRL + ZOOM"); min = range.getLowerBound(); max = range.getUpperBound(); DateRange dateRangeX = move(val, min, max); range.setRange(dateRangeX); } else if (shiftPressed == true) { //System.out.println("SHIFT + ZOOM"); min = domain.getLowerBound(); max = domain.getUpperBound(); DateRange dateRangeY = move(val, min, max); domain.setRange(dateRangeY); } else { Double x = Double.valueOf(e.getY()); Double y = Double.valueOf(e.getY()); if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL) return; if (e.getWheelRotation() < 0) increaseZoom((ChartPanel) e.getComponent(), true, x, y); else decreaseZoom((ChartPanel) e.getComponent(), true, x, y); } } private DateRange move(Double val, Double min, Double max) { Double minimum = min; Double maximum = max; delta = Math.abs(maximum - minimum) * 0.01 * val; minimum = minimum + delta; maximum = maximum + delta; return new DateRange(minimum, maximum); } public synchronized void increaseZoom(JComponent chart, boolean saveAction, Double x, Double y) { ChartPanel ch = (ChartPanel) chart; zoomChartAxis(ch, true, x, y); } public synchronized void decreaseZoom(JComponent chart, boolean saveAction, Double x, Double y) { ChartPanel ch = (ChartPanel) chart; zoomChartAxis(ch, false, x, y); } private void zoomChartAxis(ChartPanel chartP, boolean increase, Double x, Double y) { int width = chartP.getMaximumDrawWidth() - chartP.getMinimumDrawWidth(); int height = chartP.getMaximumDrawHeight() - chartP.getMinimumDrawWidth(); if (increase) { chartP.zoomInBoth(width / 2, height / 2); } else { chartP.zoomOutBoth(width / 2, height / 2); } } }); } public void clear() { if (dataset != null) dataset.removeAllSeries(); } }