Determing size of visible area of a ScrollingGraphicalViewer in Eclipse GEF - eclipse-rcp

I am attempting to create a simple application using Eclipse GEF that displays a diagram inside a ScrollingGraphicalViewer. On start-up I want the diagram to be centered inside the viewer (imagine a star layout where the center of the star is in the center of the view).
Here are what I think are the relevant code sections:
My view:
public class View extends ViewPart {
public static final String ID = "GEFProofOfConcept.view";
...
public void createPartControl(Composite parent) {
viewer.createControl(parent);
viewer.setRootEditPart(rootEditPart);
viewer.setEditPartFactory(editPartFactory);
viewer.setContents(DummyModelCreator.generateModel());
}
The edit part code:
#Override
protected void refreshVisuals() {
Project project = (Project) getModel();
// This is where the actual drawing is done,
// Simply a rectangle with text
Rectangle bounds = new Rectangle(50, 50, 75, 50);
getFigure().setBounds(bounds);
Label label = new Label(project.getName());
projectFont = new Font(null, "Arial", 6, SWT.NORMAL);
label.setFont(projectFont);
label.setTextAlignment(PositionConstants.CENTER);
label.setBounds(bounds.crop(IFigure.NO_INSETS));
getFigure().add(label);
setLocation();
}
private void setLocation() {
Project project = (Project) getModel();
if (project.isRoot()) {
// Place in centre of the layout
Point centrePoint = new Point(0, 0); // This is where I need the center of the view
getFigure().setLocation(centrePoint);
} else {
...
}
}
And the parent of the above edit part:
public class ProjectDependencyModelEditPart extends AbstractGraphicalEditPart {
#Override
protected IFigure createFigure() {
Figure f = new FreeformLayer();
f.setLayoutManager(new XYLayout());
return f;
}
...
Alternative solutions to the problem also welcome, I am most certainly a GEF (and Eclipse in general) newbie.

Worked it out, for anyone who's interested:
Dimension viewSize = (((FigureCanvas) getViewer().getControl()).getViewport().getSize());

Related

How do I get the clicked Box in JavaFX 3d

I've got a problem with my JavaFX 3D application. My application creates a grid consisting of different boxes. The data used for the boxes are from the harry potter books, which are transferred to nodes and then to boxes. Every box symbolizes one character. Now I want to add an event, that when a box is clicked application a window should open to show, which character it is and some other data.
"for (Book book : books) {
Node bookNode = new Node();
bookNode.setType(NodeType.BOOK);
bookNode.setName(book.getName());
bookNode.setMetric(getMetricFromPrimaryInt(book.getPages(),overallPages));
for (Chapter chapter : book.chapters) {
Node chapterNode = new Node();
chapterNode.setType(NodeType.CHAPTER);
chapterNode.setName(chapter.getName());
chapterNode.setMetric(getMetricFromPrimaryInt(chapter.getPages(), book.getPages()));
for (String character : chapter.characters) {
Node characterNode = new Node();
characterNode.setType(NodeType.CHARACTER);
characterNode.setName(character);
characterNode.setMetric(getMetricFromPrimaryInt(1, chapter.characters.length));
//Das neue child node dem parent hinzufügen
chapterNode.extendChildren(characterNode);
}
//Das neue child node dem parent hinzufügen
bookNode.extendChildren(chapterNode);
}"
.
.
.
"for (Node chars: chapt.getChildren()) {
double height = rnd.nextDouble() * 500;
Box box = new Box(chars.getHeight(), height, chars.getWidth());
// color
PhongMaterial mat = new PhongMaterial();
mat.setDiffuseColor(randomColor());
box.setMaterial(mat);
// location
box.setLayoutY(-height * 0.5);
box.setTranslateX(xStart-(chars.getHeight()/2));
box.setTranslateZ(yStart-(chars.getWidth()/2));
grid.getChildren().addAll(box);
Boxliste.add(box);
}"
My problem now is:
How do I differentiate which box got clicked, because I need the box to get the characterdata and then display it. Hope it's clear what I mean.
Casting Intersected Node with mouse event
In this approach getIntersectedNode() method from PickResult class will return a Node object . That object is casted to CustomSphere which extends Sphere and , like any other node in javafx , extends Node class .
This is a single javafx app you can try .
App.java
public class App extends Application {
#Override
public void start(Stage stage) {
Label label = new Label("name");
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setTranslateZ(-10);
Group group3d = new Group(camera, new CustomSphere("violet sphere ", Color.BLUEVIOLET, 0.8, 0),
new CustomSphere("coral sphere ", Color.CORAL, 0.7, 2),
new CustomSphere("yellow-green sphere ", Color.YELLOWGREEN, 0.9, -2));
SubScene subScene = new SubScene(group3d, 480, 320, true, SceneAntialiasing.DISABLED);
subScene.setOnMouseClicked(t -> {
PickResult result = t.getPickResult();
Node intersectedNode = result.getIntersectedNode();
if (intersectedNode instanceof CustomSphere) {
CustomSphere clickedSphere = (CustomSphere) intersectedNode;
label.setText(clickedSphere.getName());
}
});
subScene.setCamera(camera);
StackPane stackPane = new StackPane(subScene, label);
StackPane.setAlignment(label, Pos.TOP_CENTER);
Scene scene = new Scene(stackPane, 480, 320, true, SceneAntialiasing.BALANCED);
stage.setTitle("pickresult");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
class CustomSphere extends Sphere {
private String name;
PhongMaterial material = new PhongMaterial();
public CustomSphere(String name, Color color, double d, double x) {
super(d);
this.name = name;
material.setDiffuseColor(color);
this.setMaterial(material);
this.setTranslateX(x);
}
public String getName() {
return name;
}
}
}

i have written a code which shows image slideshow now i want to put a button on it how can i do that?

I have tried this code by setting setComponentZOrder() but it also did not worked please give me some suggestion how can i achieve this goal to make an image slideshow and put a button on it in jframe
import java.awt.Image;
import java.awt.*;
import java.awt.event.ActionListener;
import javafx.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.*;
public class slidemain extends JFrame {
JLabel jl;
JButton b;
Timer tm;
int x = 0;
int w;
int h;
String[] list = {
"C:\\Users\\HARITI\\Desktop\\sat.jpg",
"C:\\Users\\HARITI\\Desktop\\mtab.jpg",
"C:\\Users\\HARITI\\Desktop\\abc.jpg"
};
public slidemain()
{
super("java slide show");
// w = super.getWidth();
// h = super.getHeight();
jl = new JLabel();
b = new JButton();
//b.setVisible(true);
super.setComponentZOrder(jl, 0);
super.setComponentZOrder(b, 1);
jl.setBounds(0, 100, 1350, 650);
setImageSize(2);
tm = new Timer(1500, new ActionListener(){
#Override
public void actionPerformed(java.awt.event.ActionEvent e) {
setImageSize(x);
x += 1;
if (x >= list.length)
{
x = 0;
}
}
});
add(jl);
tm.start();
setLayout(null);
getContentPane().setBackground(Color.decode("#bdb67b"));
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void setImageSize(int i) {
ImageIcon icon = new ImageIcon(list[i]);
Image img = icon.getImage();
Image newimg = img.getScaledInstance(jl.getWidth(), jl.getHeight(), Image.SCALE_SMOOTH);
ImageIcon newimc = new ImageIcon(newimg);
jl.setIcon(newimc);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
new slidemain();
}
}
This...
super.setComponentZOrder(jl, 0);
super.setComponentZOrder(b, 1);
is going to have no affect if neither of the components have been added to the container yet.
Which brings us to your next problem, you never actually add the button to anything
And event if you did, it wouldn't be displayed, because you're using a null layout
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify.
Maybe have a look at Why is it frowned upon to use a null layout in SWING? for some more details

Cannot reduce size of RCP view when migrated to Eclipse 4

I'm currently working on migrating a set of eclipse RCP applications from 3.6 to 4.2.
I'm struggling with an issue with RCP perspectives that view height cannot be reduced below a certain size (looks like 10% from the window height).
The code works fine in eclipse 3.x and user can reduce the view height by dragging the border.
However, in 4.x the height of top most view (button view) can only be reduced upto a certain value.
Can anybody help with this, please?
public class Perspective implements IPerspectiveFactory {
public static final String ID = "im.rcpTest2.fixedperspective";
public void createInitialLayout(IPageLayout layout) {
String editorArea = layout.getEditorArea();
layout.setEditorAreaVisible(false);
layout.addStandaloneView(ButtonView.ID, false, IPageLayout.TOP,
0.1f, editorArea);
layout.addStandaloneView(View.ID, false, IPageLayout.LEFT,
0.25f, editorArea);
IFolderLayout folder = layout.createFolder("messages", IPageLayout.TOP,
0.5f, editorArea);
folder.addPlaceholder(View2.ID + ":*");
folder.addView(View2.ID+":2");
folder.addView(View2.ID+":3");
layout.getViewLayout(ButtonView.ID).setCloseable(false);
layout.getViewLayout(View.ID).setCloseable(false);
}
}
public class ButtonView extends ViewPart {
public ButtonView() {
}
public static final String ID = "im.rcptest2.ButtonView"; //$NON-NLS-1$
private Text text;
/**
* Create contents of the view part.
* #param parent
*/
#Override
public void createPartControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
container.setBackground(SWTResourceManager.getColor(SWT.COLOR_GRAY));
container.setLayout(new GridLayout(2, false));
text = new Text(container, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
{
Button btnMybutton = new Button(container, SWT.NONE);
btnMybutton.setText("MyButton");
}
}
#Override
public void setFocus() {
// TODO Auto-generated method stub
}
}
This looks like the value
int minSashPercent = 10;
in org.eclipse.e4.ui.workbench.renderers.swt.SashLayout
There does not seem to be a way to change this value. So the only thing you could do would be to write a custom Sash Renderer class by providing your own Renderer Factory.

How to get Menu or MenuItem width in JavaFX?

I am extending the default Menu and MenuItem class to add some animated effects to it.
The problem is that I need to know the width and height of the Menu and MenuItem I'm working on. This classes doesn't extend Node or Region so there are no public methods to get their size. The size is composed by the text size inside the MenuItem plus the corresponding default padding, I can calculate how much space the text takes, but I can't get how much padding the MenuItem has neither.
There is a method called impl_styleableGetNode() that returns a Node but it always returns null for me.
Is there anyway to get the size? MenuBar also doesn't seems to expose any helpful method for this.
EDIT:
Here is my class, I'm trying to implement this material design button into the Menu class. Basically I render all the button using the setGraphic() method. It's working perfectly but I'm using the Pane width which doesn't take into account the padding of the Menu so the effect is not complete.
public class MaterialDesignMenu extends Menu {
private Pane stackPane = new Pane();
private Label label = new Label();
private Circle circleRipple;
private Rectangle rippleClip = new Rectangle();
private Duration rippleDuration = Duration.millis(250);
private double lastRippleHeight = 0;
private double lastRippleWidth = 0;
private Color rippleColor = new Color(1, 0, 0, 0.3);
public MaterialDesignMenu() {
init("");
}
public MaterialDesignMenu(String text) {
init(text);
}
public MaterialDesignMenu(String text, Node graphic) {
init(text);
}
private void init(String text){
label.setText(text);
createRippleEffect();
stackPane.getChildren().addAll(circleRipple, label);
setGraphic(stackPane);
}
private void createRippleEffect() {
circleRipple = new Circle(0.1, rippleColor);
circleRipple.setOpacity(0.0);
// Optional box blur on ripple - smoother ripple effect
//circleRipple.setEffect(new BoxBlur(3, 3, 2));
// Fade effect bit longer to show edges on the end of animation
final FadeTransition fadeTransition = new FadeTransition(rippleDuration, circleRipple);
fadeTransition.setInterpolator(Interpolator.EASE_OUT);
fadeTransition.setFromValue(1.0);
fadeTransition.setToValue(0.0);
final Timeline scaleRippleTimeline = new Timeline();
final SequentialTransition parallelTransition = new SequentialTransition();
parallelTransition.getChildren().addAll(
scaleRippleTimeline,
fadeTransition
);
// When ripple transition is finished then reset circleRipple to starting point
parallelTransition.setOnFinished(event -> {
circleRipple.setOpacity(0.0);
circleRipple.setRadius(0.1);
});
stackPane.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
parallelTransition.stop();
// Manually fire finish event
parallelTransition.getOnFinished().handle(null);
circleRipple.setCenterX(event.getX());
circleRipple.setCenterY(event.getY());
// Recalculate ripple size if size of button from last time was changed
if (stackPane.getWidth() != lastRippleWidth || stackPane.getHeight() != lastRippleHeight) {
lastRippleWidth = stackPane.getWidth();
lastRippleHeight = stackPane.getHeight();
rippleClip.setWidth(lastRippleWidth);
rippleClip.setHeight(lastRippleHeight);
/*
// try block because of possible null of Background, fills ...
try {
rippleClip.setArcHeight(stackPane.getBackground().getFills().get(0).getRadii().getTopLeftHorizontalRadius());
rippleClip.setArcWidth(stackPane.getBackground().getFills().get(0).getRadii().getTopLeftHorizontalRadius());
circleRipple.setClip(rippleClip);
} catch (Exception e) {
e.printStackTrace();
}*/
circleRipple.setClip(rippleClip);
// Getting 45% of longest button's length, because we want edge of ripple effect always visible
double circleRippleRadius = Math.max(stackPane.getHeight(), stackPane.getWidth()) * 0.45;
final KeyValue keyValue = new KeyValue(circleRipple.radiusProperty(), circleRippleRadius, Interpolator.EASE_OUT);
final KeyFrame keyFrame = new KeyFrame(rippleDuration, keyValue);
scaleRippleTimeline.getKeyFrames().clear();
scaleRippleTimeline.getKeyFrames().add(keyFrame);
}
parallelTransition.playFromStart();
});
}
public void setRippleColor(Color color) {
circleRipple.setFill(color);
}
}
First you have to listen to parentPopupProperty changes of MenuItem. When you get the instance of parent popup than register listener for skinProperty of ContextMenu (parentPopup). When you get the skin then you can get MenuItemContainer which is Node equivalent of MenuItem and you can listen to widthProperty or heightProperty changes of MenuItemContainer.
Note: skinProperty change is fired just before ContextMenu is shown on the screen.
Custom class extending MenuItem class:
public class CstMenuItem extends MenuItem {
public CstMenuItem() {
// Create custom menu item listener.
new CstMenuItemListener(this);
}
/*
* Returns MenuItemContainer node associated with this menu item
* which can contain:
* 1. label node of type Label for displaying menu item text,
* 2. right node of type Label for displaying accelerator text,
* or an arrow if it's a Menu,
* 3. graphic node for displaying menu item icon, and
* 4. left node for displaying either radio button or check box.
*
* This is basically rewritten impl_styleableGetNode() which
* should not be used since it's marked as deprecated.
*/
public ContextMenuContent.MenuItemContainer getAssociatedNode() {
ContextMenu contextMenu = getParentPopup();
ContextMenuSkin skin = (ContextMenuSkin) contextMenu.getSkin();
ContextMenuContent content = (ContextMenuContent) skin.getNode();
// Items container contains MenuItemContainer nodes and Separator nodes.
Parent itemsContainer = content.getItemsContainer();
List<Node> children = itemsContainer.getChildrenUnmodifiable();
for (Node child : children) {
if (child instanceof ContextMenuContent.MenuItemContainer) {
ContextMenuContent.MenuItemContainer menuItemContainer =
(ContextMenuContent.MenuItemContainer) child;
if (menuItemContainer.getItem() == this) {
return menuItemContainer;
}
}
}
return null;
}
}
Custom MenuItem listener class:
public class CstMenuItemListener implements ChangeListener {
private CstMenuItem menuItem;
private ContextMenu parentPopup;
private Region menuItemContainer;
public CstMenuItemListener(CstMenuItem menuItem) {
this.menuItem = menuItem;
menuItem.parentPopupProperty().addListener(this);
}
#Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
if (observable == menuItem.parentPopupProperty()) {
parentPopup = (ContextMenu) newValue;
parentPopup.skinProperty().addListener(this);
} else if (observable == parentPopup.skinProperty()) {
menuItemContainer = menuItem.getAssociatedNode();
menuItemContainer.widthProperty().addListener(this);
menuItemContainer.heightProperty().addListener(this);
} else if (observable == menuItemContainer.widthProperty()) {
System.out.println("width: " + (double) newValue);
} else if (observable == menuItemContainer.heightProperty()) {
System.out.println("height: " + (double) newValue);
}
}
}

