I am working on a JavaFx Application in which I need a list of Tree Views.
This is an application solving problem , every time I create a new problem a new tree view is created.
I want to maintain a list of such tree views which is feasible to scroll.
What I tried?
1.)Create a scroll pane and put a vbox in it.
2.)Add tree views in a vbox.
Issues with this
When I resize the window the vbox does not resize.(While putting any container inside scroll pane I cannot set Fit To Parent From Scene Builder)
Please suggest a good way to implement list of tree views
MyCode
#FXML
private VBox treeContainer;
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
for(int j=0;j<3;++j){
TreeItem<String> rootItem = new TreeItem<String> ("Item " + j);
rootItem.setExpanded(true);
String[] names = {"SubItem1","SubItem2", "SubItem3","SubItem4", "SubItem5","SubItem6","SubItem7",};
for (int i = 0; i < names.length; i++) {
TreeItem<String> item = new TreeItem<String> (names[i]);
rootItem.getChildren().add(item);
}
TreeView<String> tree = new TreeView<String> (rootItem);
tree.setMaxHeight(Double.MAX_VALUE);
tree.setStyle("-fx-background-color: white");
treeContainer.getChildren().add(tree);
}
}
"Issues with this
When I resize the window the vbox does not resize. ..."
Use "fit to" properties of ScrollPane.
<ScrollPane fitToHeight="true" fitToWidth="true" ... >
</ScrollPane>
Related
I'm trying to create some custom controls for Xamarin forms...
The controls should behave as a group of other controls. For example Label + Entry as one control to be inserted in a page.
I created a simple control here inherting from the class View.
This is an example of class with two labels. And inside this class, other controls are supposed to be inserted in addition to these labels.
public class Ton : View
{
public Ton() : base()
{
Label L;
L = new Label();
L.Parent = this;
L.Text = "XXX";
Label M;
M = new Label();
M.Parent = this;
M.Text = "YYY";
}
}
I insert then this class in a page :
<local:Ton></local:Ton>
but the contol is not shown in the page.
Does anyone know the reason please ?
Thanks.
Cheers,
A view is an abstract class and it cannot not have children. Also it does not know how to layout it's children inside it. You must have inherited your class from Layout<View> or someother existing layout classes like Grid, StackLayout, RelativeLayout, etc..
The base class depends on how you need to layout your children.
Refer my below GitHub repository to know how to create a custom control.
https://github.com/harikrishnann/BusyButton-XamarinForms
you create two Labels but don't actually add them to the View hierarchy
public class Ton : ContentView
{
public Ton() : base()
{
Label L;
L = new Label();
L.Text = "XXX";
Label M;
M = new Label();
M.Text = "YYY";
// because you have multiple elements, they must be contained in a Layout
var stack = new StackLayout();
stack.Children.Add(L);
stack.Children.Add(M);
// assign your controls to the View hierarchy
this.Content = stack;
}
}
i have an node in javafx which are moving in a timeline.
Now i want rotate the node also.
I tried it but everytime the node doesn't hold the path anymore and "fly away". Is there a way to relcate and rotate (I tried it with rotatetransition)?
Edit:
That is my View -Class
public class MyView extends ImageView{
public MyView (Image image) {
super(image);
RotateTransition transition = new RotateTransition();
transition.setCycleCount(Animation.INDEFINITE);
transition.setNode(this);
transition.setDuration(Duration.millis(10));
transition.setFromAngle(5);
transition.setToAngle(5;
transition.setAutoReverse(true);
transition.play(); // */
}
}
On another class i have this:
private void startMoveAnimation(MyView[] views) {
x++;
y++;
this.timeline = new Timeline();
timeline.setCycleCount(Animation.INDEFINITE);
moveEvent = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
for(View view: views){
view.relocate(x,y);
}
}
}
};
KeyFrame moveKeyFrame = new KeyFrame(Duration.millis(SPEED), moveEvent);
timeline.getKeyFrames().add(moveKeyFrame);
timeline.play(); // */
}
x and y are double values.
Using transforms gives you better control of the order of the transformations. Furthermore some transfroms allow you to specify a pivot point, which is not possible for e.g. the Node.rotate property. Transforms in a list are applied "right to left". (The transform with the highest index is applied first).
The following example shows how to move a rectangle rotating arount its own center (even though the cycle resets to the original position instead of continuously moving in the same direction, but the properties of the transforms can be animated independently in arbitrary ways):
#Override
public void start(Stage primaryStage) {
Rectangle view = new Rectangle(100, 100);
// pivot point = center of rect
Rotate rotate = new Rotate(0, 50, 50);
Translate translate = new Translate();
// rotate first, then move
view.getTransforms().addAll(translate, rotate);
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(translate.xProperty(), 0d),
new KeyValue(translate.yProperty(), 0d), new KeyValue(rotate.angleProperty(), 0d)),
new KeyFrame(Duration.seconds(2), new KeyValue(translate.xProperty(), 300d),
new KeyValue(translate.yProperty(), 500d), new KeyValue(rotate.angleProperty(), 360d)));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
Pane root = new Pane(view);
Scene scene = new Scene(root, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
}
That's what I would try first:
Put the node into a Group. Add the Group to the parent instead of the node. Do the translate animation on the Group and do the rotate animation on the node itself. This is just a first guess which I cannot try out because you haven't provided a minimal reproducible example.
I have three COMBO BOXES in my window. It is a family tree application I am developing using JavaFX and SQLIte. Each person has Father, Mother and Spouse info which can be selected from ComboBoxes. ComboBoxes are loaded with data from database.
It takes a while to load these three combo boxes. Actually different delays for different combo boxes.
If I click on a combo box while it is not ready or another combo box is not ready, the screen turns white until the other combo box is ready.
I want to prevent user input on entire window from Mouse, Keyboard and Buttons until entire window is ready to accept user's input. Until then I want change the cursor to something like STOP.
How to do this? Any suggestions?
Thanks,
Hornigold
Run a Task<ObservableList<SomeType>> (or a Task returning some object containing more than a single list) on a seperate Thread. Before starting the thread you disable the root and set the cursor for the scene and when the task finishes you initialize the GUI with the results and reenable the scene again:
#Override
public void start(Stage primaryStage) {
Button loadButton = new Button("load");
ComboBox<String> combo = new ComboBox<>();
VBox root = new VBox(combo, loadButton);
Scene scene = new Scene(root);
loadButton.setOnAction(evt -> {
root.setDisable(true);
// save old cursor to restore after finishing the task
final Cursor oldCursor = root.getScene().getCursor();
scene.setCursor(Cursor.WAIT);
Task<ObservableList<String>> task = new Task<ObservableList<String>>() {
#Override
protected ObservableList<String> call() throws Exception {
ObservableList<String> result = FXCollections.observableArrayList();
for (int i = 0; i < 100; i++) {
result.add(Integer.toString(i));
}
// simulate delay
Thread.sleep(5000);
return result;
}
};
task.setOnSucceeded(e -> {
// use results of task in the GUI
combo.setItems(task.getValue());
// restore cursor and reenable scene
root.setDisable(false);
scene.setCursor(oldCursor);
});
task.setOnFailed(e -> {
// todo: handle exception in Task.call
});
Thread thread = new Thread(task);
thread.start();
});
primaryStage.setScene(scene);
primaryStage.show();
}
I want to layout three VerticalFieldManager in a screen with NO_VERTICAL_SCROLL. One manager should be aligned to TOP, one should be aligned to BOTTOM and the last one should consume the rest of the height between the former two.
Can it be achieved without overriding sublaout() for any Manager? The result I want to achieve is:
I layouted this screen with the following code. The problem is that I wasn't able to do it without overriding sublayout().
public class LayoutSandboxScreen extends MainScreen {
public LayoutSandboxScreen() {
super(NO_VERTICAL_SCROLL);
VerticalFieldManager vfmTop = new VerticalFieldManager(USE_ALL_WIDTH);
vfmTop.setBackground(BackgroundFactory.createSolidBackground(Color.GREEN));
vfmTop.add(new ButtonField("TOP", FIELD_HCENTER));
final VerticalFieldManager vfmCenter = new VerticalFieldManager(USE_ALL_WIDTH);
HorizontalFieldManager hfmCenter = new HorizontalFieldManager(USE_ALL_HEIGHT | FIELD_HCENTER);
vfmCenter.setBackground(BackgroundFactory.createSolidBackground(Color.RED));
hfmCenter.add(new ButtonField("CENTER", FIELD_VCENTER));
vfmCenter.add(hfmCenter);
final VerticalFieldManager vfmBottom = new VerticalFieldManager(USE_ALL_WIDTH);
vfmBottom.setBackground(BackgroundFactory.createSolidBackground(Color.BLUE));
final ButtonField btn = new ButtonField("BUTTOM", FIELD_HCENTER);
vfmBottom.add(btn);
VerticalFieldManager vfmSecond = new VerticalFieldManager(USE_ALL_HEIGHT) {
protected void sublayout(int maxWidth, int maxHeight) {
setExtent(maxWidth, maxHeight);
layoutChild(vfmBottom, maxWidth, maxHeight);
int bottomHeight = vfmBottom.getHeight();
layoutChild(vfmCenter, maxWidth, maxHeight - bottomHeight);
setPositionChild(vfmCenter, 0, 0);
setPositionChild(vfmBottom, 0, maxHeight - bottomHeight);
}
};
vfmSecond.add(vfmBottom);
vfmSecond.add(vfmCenter);
add(vfmTop);
add(vfmSecond);
}
}
Since you're already using a MainScreen, have you tried using setTitle() and setStatus() for the top and bottom VerticalFieldManager? I think that will do what you want.
Edit
If MainScreen is too specific, you can write your own MainManager, which supports the same layout components as MainScreen - banner, title, main content, status. You will have to write your own layout code though, so you'll still be implementing sublayout(), which you specifically wanted to avoid. The plus side is that this will be more composable - you won't be overriding the sublayout() method in an ad-hoc way on random UI components.
Trying to create a custom cyclical horizontal manager which will work as follows. It will control several field buttons where the buttons will always be positioned so that the focused button will be in the middle of the screen. As it is a cyclical manager once the focus moves to the right or left button, it will move to the center of the screen and all the buttons will move accordingly (and the last button will become the first to give it an cyclic and endless list feeling)
Any idea how to address this?
I tried doing this by implementing a custom manager which aligns the buttons according to the required layout. Each time moveFocus() is called I remove all fields (deleteAll() ) and add them again in the right order.
Unfortunately this does not work.
Using HorizontalButtonFieldSet class from KB How to - Implement advanced buttons, fields, and managers:
class CentricHManager extends HorizontalButtonFieldSet {
int focusedFieldIndex = 0;
public void focusChangeNotify(int arg0) {
super.focusChangeNotify(arg0);
int focusedFieldIndexNew = getFieldWithFocusIndex();
if (focusedFieldIndexNew != focusedFieldIndex) {
if (focusedFieldIndexNew - focusedFieldIndex > 0)
switchField(0, getFieldCount() - 1);
else
switchField(getFieldCount() - 1, 0);
}
}
private void switchField(int prevIndex, int newIndex) {
Field field = getField(prevIndex);
delete(field);
insert(field, newIndex);
}
public void add(Field field) {
super.add(field);
focusedFieldIndex = getFieldCount() / 2;
setFieldWithFocus(getField(focusedFieldIndex));
}
}