In der Main Klasse instanziere ich lediglich die RoundedMenu Klasse und übergabe eine String[]. Hier passt alles.
In der RoundedMenu Klasse habe eine deBug method angelegt, weil ich sonst nicht die breite der nodes ermitteln konnte, bevor sie gezeichnet wurden in der scene. Der MenuItem wird nicht richtig positiniert und bei MouseEnter bewegt sich nur der zuletzt instanzierte MenuItem
Hier im MenuItem Klasse in der ich leider nur über ein deBug die richtige Breite ermitteln konnte um den dazugehörigen Text zu zentrieren.
Habt ihr eine andere Alternative als so ein verzögerndes aufrufen einer Methode? Warum wird das zweite MenuItem nicht richtig positioniert? Und wieso reagiert der letzte MenuItem auf Bewegung?
Java:
package RoundedNav2;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
try {
primaryStage.setTitle("Edelherz");
primaryStage.getIcons().add(new Image("images/Playlist-16.png"));
Group root = new Group();
String[] myStrings = new String[] {"Home","Projects","Events","Contact"};
RoundedMenu roundedMenu = new RoundedMenu(myStrings);
root.getChildren().add(roundedMenu);
Scene scene = new Scene(root, 400, 400);
scene.getStylesheets().add(getClass().getResource("myStyle.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
In der RoundedMenu Klasse habe eine deBug method angelegt, weil ich sonst nicht die breite der nodes ermitteln konnte, bevor sie gezeichnet wurden in der scene. Der MenuItem wird nicht richtig positiniert und bei MouseEnter bewegt sich nur der zuletzt instanzierte MenuItem
Java:
package RoundedNav2;
import java.util.Arrays;
import java.util.List;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.layout.Region;
import javafx.util.Duration;
public class RoundedMenu extends Region{
private List myList;
private String str;
private int listLength;
private int cnt = 0;
private double xPos;
private MenuItem mItem = null;
public RoundedMenu(String[] myStrings){
this.myList = Arrays.asList(myStrings);
//System.out.println(myList.get(2));
listLength = myList.size();
deBug();
}
public void deBug(){
if(cnt == 0){
xPos = 0;
}else
{
xPos += mItem.getWidth();
}
if(cnt < listLength){
mItem = new MenuItem(myList.get(cnt).toString());
System.out.println("xPos: " + xPos);
mItem.setLayoutX(xPos);
getChildren().add(mItem);
mItem.setOpacity(.5);
cnt++;
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(50),ae -> deBug()));
timeline.play();
}
}
}
Hier im MenuItem Klasse in der ich leider nur über ein deBug die richtige Breite ermitteln konnte um den dazugehörigen Text zu zentrieren.
Java:
package RoundedNav2;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.util.Duration;
public class MenuItem extends Region {
private static Text txt;
private static Rectangle r;
private static Group root;
private static Pane holder;
private static int startYpos = -100;
private static int endMovePos = -60;
private static int textOffsetFromBottom = 5;
private static int rectangleTextOffset = 15;
private String menuItemText;
// ******************** Constructors **************************************
public MenuItem(String menuItemText) {
this.menuItemText = menuItemText;
txt = new Text(menuItemText);
txt.getStyleClass().add("roundedNavText");
txt.applyCss();
r = new Rectangle();
r.setWidth(50);
r.setHeight(150);
r.setArcHeight(25);
r.setArcWidth(25);
r.setFill(Color.web("#668845"));
holder = new Pane();
holder.setLayoutY(startYpos);
holder.setOnMouseClicked(e->{
System.out.println("CLICK");;
});
holder.setOnMouseEntered(e->{
moveRec(0.3, endMovePos, holder);
System.out.println(this);
});
holder.setOnMouseExited(e->{
moveRec(0.3, startYpos, holder);
});
holder.getChildren().addAll(r, txt);
getChildren().add(holder);
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(1),ae -> deBug()));
timeline.play();
}
public static void deBug(){
final double tWidth = txt.getLayoutBounds().getWidth();
System.out.println("tWidth: " + tWidth);
double tHeight = txt.getBoundsInLocal().getHeight();
r.setWidth(tWidth + (rectangleTextOffset * 2));
txt.setLayoutX(r.getWidth()/2-tWidth/2);
txt.setLayoutY(r.getHeight()-tHeight/2-textOffsetFromBottom);
}
public static void moveRec(double d, int kv, Node obj){
Timeline t = new Timeline();
Duration duration = Duration.seconds(d);
KeyValue keyValue = new KeyValue(obj.layoutYProperty(), kv, Interpolator.EASE_OUT);
t.getKeyFrames().add(new KeyFrame(duration, keyValue));
t.play();
}
}
Habt ihr eine andere Alternative als so ein verzögerndes aufrufen einer Methode? Warum wird das zweite MenuItem nicht richtig positioniert? Und wieso reagiert der letzte MenuItem auf Bewegung?