How do I get my grid to refresh whenever I visit the view that accesses it? - jpa

I have a Grid in my Vaadin project that displays portions of all the Events entities in my EventsRepository. The view that shows this grid shows the Events entities just fine, but only in their first state once they enter the repository. Whenever a user signs up for an event, its "participants" count is supposed to drop, and their name is supposed to be added to the user list (just a large String for now). However, whenever I go back to this view, the grid is not updated. I know that I need to be calling grid.getDataProvider().refreshAll(); somewhere in my code for the grid to update with these changes, but I just can't figure out where to put it. I have confirmed that I am properly changing these values, but these changes just are not being reflected in the grid.
Here is my view that accesses the grid I mention:
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.AfterNavigationEvent;
import com.vaadin.flow.router.AfterNavigationListener;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import ymca.tracker.application.data.entity.Events;
import ymca.tracker.application.data.service.EventsService;
import java.util.List;
#PageTitle("Registration Management")
#Route(value = "registration-management")
public class RegistrationManagementView extends Div implements AfterNavigationListener {
EventsService eventsService;
Grid<Events> grid = new Grid<>();
public RegistrationManagementView(EventsService eventsService) {
this.eventsService = eventsService;
addClassName("account-view");
setSizeFull();
grid.setHeight("100%");
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER, GridVariant.LUMO_NO_ROW_BORDERS);
List<Events> events = getData();
grid.setItems(events);
grid.addComponentColumn(event -> createCard(event));
add(grid);
// I tried calling this line of code in the constructor, but this does not refresh either
grid.getDataProvider().refreshAll();
}
private HorizontalLayout createCard(Events events) {
HorizontalLayout card = new HorizontalLayout();
card.addClassName("card");
card.setSpacing(false);
card.getThemeList().add("spacing-s");
VerticalLayout vl = new VerticalLayout();
vl.addClassName("description");
vl.setSpacing(false);
vl.setPadding(false);
HorizontalLayout header = new HorizontalLayout();
header.addClassName("header");
header.setSpacing(false);
header.getThemeList().add("spacing-s");
Span name = new Span(events.getName());
name.addClassName("name");
header.add(name);
Span capacity = new Span("Spots Remaining: " + events.getParticipants());
capacity.addClassName("capacity");
String registrantList = events.getUsers();
Span signUps = new Span("Current Registrants: \n" + registrantList);
signUps.addClassName("signUps");
vl.add(header, capacity, signUps);
card.add(vl);
return card;
}
public List<Events> getData() {
List<Events> events = eventsService.findAllEvents();
return events;
}
/* I tried an aferNavigationListener, but I really don't know how
to implement this at all but I know this is not correct
*/
#Override
public void afterNavigation(AfterNavigationEvent afterNavigationEvent) {
grid.getDataProvider().refreshAll();
}
}

Related

Vaadin formlayout won't centre

