Swing context menu on JavaFX Chart - java

I am working on an application primarily in swing, though the chart dialog uses JavaFX. (Chart in a GridPane in a JFXPanel to be exact.)
First, Chart does not implement a setContextMenu method to use a JFX ContextMenu. I have seen a workaround by attaching a handler to the right click of the chart, but the menu is not removed from the GUI when it loses focus, rather it persists until the user either 1) triggers it to open again or 2) clicks a MenuItem.
chart.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
if (t.getButton() == MouseButton.SECONDARY) {
contextMenu.show(chart, t.getScreenX(), t.getScreenY());
}
}
});
That said, I would prefer to use a Swing JPopupMenu instead. How can I bind this to my Chart and maintain a natural behavior?
Thank you!

I determined it was not possible to use a JPopupMenu.
The ContextMenu is added to a JLabel:
Label contextMenuLabel = new Label();
grid.add(contextMenuLabel, 0, 0); // Add to the same grid after adding the chart
contextMenuLabel.setPrefSize(width, height);
contextMenuLabel.setMinSize(width, height);
contextMenuLabel.setMaxSize(width, height);
ContextMenu contextMenu = new ContextMenu();
contextMenuLabel.setContextMenu(contextMenu);

Related

JAVAFX How to make a button stacked behind a Label clickable

How to make a button stacked behind a Label clickable?
Button
Button btn = new Button();
//TODO: button's main function, like onPressed, onReleased etc. here...
Custom label
CustomLabel sp = new CustomLabel("Some texts here"));
//TODO: custom label's main function, like a translucent background etc here...
//main purpose of this is to overlay the button
Main Pane
StackPane mainPane = new StackPane();
mainPane.getChildren.addAll(btn, sp);
With this, the area which the custom label overlays becomes unclickable.
Is there anyway to make the button still clickable even though overlay-ed, for example?
Or is there another way to do it? Something like setting label to not visible on click?
EDIT : To answer Itamar Green 's question..
By using the example as shown in this link: Mouse Events get Ignored on the Underlying Layer , it still does not seems to work. The button stacked under the layer is still not clickable.
sp.setPickOnBounds(false);
You can set the mouseTransparent property of the element(s) drawn on top to true. Note that this way all descendants of the node are ignored for mouse events:
#Override
public void start(Stage primaryStage) {
Button btn = new Button("Say 'Hello World'");
btn.setOnAction((ActionEvent event) -> {
System.out.println("Hello World!");
});
Region region = new Region();
region.setStyle("-fx-background-color: #0000ff88;");
region.setMouseTransparent(true);
StackPane root = new StackPane(btn, region);
Scene scene = new Scene(root, 100, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
Comment out
region.setMouseTransparent(true);
and the button will no longer react to mouse events in any way...
thanks for your help. I think I have solved my own question.
All I did was set a clickable event for my label.
Label sp = new Label("some texts here")
sp.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
//copy over the button's event.
}
});
Not sure if there is any better way of doing this...
in addition with the correct answer. you can enable or disable " mouse transparent " property via fxml with scenebuilder

Java Swing show tooltip as a message dialog

Is it possible in Java Swing to show message box using tooltip item. I need to show tooltip not only when a mouse hovers some component but also when I choose specific item in context menu of this component when tooltips are turned off.
You can use PopupFactory to show your popup message
final Popup p = PopupFactory.getSharedInstance().getPopup(myComponent, new JLabel("Here is my popup!"), x, y);
p.show();
// create a timer to hide the popup later
Timer t = new Timer(5000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
p.hide();
}
});
t.setRepeats(false);
t.start();
where myComponent - is the component for which popup must be shown
x, y - coordinates of popup.

JavaFx Combobox drop down list width is less on first click on Combo box

when I click on the ComboBox the first time and the popup menu list that is shown has its width very short. The second time I click on the ComboBox and the list is shown again, the width is now correct as the width of the list now aligns itself with the Combbox.
i tried to alter the width of the drop down on mouse click on the combo box. But it did not work,
final ComboBox<String> combo = new ComboBox<String>();
combo.getStyleClass().add("combo-border");
combo.setMinWidth(100.0);
combo.setEditable(true);
combo.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent arg0) {
combo.setMinWidth(100.0); // Did not work
//csectCombo.setPrefWidth(100.0); // Did not work
}
});
I am using Javafx 2.2. Is there any workaround for this?
From the below post, it says that is the known bug in JavaFx 2 and has been fixed in JavaFx 8.
http://tech.chitgoks.com/2013/09/20/width-of-combobox-popup-list-is-too-small-in-java-fx-2/
Try this
final ComboBox<String> combo = new ComboBox<String>();
combo.getStyleClass().add("combo-border");
combo.setMinWidth(100.0);
combo.setEditable(true);
combo.setPrefWidth(combo.getMinWidth());

How to create a popup window in javafx [duplicate]

