1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
| /*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package test;
import java.text.MessageFormat;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.geometry.VPos;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.scene.layout.RegionBuilder;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
import javafx.scene.transform.Rotate;
/**
* @author fabriceb
*/
public class VolumeButton extends Region {
private Region knob = RegionBuilder.create().id("knob").build(); // NOI18N.
private final double minAngle = -20;
private final double maxAngle = 200;
private Rotate rotate = new Rotate();
private Line currentLine = new Line();
private Line minLine = new Line();
private Line maxLine = new Line();
private Text text = new Text();
public VolumeButton() {
super();
getStyleClass().add("volume-button"); // NOI18N.
knob.setPrefSize(75, 75);
knob.getStyleClass().add("knob"); // NOI18N.
knob.getTransforms().add(rotate);
setOnMouseMoved(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
double x = event.getX();
double y = event.getY();
double centerX = getWidth() / 2.0;
double centerY = getHeight() / 2.0;
currentLine.setStartX(centerX);
currentLine.setStartY(centerY);
currentLine.setEndX(x);
currentLine.setEndY(y);
}
});
setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
double x = event.getX();
double y = event.getY();
double centerX = getWidth() / 2.0;
double centerY = getHeight() / 2.0;
currentLine.setStartX(centerX);
currentLine.setStartY(centerY);
currentLine.setEndX(x);
currentLine.setEndY(y);
double theta = Math.atan2((y - centerY), (x - centerX));
double angle = Math.toDegrees(theta);
if (angle > 0.0) {
angle = 180 + (180 - angle);
} else {
angle = 180 - (180 - Math.abs(angle));
}
if (angle >= 270) {
angle = angle - 360;
}
double value = angleToValue(angle);
text.setText(MessageFormat.format("{0}\n{1}", angle, value));
setValue(value);
}
});
minLine.setStroke(Color.GREEN);
maxLine.setStroke(Color.BLUE);
text.setTextOrigin(VPos.TOP);
getChildren().addAll(minLine, maxLine);
getChildren().add(knob);
getChildren().addAll(currentLine, text);
setPrefSize(100, 100);
valueProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
requestLayout();
}
});
minProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
requestLayout();
}
});
maxProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
requestLayout();
}
});
}
/**
* {@inheritDoc}
*/
@Override
protected void layoutChildren() {
super.layoutChildren();
double centerX = getWidth() / 2.0;
double centerY = getHeight() / 2.0;
currentLine.setStartX(centerX);
currentLine.setStartY(centerY);
minLine.setStartX(centerX);
minLine.setStartY(centerY);
minLine.setEndX(centerX + 90 * Math.cos(Math.toRadians(-minAngle)));
minLine.setEndY(centerY + 90 * Math.sin(Math.toRadians(-minAngle)));
maxLine.setStartX(centerX);
maxLine.setStartY(centerY);
maxLine.setEndX(centerX + 90 * Math.cos(Math.toRadians(-maxAngle)));
maxLine.setEndY(centerY + 90 * Math.sin(Math.toRadians(-maxAngle)));
double knobX = (getWidth() - knob.getPrefWidth()) / 2.0;
double knobY = (getHeight() - knob.getPrefHeight()) / 2.0;
knob.setLayoutX(knobX);
knob.setLayoutY(knobY);
double value = getValue();
double angle = valueToAngle(getValue());
if (minAngle <= angle && angle <= maxAngle) {
rotate.setPivotX(knob.getWidth() / 2.0);
rotate.setPivotY(knob.getHeight() / 2.0);
rotate.setAngle(-angle);
}
}
double valueToAngle(double value) {
double maxValue = getMax();
double minValue = getMin();
double angle = minAngle + (maxAngle - minAngle) * (value - minValue) / (maxValue - minValue);
System.out.printf("valueToAngle %f => %f", value, angle).println();
return angle;
}
double angleToValue(double angle) {
double maxValue = getMax();
double minValue = getMin();
double value = minValue + (maxValue - minValue) * (angle - minAngle) / (maxAngle - minAngle);
value = Math.max(minValue, value);
value = Math.min(maxValue, value);
System.out.printf("angleToValue %f => %f", angle, value).println();
return value;
}
//
private final DoubleProperty value = new SimpleDoubleProperty(this, "value", 0); // NOI18N.
public final void setValue(double v) {
value.set(v);
}
public final double getValue() {
return value.get();
}
public final DoubleProperty valueProperty() {
return value;
}
private final DoubleProperty min = new SimpleDoubleProperty(this, "min", 0); // NOI18N.
public final void setMin(double v) {
min.set(v);
}
public final double getMin() {
return min.get();
}
public final DoubleProperty minProperty() {
return min;
}
private final DoubleProperty max = new SimpleDoubleProperty(this, "max", 100); // NOI18N.
public final void setMax(double v) {
max.set(v);
}
public final double getMax() {
return max.get();
}
public final DoubleProperty maxProperty() {
return max;
}
} |
Partager