I'm building a registration form in Vaadin 22 and I want the FormLayout to be in the centre of the page horizontally.
The headlingLabel centres correctly but the form is always to the left hand side of the page.
If I remove the setMaxWidth of the form the form fills the full width of the page.
package dev.onepub.ui.views.authed;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.formlayout.FormLayout.ResponsiveStep;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.router.Route;
import dev.onepub.dao.DaoMember;
import dev.onepub.entity.enums.ActionEnum;
import dev.onepub.session.MemberSession;
import dev.onepub.ui.DefaultView;
import dev.onepub.ui.OnePubLayout;
import dev.onepub.ui.crud.Access;
/// Place holder for the re-registration process.
#Access(required = ActionEnum.notRequired)
#Route(value = "Register", layout = OnePubLayout.class)
public class RegistrationView extends VerticalLayout
{
private transient Logger logger = LogManager.getLogger();
private static final long serialVersionUID = 1L;
public static final String NAME = "Register";
public static final String LABEL = "register";
TextField firstName = new TextField("First name");
TextField lastName = new TextField("Last name");
TextField email = new TextField("Preferred Email");
TextField publisher = new TextField("Organisation Name");
Checkbox subscribe = new Checkbox("Subscribe to periodic newsletters for product features, tips and tricks.");
Checkbox terms = new Checkbox();
Button signup = new Button("Signup");
private Binder<Registration> binder = new Binder<>(Registration.class);
public RegistrationView()
{
this.setSizeFull();
// this.setMargin(false);
HorizontalLayout heading = new HorizontalLayout();
heading.setWidth("100%");
Label headingLabel = new Label("Please confirm the following details");
this.add(headingLabel);
final var form = new FormLayout();
this.add(form);
this.setAlignItems(Alignment.CENTER);
this.setJustifyContentMode(JustifyContentMode.START);
form.setMaxWidth("800px");
terms.setLabelAsHtml(
"I agree to both the <a href='https://www.onepub.dev/terms' target='_blank'>terms and conditions</a>, and the <a href='https://www.onepub.dev/privacy' target='_blank'>privacy policy.</a>");
form.add(firstName, lastName, email, publisher, subscribe, terms, signup);
form.setColspan(email, 2);
form.setColspan(publisher, 2);
form.setColspan(subscribe, 2);
form.setColspan(terms, 2);
form.setColspan(signup, 2);
form.setResponsiveSteps(
// Use one column by default
new ResponsiveStep("0", 1),
// Use two columns, if layout's width exceeds 500px
new ResponsiveStep("500px", 2));
binder.bindInstanceFields(this);
final var member = MemberSession.getCurrent().loggedInMember;
final var registration = new Registration(member);
binder.setBean(registration);
signup.addClickListener(event -> save());
}
private void save()
{
Registration registration = binder.getBean();
final var member = new DaoMember().findByEntity(MemberSession.getCurrent().loggedInMember);
member.setFirstname(registration.firstName);
member.setSurname(registration.lastName);
member.setPreferredEmail(registration.email);
member.getPublisher().setName(registration.publisher);
member.setAcceptedTerms(terms.getValue());
member.setSubcribed(subscribe.getValue());
UI.getCurrent().navigate(DefaultView.class);
}
}
Add this form.getStyle().set("align-self", "center");
Explanation
If you inspect the vaadin-form-layout element, you'll discover 2 things:
It automatically sets align-self to stretch which basically makes it try to fill up the available space of the parent.
max-width: 100%
You can override those Behavior by setting align-self to center and setting a width to the form using form.setWidth("WIDTH");.
Based on #styl3r response I found that I just need to add
setAlignSelf(Alignment.CENTER, form);
setJustifyContentMode(JustifyContentMode.START);
This avoids directly playing with styles.
So the full answer is:
package dev.onepub.ui.views.authed;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.formlayout.FormLayout.ResponsiveStep;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.router.Route;
import dev.onepub.dao.DaoMember;
import dev.onepub.entity.enums.ActionEnum;
import dev.onepub.fields.validators.EmailValidator;
import dev.onepub.session.MemberSession;
import dev.onepub.ui.CheckboxWithError;
import dev.onepub.ui.DefaultView;
import dev.onepub.ui.OnePubLayout;
import dev.onepub.ui.crud.Access;
import dev.onepub.ui.crud.PublicView;
/// Place holder for the re-registration process.
#Access(required = ActionEnum.notRequired)
#Route(value = "Register", layout = OnePubLayout.class)
public class RegistrationView extends VerticalLayout implements PublicView
{
#SuppressWarnings("unused")
private transient Logger logger = LogManager.getLogger();
private static final long serialVersionUID = 1L;
public static final String NAME = "Register";
public static final String LABEL = "register";
TextField firstName = new TextField("First name");
TextField lastName = new TextField("Last name");
TextField email = new TextField("Preferred Email");
TextField publisher = new TextField("Organisation Name");
Checkbox subscribe = new Checkbox(
"Subscribe to periodic newsletters for product features, tips and tricks. (No more than once a month)");
CheckboxWithError terms = new CheckboxWithError();
Button signup = new Button("Signup");
private Binder<Registration> binder = new Binder<>(Registration.class);
public RegistrationView()
{
this.setSizeFull();
// this.setMargin(false);
HorizontalLayout heading = new HorizontalLayout();
heading.setWidth("100%");
Label headingLabel = new Label("Please confirm the following details");
this.add(headingLabel);
final var form = new FormLayout();
setAlignSelf(Alignment.CENTER, form);
setJustifyContentMode(JustifyContentMode.START);
this.add(form);
this.setAlignItems(Alignment.CENTER);
this.setJustifyContentMode(JustifyContentMode.START);
form.setMaxWidth("800px");
terms.setLabelAsHtml(
"I agree to both the <a href='https://www.onepub.dev/terms' target='_blank'>terms and conditions</a>, and the <a href='https://www.onepub.dev/privacy' target='_blank'>privacy policy.</a>");
form.add(firstName, lastName, email, publisher, subscribe, terms, signup);
form.setColspan(email, 2);
form.setColspan(publisher, 2);
form.setColspan(subscribe, 2);
form.setColspan(terms, 2);
form.setColspan(signup, 2);
form.setResponsiveSteps(
// Use one column by default
new ResponsiveStep("0", 1),
// Use two columns, if layout's width exceeds 500px
new ResponsiveStep("500px", 2));
binder.bindInstanceFields(this);
binder.forField(email).withValidator(new EmailValidator("Note a valid email address"))
.bind("email");
binder.forField(terms).withValidator((v) -> v == true, "You must accept the Terms and Conditions")
.bind("terms");
final var member = MemberSession.getCurrent().preRegistrationMember;
final var registration = new Registration(member);
binder.setBean(registration);
signup.addClickListener(event -> save());
}
private void save()
{
Registration registration = binder.getBean();
final var status = binder.validate();
if (status.isOk())
{
final var member = new DaoMember().findByEntity(MemberSession.getCurrent().loggedInMember);
member.setFirstname(registration.firstName);
member.setSurname(registration.lastName);
member.setPreferredEmail(registration.email);
member.getPublisher().setName(registration.publisher);
member.setSubcribed(subscribe.getValue());
member.setAcceptedTerms(terms.getValue());
MemberSession.getCurrent().preRegistrationMember = null;
UI.getCurrent().navigate(DefaultView.class);
}
}
}

