编辑:代码可用 github上(https://github.com/goxr3plus/DragAdjustableLabel)
问题
我在javaFX
制作了一个自定义控件,我不知道如何命名。它实际上并不存在于javaFX
包中,但我在其他程序中看到它,例如LMMS,它用于控制音量。
问题
当鼠标到达监视器屏幕的顶部或底部时,无法执行任何操作。看看代码,看看我在说什么。如何解决问题?您可以随意将标题编辑为更合适的标题。
import java.awt.Robot;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class FX3 extends Application {
@Override
public void start(Stage stage) throws Exception {
// Root-BorderPane
BorderPane borderPane = new BorderPane(new VolumeLabel(0, 100));
borderPane.setStyle("-fx-background-color:black;");
// Scene
stage.setScene(new Scene(borderPane, 200, 200, Color.BLACK));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
// TODO SpecialLabel
class VolumeLabel extends Label {
int screenX, screenY, previousY, minimumValue, maximumValue;
IntegerProperty currentValue = new SimpleIntegerProperty(15);
/**
* Constructor
*/
public VolumeLabel(int minimumValue, int maximumValue) {
this.minimumValue = minimumValue;
this.maximumValue = maximumValue;
textProperty().bind(currentValue.asString().concat(" %"));
setStyle(
"-fx-background-color:white; -fx-text-fill:black; -fx-padding:-2 8 -2 8; -fx-background-radius: 15; -fx-font-size:20; -fx-cursor:open-hand;");
// MouseListeners
setOnMousePressed(m -> {
screenX = (int) m.getScreenX();
screenY = (int) m.getScreenY();
//setCursor(Cursor.NONE); //Uncommend this line to make the cursor invisible
});
setOnMouseDragged(m -> {
setCurrentValue(
getCurrentValue() + (m.getScreenY() == previousY ? 0 : m.getScreenY() > previousY ? -1 : 1));
previousY = (int) m.getScreenY();
});
setOnMouseReleased(m -> {
// When the mouse is released -> move it to the initial position
try {
new Robot().mouseMove(screenX, screenY);
} catch (Exception e) {
e.printStackTrace();
}
setCursor(Cursor.OPEN_HAND);
});
}
/**
* Returns the Current Value of VolumeLabel
*
* @return
*/
public int getCurrentValue() {
return currentValue.get();
}
/**
* Setting the Current Value of VolumeLabel
*
* @param value
*/
public void setCurrentValue(int value) {
//System.out.println("Value:" + value + ", CurrentValue:" + currentValue.get());
if (value >= minimumValue && value <= maximumValue)
currentValue.set(value);
}
}
}
答案 0 :(得分:0)
以下是答案(代码也在github上):
import java.awt.Robot;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Cursor;
import javafx.scene.control.Label;
import javafx.stage.Screen;
/**
* A custom Node which is working like a Slider. <br>
* <b>!</b> When you hold the mouse on it and drag upside the value is
* increased. <br>
* <b>!</b> When you hold the mouse on it and drag down side the value is
* decreased.
*
* <br>
* Usage:
*
* <pre>
* <code>
* //initialize
* DragAdjustableLabel dragAdjustableLabel = new DragAdjustableLabel(10, 0, 100);
*
* //add it for example to a BorderPane
* primaryStage.setScene(new Scene(new BorderPane(dragAdjustableLabel)));
*</code>
* </pre>
*
* @author GOXR3PLUS
* @version 1.0
*/
public class DragAdjustableLabel extends Label {
// Variables
private int screenX;
private int screenY;
private int previousY;
private int minimumValue;
private int maximumValue;
/**
* The current value of the DragAdjustableLabel
*/
private IntegerProperty currentValue;
/**
* Constructor
*
* @param minimumValue
* Minimum Value that the slider can have
* @param maximumValue
* Maximum Value that the slider can have
*/
public DragAdjustableLabel(int currentValue, int minimumValue, int maximumValue) {
this.currentValue = new SimpleIntegerProperty(currentValue);
this.minimumValue = minimumValue;
this.maximumValue = maximumValue;
// Add a costume style class
this.getStyleClass().add("drag-adjustable-label");
setCursor(Cursor.OPEN_HAND);
textProperty().bind(this.currentValue.asString().concat(" %"));
// when the mouse is pressed
setOnMousePressed(m -> {
screenX = (int) m.getScreenX();
screenY = (int) m.getScreenY();
setCursor(Cursor.NONE); // comment this line to make the cursor
// visible
});
// when the mouse is dragged
setOnMouseDragged(m -> {
// calculate the monitor height
double screenHeight = Screen.getPrimary().getBounds().getHeight();
// !if the mouse has reached the the top of the monitor
// or
// ! if the mouse has reached the bottom of the monitor
if (m.getScreenY() <= 0 || m.getScreenY() + 10 >= screenHeight) {
resetMouse();
return;
}
// Calculate the current value
setCurrentValue(
getCurrentValue() + (m.getScreenY() == previousY ? 0 : m.getScreenY() > previousY ? -1 : 1));
previousY = (int) m.getScreenY();
});
// when the mouse is released
setOnMouseReleased(m -> {
resetMouse();
setCursor(Cursor.OPEN_HAND);
});
}
/**
* Reset the mouse to the default position(which is the center of the
* element)
*
* @param x
* @param y
*/
private void resetMouse() {
try {
new Robot().mouseMove(screenX, screenY);
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Set the current value
*
* @param value
*/
public void setCurrentValue(int value) {
// if the value is between the limits
if (value >= minimumValue && value <= maximumValue)
currentValue.set(value);
}
public int getCurrentValue() {
return currentValue.get();
}
public IntegerProperty currentValueProperty() {
return currentValue;
}
}