This question already has an answer here:
JavaFX 2 custom popup pane
(1 answer)
Closed 7 years ago.
I want to create a popup window in a JavaFX application. Give me some ideas.
When I click on Check button it opens the popup window.
How to do it?
You can either create a new Stage, add your controls into it or if you require the POPUP as Dialog box, then you may consider using DialogsFX or ControlsFX(Requires JavaFX8)
For creating a new Stage, you can use the following snippet
#Override
public void start(final Stage primaryStage) {
Button btn = new Button();
btn.setText("Open Dialog");
btn.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
final Stage dialog = new Stage();
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(primaryStage);
VBox dialogVbox = new VBox(20);
dialogVbox.getChildren().add(new Text("This is a Dialog"));
Scene dialogScene = new Scene(dialogVbox, 300, 200);
dialog.setScene(dialogScene);
dialog.show();
}
});
}
If you don't want it to be modal (block other windows), use:
dialog.initModality(Modality.NONE);
The Popup class might be better than the Stage class, depending on what you want. Stage is either modal (you can't click on anything else in your app) or it vanishes if you click elsewhere in your app (because it's a separate window). Popup stays on top but is not modal.
See this Popup Window example.
Take a look at jfxmessagebox (http://en.sourceforge.jp/projects/jfxmessagebox/) if you are looking for very simple dialog popups.
Have you looked into ControlsFx Popover control.
import org.controlsfx.control.PopOver;
import org.controlsfx.control.PopOver.ArrowLocation;
private PopOver item;
final Scene scene = addItemButton.getScene();
final Point2D windowCoord = new Point2D(scene.getWindow()
.getX(), scene.getWindow().getY());
final Point2D sceneCoord = new Point2D(scene.getX(), scene.
getY());
final Point2D nodeCoord = addItemButton.localToScene(0.0,
0.0);
final double clickX = Math.round(windowCoord.getX()
+ sceneCoord.getY() + nodeCoord.getX());
final double clickY = Math.round(windowCoord.getY()
+ sceneCoord.getY() + nodeCoord.getY());
item.setContentNode(addItemScreen);
item.setArrowLocation(ArrowLocation.BOTTOM_LEFT);
item.setCornerRadius(4);
item.setDetachedTitle("Add New Item");
item.show(addItemButton.getParent(), clickX, clickY);
This is only an example but a PopOver sounds like it could accomplish what you want. Check out the documentation for more info.
Important note: ControlsFX will only work on JavaFX 8.0 b118 or later.

Weird behavior of two mouse events being triggered infinitely in tooltip code

I am trying to implement a custom tooltip using the javafx.stage.Popup. The sample demo code is:
public class PopupDemo extends Application {
private Popup tooltip;
private final SepiaTone sepiaTone = new SepiaTone();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("PopupDemo");
Label content = new Label();
content.setStyle("-fx-background-color:#FCFBBD; -fx-padding: 5; -fx-border-color: #BFBD3B");
tooltip = new Popup();
tooltip.getContent().add(content);
VBox vbox = new VBox(10);
for (int i = 0; i < 5; i++) {
final Label lbl = new Label("item " + i);
lbl.setStyle("-fx-border-color:darkgray; -fx-background-color:lightgray");
lbl.setMaxSize(80, 60);
lbl.setMinSize(80, 60);
lbl.setAlignment(Pos.CENTER);
lbl.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override
public void handle(final MouseEvent e) {
lbl.setEffect(sepiaTone);
lbl.setStyle("-fx-cursor: hand");
Label content = (Label) tooltip.getContent().get(0);
content.setText(lbl.getText());
tooltip.show(lbl, e.getScreenX(), e.getScreenY());
}
});
lbl.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
lbl.setEffect(null);
lbl.setStyle("-fx-cursor: default");
tooltip.hide();
}
});
vbox.getChildren().add(lbl);
}
StackPane root = new StackPane();
root.setPadding(new Insets(20));
root.getChildren().add(vbox);
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.show();
}
}
When I move the mouse over the labels the popup shows up and it is working great. But in some cases the two mouse event handlers OnMouseEntered and OnMouseExited are being called continuously one after another. One can reproduce this by running provided example, maximising a window and hovering labels continuously.
Is there a way to avoid this? I'm using JavaFX 2.0.1. Thanks.
It's a classic problem: you put mouse at a point, node receives MouseEntered — tooltip appears under the mouse and covers the node triggering MouseExited.
To avoid that you can change tooltip.show(lbl, e.getScreenX(), e.getScreenY()) call to
tooltip.show(lbl, e.getScreenX() + 1, e.getScreenY() + 1);
This is not really an answer, so much as pointers to things you might try or investigate further.
You could look at the implementation of Tooltip Skin and Behavior to see how it handles some of these cases.
The easiest way to implement a custom popup is just to use a Tooltip, style it the way you need using css and use the Tooltip's setGraphic method to add any custom Node content you want.
If you prefer to use your own implementation, I think you need to keep track of whether the popup has been displayed or not, so you don't try to show it if it is already showing, etc. You may also need invoke the hiding of the popup by having a mouse exit handler installed on the popup itself. You also might want a click to dismiss function for the popup by implementing a mouse click handler on the popup. You should also consider whether you should do a straight subclass of Popup or PopupControl, though using Popup as you have is likely more straightforward.

Categories