how to add same background color for all pane in javafx?

I want to maintain single background color(black) for all panes, and for all views. i don't want write css for every view. i am using only vbox and hbox mostly. and very few table views. is there any easy way to write css once and apply to all. thank you in advance
You don't write a css for every view, you give every element the same style class.
Pane pane = new Pane();
pane.getStyleClass().add("bg-black-style");
Somewhere you need to add the stylesheet to the scene
scene.getStylesheets().add("css-file.css");
And in the css file
.bg-black-style {
-fx-background-color: black;
}
This way every thing that should look the same has it's style all in one place.
You can just use .pane in CSS class, and it will work for all the panes.
.pane{
-fx-background-color: black;
}
Same works with .button etc.
You can apply the style sheet to the entire application like this:
package hacks;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import java.net.URL;
/**
* Created by BDay on 7/10/17.<br>
* <br>
* CssStyle sets the style for the entire project
*/
public class CssStyle extends Application {
private String yourCss = "YourResource.css";
public CssStyle() {
try {
Application.setUserAgentStylesheet(getCss()); //null sets default style
} catch (NullPointerException ex) {
System.out.println(yourCss + " resource not found");
}
}
private Button button = new Button("Button Text");
private TextArea textArea = new TextArea("you text here");
private ObservableList<String> listItems = FXCollections.observableArrayList("one", "two", "three");
private ListView listView = new ListView<String>(listItems);
private FlowPane root = new FlowPane(button, textArea, listView);
private Scene scene = new Scene(root);
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(scene);
primaryStage.show();
}
private String getCss() throws NullPointerException {
ClassLoader classLoader = getClass().getClassLoader();
URL resource = classLoader.getResource(yourCss);
String asString = resource.toExternalForm(); //throws null
return asString;
}
}

