/* * ValueModelSlider.java * * * Copyright 2006-2018 James F. Bowring, CIRDLES.org, and Earth-Time.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.earthtime.UPb_Redux.beans; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; import javax.swing.JPanel; import org.earthtime.UPb_Redux.ReduxConstants; import org.earthtime.UPb_Redux.valueModels.ValueModel; /** * * @author James F. Bowring */ public final class ValueModelValueSlider extends JPanel implements // June 2017 modified to use adapter class //MouseListener, //MouseMotionListener, /*Serializable,*/ ValueModelSliderI { /** * */ public static final String VALUE_PROPERTY = "value"; private BigDecimal valueProperty; private PropertyChangeSupport propertySupport; private final JPanel valueModelSliderBox; private final int leftX; private final int topY; private final int width; private int height; private String units; private ValueModel valueModel; private ValueModel valueModelSavedCopy; private BigDecimal currentValue; private int sigDigits; private BigDecimal pixelSlideRange; private int lastX; private int nextX; private boolean mouseInsideValueModelSliderBox; /** * * @param leftX * @param topY * @param width * @param height * @param valueModel * @param units * @param kwikiListener */ @SuppressWarnings("LeakingThisInConstructor") public ValueModelValueSlider( int leftX, int topY, int width, int height, ValueModel valueModel, String units, PropertyChangeListener kwikiListener) { this.leftX = leftX; this.topY = topY; sigDigits = 4; this.width = width; this.height = height; this.valueModel = valueModel; valueModelSavedCopy = valueModel.copy(); this.units = units; currentValue = valueModel.getValue(); propertySupport = new PropertyChangeSupport(this); addPropertyChangeListener(kwikiListener); this.valueProperty = currentValue;// oct 2010 setValueProperty(currentValue); setOpaque(true); setBackground(Color.white); // June 2017 modified to use adapter class addMouseListener(new myMouseAdapter()); addMouseMotionListener(new myMouseAdapter()); // addMouseListener(this); // addMouseMotionListener(this); setBounds(leftX, topY, width, height); valueModelSliderBox = // new ValueModelSliderBox(// width, height - 3, getCurrentValueShowValue()); lastX = 0; nextX = 0; BigDecimal fourSigma = new BigDecimal("4.0").// multiply(valueModel.getOneSigmaAbs()); pixelSlideRange = new BigDecimal(Math.abs(fourSigma.doubleValue())/* added abs July 2011 for tripoli alphas*/ / ((width - valueModelSliderBox.getWidth()) / 2)); } private String getCurrentValueShowValue() { // System.out.println(currentValue); // return ValueModel.formatBigDecimalForPublicationSigDigMode(// // new BigDecimal( currentValue.doubleValue(), ReduxConstants.mathContextSlider ).// // movePointRight( ReduxConstants.getUnitConversionMoveCount( units ) ), sigDigits ); // // Sept 2012 simplification String formattedString = ""; if (currentValue.movePointRight(ReduxConstants.getUnitConversionMoveCount(units)).abs().compareTo(new BigDecimal(10e3)) > 0) { DecimalFormat formatterForBigNumbers = new DecimalFormat("0.00E00"); formattedString = formatterForBigNumbers.format(currentValue.movePointRight(ReduxConstants.getUnitConversionMoveCount(units)).doubleValue()); } else { formattedString = currentValue.movePointRight(ReduxConstants.getUnitConversionMoveCount(units)).setScale(sigDigits, RoundingMode.HALF_UP).toEngineeringString(); } return formattedString; } /** * * @param g */ @Override protected void paintComponent(Graphics g) { super.paintComponent(g); paint((Graphics2D) g); } /** * * @param g2d */ public void paint(Graphics2D g2d) { // show all values, even zero RenderingHints rh = g2d.getRenderingHints(); rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2d.setRenderingHints(rh); g2d.setColor(Color.black); DrawBounds(g2d); g2d.setColor(Color.red); g2d.drawLine((width / 2), 0, (width / 2), height); ((ValueModelSliderBox) valueModelSliderBox).// setValueString(getCurrentValueShowValue()); ((ValueModelSliderBox) valueModelSliderBox).paint(g2d); } private void DrawBounds(Graphics2D g2d) { g2d.drawRect(0, 0, width - 1, height - 1); } /** * * @param evt * @return */ public boolean mouseInsideValueModelSliderBox(MouseEvent evt) { // this is not very sensitive return (evt.getX() >= valueModelSliderBox.getX()) && (evt.getX() <= (valueModelSliderBox.getX() + valueModelSliderBox.getWidth())); } /** * * @return */ public BigDecimal getValueProperty() { return valueProperty; } /** * * @param value */ public void setValueProperty(BigDecimal value) { BigDecimal oldValue = valueProperty; valueProperty = value; BigDecimal change; try { change = currentValue.// subtract(valueModelSavedCopy.getValue()).// divide(valueModelSavedCopy.getOneSigmaAbs(), ReduxConstants.mathContext15); } catch (Exception e) { change = BigDecimal.ZERO; } setToolTipText(// ValueModel.formatBigDecimalForPublicationSigDigMode(// currentValue, sigDigits) // + " (current) = " // + ValueModel.formatBigDecimalForPublicationSigDigMode(// valueModelSavedCopy.getValue(), sigDigits) // + " (orig) + " // + change.setScale(1, RoundingMode.HALF_UP).toPlainString()// + " sigma"); // change fraction's copy valueModel.setValue(value); propertySupport.firePropertyChange(VALUE_PROPERTY, oldValue, valueProperty); } /** * * @param listener */ @Override public void addPropertyChangeListener(PropertyChangeListener listener) { propertySupport.addPropertyChangeListener(listener); } /** * * @param listener */ @Override public void removePropertyChangeListener(PropertyChangeListener listener) { propertySupport.removePropertyChangeListener(listener); } /** * */ @Override public void resetSliderBox() { currentValue = valueModelSavedCopy.getValue(); setValueProperty(currentValue); ((ValueModelSliderBox) valueModelSliderBox).// centerSliderBox(ValueModel.// formatBigDecimalForPublicationSigDigMode(currentValue, sigDigits)); repaint(); valueModel.setValue(valueModelSavedCopy.getValue()); } public class myMouseAdapter extends MouseAdapter { /** * single click outside valuebox will reset valuebox to original value * * @param e */ @Override public void mouseClicked(MouseEvent e) { if (!mouseInsideValueModelSliderBox) { resetSliderBox(); } } /** * * @param e */ @Override public void mousePressed(MouseEvent e) { lastX = e.getX(); mouseInsideValueModelSliderBox = mouseInsideValueModelSliderBox(e); // System.out.println("PRESSED inside = " + mouseInsideValueModelSliderBox); } /** * * @param e */ @Override public void mouseReleased(MouseEvent e) { nextX = lastX;//e.getX(); if (mouseInsideValueModelSliderBox) { // recalculate fraction - fire property setValueProperty(currentValue); // june 2017 workaround for broken java 1.8 // mouseInsideValueModelSliderBox = false; } } /** * * @param e */ @Override public void mouseExited(MouseEvent e) { nextX = lastX;//e.getX(); if (mouseInsideValueModelSliderBox) { // recalculate fraction - fire property setValueProperty(currentValue); // june 2017 workaround for broken java 1.8 // mouseInsideValueModelSliderBox = false; } } /** * * @param e */ @Override public void mouseDragged(MouseEvent e) { nextX = e.getX(); //System.out.println("in at x = " + e.getX() + " lastx = " + lastX + " nextx = " + nextX); // System.out.println("DRAGGED inside = " + mouseInsideValueModelSliderBox); if (mouseInsideValueModelSliderBox) { // check for moving past limits of valueModelSlider int pos = valueModelSliderBox.getX() + (nextX - lastX); if ((pos + valueModelSliderBox.getWidth()) <= (getWidth() + 1) && (pos >= -1)) { valueModelSliderBox.setLocation(// pos, valueModelSliderBox.getY()); currentValue = // currentValue.// add(pixelSlideRange.// multiply(new BigDecimal(nextX - lastX))); lastX = nextX; repaint(); } } } } /** * @return the valueModelSavedCopy */ public ValueModel getValueModelSavedCopy() { return valueModelSavedCopy; } }