objects cannot be dragged - with dnd gwt query

I created the follow grid of label that i want thme to be draggable:
public static Grid setLabels (String [] str){
Label [] lbl = new Label [str.length];
Grid grid = new Grid(5,1);
CellFormatter cellFormatter = grid.getCellFormatter();
for(int i=0; i<str.length; i++){
lbl[i] = new Label();
lbl[i].setText(str[i]);
DraggableWidget<Label> draggableLabel = new DraggableWidget<Label>(lbl[i]);
draggableLabel.setRevert(RevertOption.ON_INVALID_DROP);
draggableLabel.setDraggingZIndex(100);
draggableLabel.setDraggingCursor(Cursor.MOVE);
grid.setWidget(i, 0, draggableLabel);
cellFormatter.setHeight(i, 0, "50px");
}
return grid;
}
Then the grid is added on a Panel. Everything is displayed ok.
Then I create a dropable widget.
public static void createDND(){
final Label moveHere = new Label("Move here!");
DroppableWidget<Label> dnd1 = new DroppableWidget<Label>(moveHere);
dnd1.addDropHandler(new DropEventHandler() {
public void onDrop(DropEvent event) {
Widget droppedLabel= event.getDraggableWidget();
moveHere.setText("");
}
});
dndPanel1.add(dnd1);
}
But the labels cannot be dragged and dropped. I feel sth is missing but I can't figure out what.
I would say go NATIVE and make use of GWT HTML5 Drag and Drop support. You also have a sample project set up in GWT source code samples.
Demo - http://gwt-cloudtasks.appspot.com/
Also Refer - Drag and Drop in GWT 2.4