JavaFX ListChangedListeners not firing with ControlsFX PopOver and CheckListView

I am writing a generic Java class to display a list of filter items that can be un/checked and the resulting selection being then passed to a controller to filter the collection of primary objects for display. I'm using two ControlsFX controls: the PopOver to contain the filter list and a CheckListView to display and control the individual items.
The flow is that the filter PopOver class is instantiated in the controller's constructor and the source data is reloaded every time it is shown.
On the surface the code appears to work. The source items are added, the checking and unchecking works and the number of items in the list of checked items is correct. However I've added listeners to the Observable Lists for both the source data and the list of checked items and neither is fired.
I've tried writing the listeners in-line and as separate methods (as in the example) and I've tried writing them in traditional onChanged and lambda styles. Neither made a difference.
I've also tried using almost identical code just using theCheckListView as a node of a pane. This did work exactly as expected.
I've also gone through the ControlsFX issues log and found nothing directly relevant (except to confirm that the code I was using seemed OK).
This is the Filter class:
package debuglogger;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.layout.BorderPane;
import org.controlsfx.control.CheckListView;
import org.controlsfx.control.PopOver;
public class FilterPopOverSO<T> extends PopOver {
private ObservableList<T> sourceData;
private BorderPane popoverNode;
private CheckListView<T> filterList;
/**
* ============================================================================================
* Constructor
* ============================================================================================
*/
public FilterPopOverSO() {
super();
sourceData = FXCollections.observableArrayList();
popoverNode = new BorderPane();
filterList = new CheckListView<>();
filterList.setPrefWidth(600D);
filterList.setMaxWidth(600D);
popoverNode.setCenter(filterList);
setContentNode(popoverNode);
filterList.getItems().addListener(sourceItemsListener);
filterList.getCheckModel().getCheckedItems().addListener(checkedItemsListener);
filterList.getCheckModel().checkAll();
}
/**
* ============================================================================================
* Listeners
* ============================================================================================
*/
ListChangeListener<T> sourceItemsListener = (change) -> {
System.out.println("Start of Change Listener 'sourceItemsListener'");
while(change.next()) {
System.out.println(" Added: " + change.wasAdded());
System.out.println(" Permutated: " + change.wasPermutated());
System.out.println(" Removed: " + change.wasRemoved());
System.out.println(" Updated: " + change.wasUpdated());
}
System.out.println("End of of Change Listener 'sourceItemsListener'");
};
ListChangeListener<T> checkedItemsListener = (change) -> {
System.out.println("Start of Change Listener 'checkedItemsListener'");
while(change.next()) {
System.out.println(" Added: " + change.wasAdded());
System.out.println(" Permutated: " + change.wasPermutated());
System.out.println(" Removed: " + change.wasRemoved());
System.out.println(" Updated: " + change.wasUpdated());
}
System.out.println("End of of Change Listener 'checkedItemsListener'");
};
public void setSourceData(ObservableList<T> sourceData) {
filterList.setItems(sourceData);
}
}
And this is the test stub:
package scratchpad;
import debuglogger.FilterPopOverSO;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class FilterPopOverTest extends Application {
#Override
public void start(Stage primaryStage) {
ObservableList<String> sourceList = FXCollections.observableArrayList("Item 1", "Item 2", "Item 3");
FilterPopOverSO<String> p = new FilterPopOverSO<>();
AnchorPane root = new AnchorPane();
Button btn = new Button("Click Me!");
btn.setOnAction(event -> {
System.out.println("Just to show that I was here!");
p.setSourceData(sourceList);
p.show(btn);
});
root.getChildren().add(btn);
AnchorPane.setTopAnchor(btn, 50D);
AnchorPane.setLeftAnchor(btn, 50D);
primaryStage.setTitle("Filter PopOver Test");
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Problem solved. The garbage collector was removing the listeners every time the popover was hidden. I simply moved the 'add listener' statement to the point where I showed the popover.

Display error messages directly in Vaadin 7

I'm developing a web app in Vaadin, which involves a large number of forms. Currently, all the screens have been created, and I ran them past a couple of test users (4) to checkout their usability. All of them had one and the same comment; when a validation error occurred, it was not clear what the problem was. None of them thought about hovering their mouse over the error indicator (if they even noticed the indicator) to get the precise error message.
I read in the Book of Vaadin that the placement of the error indicator is managed by the layout in which the component is contained. However, it doesn't seem to say anything about directly showing the error message. Is it possible to do this (preferrably, without having to implement a custom widget set)?
Thanks,
​William
I don't think what you have in mind is implemented with vaadin's basic components.
I suggest the following approach: create a dedicated label above the form's input components that is invisible by default. After validation, if there are errors, add them all to the label's text and make it visible. Displaying the errors right next to the component that caused the validation error would likely mess up your layout too much anyway.
I write a utility class to do this:
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import com.vaadin.server.ErrorMessage;
import com.vaadin.server.Page;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
public class ErrorUtils {
public static List<String> getComponentError(
final AbstractComponent[] componentArray) {
List<String> errorList = new ArrayList<String>();
for (AbstractComponent component : componentArray) {
ErrorMessage errorMessage = component.getErrorMessage();
if (errorMessage != null) {
errorList.add(errorMessage.getFormattedHtmlMessage());
}
}
return errorList;
}
public static List<String> getComponentError(
final Collection<?> componentCollection) {
AbstractComponent[] componentArray = componentCollection
.toArray(new AbstractComponent[] {});
return ErrorUtils.getComponentError(componentArray);
}
public static void showComponentErrors(
final AbstractComponent[] componentArray) {
List<String> errorList = ErrorUtils.getComponentError(componentArray);
String error = StringUtils.join(errorList, "\n");
Notification notification = new Notification("Error", error,
Type.ERROR_MESSAGE, true);
notification.show(Page.getCurrent());
}
public static void showComponentErrors(
final Collection<?> componentCollection) {
AbstractComponent[] componentArray = componentCollection
.toArray(new AbstractComponent[] {});
ErrorUtils.showComponentErrors(componentArray);
}
}
The the following code is a simple sample showing how to use it:
private void saveButtonClicked() {
// this method is the handler of the click event of the [save] button
try {
this.fieldGroup.commit();
} catch (CommitException e) {
// Show all the validate errors:
ErrorUtils.showComponentErrors(this.fieldGroup.getFields());
return;
}
// save data, if there is no validate error
}
I created a Vaadin Add-on that will display validation/conversion error messages directly on the UI rather than in a tooltip.
Check it out here:
https://vaadin.com/directory#!addon/validation-error-display

drawing rectangle in drawing issue

We are creating some graphical applications to the our project. We are using Draw2d and GEF technologies in our project. We have to draw one rectangle in the draw area. The functionality is as follows.
Use click the rectangle button from the toolbar.
Changes cursor to Cross curson symbol.
When the user clicks the area and drag the mouse, it shows the rectangle based on the dragging of the mouse.
Till now it is working fine. Now the issue is, we have zoom in and zoom out functionality.
When the use zoom in and draw the rectangle, it is not coming in the desired position.
It is going below parts of the area.Then user has to scroll and see the rectangle. This problem happens only when we use zoom in and zoom out.
How to ressolve this issue? Please see my code below.
package draw2dview;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.FreeformLayout;
import org.eclipse.draw2d.FreeformViewport;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.ScalableFigure;
import org.eclipse.draw2d.ScalableFreeformLayeredPane;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.editparts.ScalableRootEditPart;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.ui.actions.ZoomInAction;
import org.eclipse.gef.ui.actions.ZoomOutAction;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.part.ViewPart;
public class View extends ViewPart implements org.eclipse.swt.events.MouseListener {
public static final String ID = "draw2dview.view";
private Action drawAction;
private ScalableFreeformLayeredPane root;
ScalableRootEditPart editPart = null ;
private XYLayout layout;
private ZoomManager zoomManager ;
EditDomain editDomain = new DefaultEditDomain(null);
GraphicalViewer graphicalViewer = new ScrollingGraphicalViewer();
ScalableFreeformRootEditPart rootEditPart = new ScalableFreeformRootEditPart();
private FigureCanvas createContents(Composite parent){
root = new ScalableFreeformLayeredPane();
zoomManager = new ZoomManager(root,new FreeformViewport());
root.setFont(parent.getFont());
//layout = new XYLayout();
layout= new FreeformLayout();
root.setLayoutManager(layout);
FigureCanvas figureCanvas = new FigureCanvas(parent,SWT.DOUBLE_BUFFERED);
figureCanvas.addMouseListener(this);
figureCanvas.setBackground(ColorConstants.white);
LightweightSystem lws = new LightweightSystem(figureCanvas);
lws.setContents(root);
return figureCanvas ;
}
private IFigure createPersonFigure() {
RectangleFigure rectangleFigure = new RectangleFigure();
rectangleFigure.setBackgroundColor(ColorConstants.blue);
rectangleFigure.setLayoutManager(new ToolbarLayout());
rectangleFigure.setPreferredSize(100, 100);
return rectangleFigure ;
}
/**
* This is a callback that will allow us to create the viewer and initialize
* it.
*/
public void createPartControl(Composite parent) {
/* graphicalViewer.createControl(parent);
editDomain.addViewer(graphicalViewer);
graphicalViewer.setRootEditPart(rootEditPart);*/
createContents(parent);
createAction();
contributeToActionBars();
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
addToToolBar(bars.getToolBarManager());
}
private void addToToolBar(IToolBarManager toolBarManager2){
toolBarManager2.add(drawAction);
toolBarManager2.add(new ZoomInAction(zoomManager));
toolBarManager2.add(new ZoomOutAction(zoomManager));
}
private void createAction() {
drawAction = new Action() {
public void run() {
System.out.println("execued..");
}
};
drawAction.setText("Draw");
drawAction.setImageDescriptor(Activator.getImageDescriptor("icons/alt_window_16.gif"));
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
// viewer.getControl().setFocus();
}
#Override
public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) {
}
#Override
public void mouseDown(org.eclipse.swt.events.MouseEvent e) {
System.out.println("inside..Mousedeown:: "+e.x+","+e.y);
IFigure personFigure = createPersonFigure();
root.add(personFigure);
layout.setConstraint(personFigure, new Rectangle(new Point(e.x,e.y),personFigure.getPreferredSize()));
//layout.setConstraint(personFigure, new Rectangle(new Point(e.x,e.y),personFigure.getPreferredSize()));
}
#Override
public void mouseUp(org.eclipse.swt.events.MouseEvent e) {
}
}
You will need to scale your mouse event coordinates according to the zoom level your zoom manager is currently using. The mouse events are absolute pixels, but your ZoomManger is causing a scale factor to be applied to your figure's coordinates. I think you will also need to take into account your ViewPort's client area.
First, when you constuct your ZoomManager pass in the ViewPort from your FigureCanvas:
zoomManager = new ZoomManager(root, figureCanvas.getViewPort());
Then try something like:
double scaleFactor = zoomManager.getZoom();
Rectangle r = figureCanvas.getViewport().getClientArea();
layout.setConstraint(personFigure, new Rectangle(new Point((e.x + r.x) * scaleFactor,(e.y + r.y) * scaleFactor),personFigure.getPreferredSize()));
This may need tweaked to get it right, let me know....
You have to translate from absolute coordinates obtained from the mouse event to relative coordinates to the person figure's parent:
#Override
public void mouseDown(org.eclipse.swt.events.MouseEvent e) {
System.out.println("inside..Mousedeown:: "+e.x+","+e.y);
IFigure personFigure = createPersonFigure();
root.add(personFigure);
Point p = new PrecisionPoint(e.x,e.y);
personFigure.translateToRelative(p);
layout.setConstraint(personFigure, new Rectangle(p,personFigure.getPreferredSize()));
}
For more information look at draw2d help