I am using os x 10.6.8, java 6, and orient 2.0.12. I have noticed the following behavior after executing this code:
package orientdb;
import java.io.File;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
public class testEdge {
public static void main(String[] args){
try{
File f = new File(System.getProperty("user.home") + File.separator + "edgeTest");
if (f.exists())
f.delete();
f.mkdirs();
OrientGraph g = new OrientGraph("plocal:" + f.getAbsolutePath());
g.begin();
Vertex v = g.addVertex(null);
Vertex v1 = g.addVertex(null);
Edge e = v.addEdge("2k", v1);
g.commit();
g.shutdown();
}
catch(Exception x){
x.printStackTrace();
}
}
}
I open studio and execute "select from e". The edge label reflected is "-2k" instead of "2k". If the label does not contain digits it does not occur.
Is this a constraint?
Thanks a lot!
Yes, it is. Edge's label is a OrientDB class that extends E (base class for Edges).
Related
I'm making a syntax highlighting plugin for my company. I'm not making a new editor, I am using an eclipse template that uses the Extensions for generic editor.
Disclaimer: I've had a lot of trouble getting XText to work consistently on 3 different machines due to versioning issues, missing files etc. so that's out of the question
org.eclipse.ui.genericeditor.presentationReconcilers
org.eclipse.ui.genericeditor.contentTypes
org.eclipse.ui.genericeditor.hoverProviders
org.eclipse.ui.genericeditor.contentAssistProcessors
org.eclipse.ui.editors
org.eclipse.core.filebuffers.documentSetup
I'm using I'm having some odd issues. Before I get started:
The plugin is detected in Help > About Eclipse > Installation Details > Plugins
Other sample plugins run using the same method i used to run this plugin
Problems:
I'm getting the following error message when placing any content in
the file except <?xml version='1.0'>:
"Content is not allowed in Prolog"
The keywords seem to be highlighted in Blue. As you can see in my
source code, they should be highlighted in red.
Click here to view what my runtime Eclipe editor looks like
when i'm trying to test my syntax rules.
Below are my classes source code.
I'm wondering:
why my keywords are being recognized in syntax coloring but are
invalid commands with that "prolog" error above
Why the prolog errors above are occurring
Why it's validating the file not to my specification or to a different specification
Point me in the right direction
Hope you can help.
Thanks :).
Reconciler Class:
package myplugin;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
public class MyReconciler extends PresentationReconciler {
public MyReconciler() {
// TODO this is logic for .project file to color tags in blue. Replace with your language logic!
MyScanner scanner = new MyScanner(new SyntaxColorProvider());
DefaultDamagerRepairer dr= new DefaultDamagerRepairer(scanner);
this.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
this.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
}
}
Scanner class:
package myplugin;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
import org.eclipse.jface.text.rules.EndOfLineRule;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.IWordDetector;
import org.eclipse.jface.text.rules.MultiLineRule;
import org.eclipse.jface.text.rules.PatternRule;
import org.eclipse.jface.text.rules.SingleLineRule;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WhitespaceRule;
import org.eclipse.jface.text.rules.WordRule;
public class MyScanner extends BufferedRuleBasedScanner
{
private static String[] misc = {
true",
"false",
"unsigned",
"jump",
"read",
"write",
};
// Tokens
private final IToken KEYWORD_TOKEN;
private List<IRule> basicRules;
public MyScanner(SyntaxColorProvider colorProvider)
{
super(5000);
// CREATE TOKENS
KEYWORD_TOKEN = new Token(new TextAttribute(colorProvider.getColor(SyntaxColorProvider.KEYWORD)));
// CREATE RULES
List rules = new ArrayList<IRule>();
// Add rule for strings and character constants.
rules.add(new SingleLineRule("\"", "\"", STRING_TOKEN, '\\'));
rules.add(new SingleLineRule("'", "'", STRING_TOKEN, '\\'));
// Add word rule for keywords, types, and constants.
WordRule wordRule = new WordRule(new WordDetector(), OTHER_TOKEN);
// Single-line comments
rules.add(new EndOfLineRule("//", STRING_TOKEN));
// Multi-line comments
rules.add(new MultiLineRule("/$", "$/", COMMENT_TOKEN));
// KEYWORDS
for (String misc : misc)
{
wordRule.addWord(misc, KEYWORD_TOKEN);
}
rules.add(wordRule);
IRule[] result= new IRule[rules.size()];
rules.toArray(result);
setRules(result);
}
}
ValidatorDocumentSetupParticipant:
package myplugin;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
import org.eclipse.core.filebuffers.IDocumentSetupParticipantExtension;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
public class ValidatorDocumentSetupParticipant implements IDocumentSetupParticipant, IDocumentSetupParticipantExtension {
private final class DocumentValidator implements IDocumentListener {
private final IFile file;
private IMarker marker;
private DocumentValidator(IFile file) {
this.file = file;
}
#Override
public void documentChanged(DocumentEvent event) {
if (this.marker != null) {
try {
this.marker.delete();
} catch (CoreException e) {
e.printStackTrace();
}
this.marker = null;
}
try (StringReader reader = new StringReader(event.getDocument().get());) {
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
documentBuilder.parse(new InputSource(reader));
} catch (Exception ex) {
try {
this.marker = file.createMarker(IMarker.PROBLEM);
this.marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
this.marker.setAttribute(IMarker.MESSAGE, ex.getMessage());
if (ex instanceof SAXParseException) {
SAXParseException saxParseException = (SAXParseException)ex;
int lineNumber = saxParseException.getLineNumber();
int offset = event.getDocument().getLineInformation(lineNumber - 1).getOffset() + saxParseException.getColumnNumber() - 1;
this.marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
this.marker.setAttribute(IMarker.CHAR_START, offset);
this.marker.setAttribute(IMarker.CHAR_END, offset + 1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void documentAboutToBeChanged(DocumentEvent event) {
}
}
#Override
public void setup(IDocument document) {
}
#Override
public void setup(IDocument document, IPath location, LocationKind locationKind) {
if (locationKind == LocationKind.IFILE) {
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(location);
document.addDocumentListener(new DocumentValidator(file));
}
WordDetector Class:
package myplugin;
import org.eclipse.jface.text.rules.IWordDetector;
public class WordDetector implements IWordDetector
{
public boolean isWordPart(char character) {
return Character.isJavaIdentifierPart(character);
}
public boolean isWordStart(char character) {
return Character.isJavaIdentifierStart(character);
}
}
SyntaxColorProvider Class:
package myplugin;
import java.util.HashMap;
public class SyntaxColorProvider
{
public static final RGB RED = new RGB(200, 0, 0);
public static final RGB GREEN = new RGB(0, 200, 0);
public static final RGB BLUE = new RGB(0, 0, 200);
public static final RGB COMMENT = new RGB(128, 128, 128);
public static final RGB KEYWORD = new RGB(255, 0, 0);
public static final RGB TYPE = new RGB(0, 0, 128);
public static final RGB STRING = new RGB(0, 128, 0);
public static final RGB DEFAULT = new RGB(0, 0, 0);
protected Map fColorTable = new HashMap(10);
/**
* Release all of the color resources held onto by the receiver.
*/
public void dispose()
{
Iterator e = fColorTable.values().iterator();
while (e.hasNext())
((Color) e.next()).dispose();
}
/**
* Return the Color that is stored in the Color table as rgb.
*/
public Color getColor(RGB rgb)
{
Color color = (Color) fColorTable.get(rgb);
if (color == null)
{
color = new Color(Display.getCurrent(), rgb);
fColorTable.put(rgb, color);
}
return color;
}
This looks like the sample editor with some changes - and
documentBuilder.parse(new InputSource(reader));
would be parsing XML, perhaps. It detects improper XML because the prolog is missing. Remove that line from the code, or implement something that flags up and marks issues similarly.
Ok so I've struggled with the same probelm the function that makes this problem is in this line: documentBuilder.parse(new InputSource(reader));, Im in the middle of trying to figure out a text parser by myself.
I'm running Wicket 7.5.0 and wicketstuff-tinymcr with the same version.
Im trying to initialize a tinyMce editor but I get this error:
Failed to load:
http://localhost:8080/mywebapp/wicket/resource/wicket.contrib.tinymce4.TinyMceBehavior/tinymce/langs/sv.js
The tiny script is loaded though:
http://localhost:8080/mywebapp/wicket/resource/wicket.contrib.tinymce4.TinyMceBehavior/tinymce/tinymce-ver-1481290207000.js
This seems to be loaded:
plugins/...
themes/...
./tinymce-ver-1481290207000.js
EDIT
This took care of it:
addCustomSetting("language: \"sv_SE\"");
This are the classes that loads it all:
import wicket.contrib.tinymce4.settings.TinyMCESettings;
public class MyTinyMCESettings extends TinyMCESettings {
public MyTinyMCESettings(TinyMCESettings.Theme theme) {
super(theme);
addCustomSetting("plugins: 'autoresize'");
addCustomSetting("language: \"sv_SE\""); // this works
}
}
The other one:
import org.apache.wicket.Component;
import wicket.contrib.tinymce4.TinyMceBehavior;
import wicket.contrib.tinymce4.settings.TinyMCESettings;
public class MyTinyMceBehavior extends TinyMceBehavior {
public static final String KEY_EVENT = "keyup";
private Component component;
private TinyMCESettings settings;
public MyTinyMceBehavior(TinyMCESettings settings) {
super(settings);
this.settings = settings;
}
#Override
protected String getScript(TinyMCESettings.Mode mode, Collection<Component> components) {
StringBuilder script = new StringBuilder();
script.append(" tinyMCE.init({")
.append(settings.toJavaScript(mode, components))
.append(",onchange_callback : function (ed) {\n" +
" var text = ed.getContent();" +
" $('#" + component.getMarkupId() + "').html(text).trigger('" + KEY_EVENT + "');" +
"}")
.append("});\n");
return script.toString();
}
}
It seems TinyMCESettings detects 'SV' locale and tries to set the language: https://github.com/wicketstuff/core/blob/7db920363a8e0254b33b8deccee95688dd922aa5/tinymce4-parent/tinymce4/src/main/java/wicket/contrib/tinymce4/settings/TinyMCESettings.java#L262
Set it explicitly to null in the settings and it won't try to load it.
Made an edit with code that works.
I'm new at Java Programming and have "beginner Question".
I already tried to find wether someone already had the same problem, but I couldn't find any posts which were on my low level.
My Problem:
I have 2 JPanels in one of them, (let's call it Panel1) I implements a JTextField (field1) and a JButton (button1). on Panel2 I want to draw something, depending on what the using tipped in the first JTextField.
My Problem is I want Panel2 to "see" that button1 (in Panel1) , which I don't manage to do.
Can anyone give me a hint, a Youtube Video or something like that, where I can see a nice example where someone handles such a Problem?
Greetings Ventura
P.S I had an idea to pass values to Panel2 where it should draw those things I want, here my code up so far (I hope I post it correctly): Here Panel1:
public class Panel1 extends JPanel
{
public JButton button = new JButton("OK");
public JTextField field1 = new JTextField(5);
public String name;int b;
public Panel1()
{
setBackground(Color.WHITE);
add(field1);
add(button);
ButtonListener listener = new ButtonListener(field1);
button.addActionListener(listener);
}
public Dimension getPreferredSize()
{
return new Dimension(400,400);
}
}
Here the ButtonListener :
class ButtonListener implements ActionListener
{
Graphics g;
//Graphics2D g2 = (Graphics2D) g;
public Panel2 pan2 = new Panel2();
public String name;
public JTextField field1 = new JTextField();
int b;
public ButtonListener(JTextField field1)
{this.field1 = field1;}
public void actionPerformed(ActionEvent e)
{
String op = e.getActionCommand();
if(op.equals("OK"))
{
name = field1.getText();
try
{
b = Integer.parseInt(name);
JOptionPane.showMessageDialog(null,"Ihre Zahl = "+b);
pan2.setvalue(b,g);
}
catch(NumberFormatException ex) {JOptionPane.showMessageDialog(null,"Please enter real numbers!");}
}
}
}
And finally Panel2 where I'd like to draw things based on the Input given in Panel1 (for example: I type in 10 and he draws me a Rectangle with width 10 or something like that)
public class Panel2 extends JPanel
{
Graphics g;
Graphics2D g2 = (Graphics2D) g;
public int b;
public Panel2()
{
setBackground(Color.YELLOW);
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g);
g2.setColor(Color.RED);
g2.fillRect(200, 200, 50, 50);
Paint2(g);
}
public void Paint2(Graphics g)
{
this.g = g;
Graphics2D g2 = (Graphics2D) g;
//super.paintComponent(g);
System.out.println("TEST2");
g2.setColor(Color.BLUE);
//System.out.println("TEST3");
g2.fillRect(10 , 10, 40, 40);
}
public void setvalue(int b, Graphics g)
{
this.b = b;
this.g = g;
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.CYAN);
g2.fillRect(0, 0, 40, 40);
System.out.println("B ist gleich = "+b);
//Paint2(g2);
}
public Dimension getPreferredSize()
{
return new Dimension(400,400);
}
I'm sorry if it is a little cumbersome to read.
My basic Problem I get in this code is the NullpointerException in Panel2 when I want to call the Method
setvalue(int b, Graphics g)
g2.setColor(Color.Cyan)
Greetings Patrick
I did a redesign to most of Panel1 and a little bit to Panel2.
I'm going to start with Panel2 because it's simpler. Here is the new code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Panel2 extends JPanel {
Graphics g;
Graphics2D g2;
public int b;
public Panel2() {
setBackground(Color.YELLOW);
b = 50;
}
#Override
public void paintComponent(Graphics g) {
g2 = (Graphics2D) g;
super.paintComponent(g);
g2.setColor(Color.RED);
g2.fillRect(200, 200, 50, 50);
g2.setColor(Color.BLUE);
g2.fillRect(10, 10, 40, 40);
g2.setColor(Color.CYAN);
g2.fillRect(b, b, 40, 40);
}
public void setValue(int b) {
this.b = b;
System.out.println("B ist gleich = " + b);
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
The biggest change that I made to Panel2 is that I made g2 a class variable that all the methods can use. Instead of making the methods take a Graphics variable each time, I just made it so that they can use the one from the class. I also didn't make a new Graphics2D variable "equal" anything each time the method was called because there was no need for that. The only place I updated it in was the paintComponent() method so that I could update it once for the whole class.
Next up is Panel1. Here is the code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Panel1 extends JPanel {
public JButton button = new JButton("OK");
public JTextField field1 = new JTextField(5);
public String name;
int b;
private Panel2 pan2;
public Panel1() {
setBackground(Color.WHITE);
add(field1);
add(button);
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String op = e.getActionCommand();
if (op.equals("OK")) {
name = field1.getText();
try {
b = Integer.parseInt(name);
pan2.setValue(b);
JOptionPane.showMessageDialog(null, "Ihre Zahl = " + b);
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(null, "Please enter real numbers!");
}
}
}
};
button.addActionListener(listener);
}
public void setSecondPanel(Panel2 panel) {
pan2 = panel;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
Panel1 pan1 = new Panel1();
Panel2 pan2 = new Panel2();
pan1.setSecondPanel(pan2);
frame.setSize(pan1.getPreferredSize().width + pan2.getPreferredSize().width, pan1.getPreferredSize().height);
frame.add(pan2, BorderLayout.EAST);
frame.add(pan1, BorderLayout.WEST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
First of all, notice how I didn't create a ButtonListener. Because you're only using it once, there's no need to create a new class for it (it's also less code).
In the main() method, I made it so that it adds both panels to the opposite sides so that they won't overlap each other or anything.
Finally, I created a setSecondPanel method in the Panel1 class so that the class would have a Panel2 variable to work with at any time.
I'm testing key handlers, and I ran into a problem.
In its barest form, I have the following code:
mainScene.setOnKeyPressed( event -> {
System.out.println("Handler called for: " + event.getCode());
});
As expected, when a key is pressed, it prints out the associated code.
The problem is, if I hold 2 keys at once, only the last key pressed generates constant events. I want to be able to add pressed keys to a queue to be dealt with elsewhere, but only the last key pressed will be added to the queue.
Is there any way to change this behavior?
The only workaround I could find was to use a map to record codes, and set up a separate pressed and released handler to add/remove codes from the map. This works, but requires constant polling of every key I may need to react to, instead of being able to just check if the pressed-key queue is empty.
I suspect the JVM is receiving the key pressed event from the operating system, so the repeat-key behavior when you hold two keys down is determined at the OS level.
To manage your own key press repeats, you can use a timeline with an indefinite cycle count; start the timeline when the key is pressed and stop it when the key is released. You will probably need to manage these in a Map<KeyCode, Timeline> to handle multiple keys. Have the timelines call a method and pass the key code for central handling of the key presses: this will avoid the need for polling.
SSCCE:
import java.util.HashMap;
import java.util.Map;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.util.Duration;
public class MultiRepeatKey extends Application {
#Override
public void start(Stage primaryStage) {
Scene scene = new Scene(new Pane(), 400, 400);
Map<KeyCode, Timeline> keyRepeats = new HashMap<>();
Duration keyPressDelay = Duration.millis(200);
scene.setOnKeyPressed(e -> {
if (! keyRepeats.containsKey(e.getCode())) {
Timeline repeat = new Timeline(new KeyFrame(Duration.ZERO, event -> processKey(e.getCode())),
new KeyFrame(keyPressDelay));
repeat.setCycleCount(Animation.INDEFINITE);
repeat.play();
keyRepeats.put(e.getCode(), repeat);
}
});
scene.setOnKeyReleased(e -> {
if (keyRepeats.containsKey(e.getCode())) {
Timeline repeat = keyRepeats.get(e.getCode());
repeat.stop();
keyRepeats.remove(e.getCode());
}
});
primaryStage.setScene(scene);
primaryStage.show();
}
private void processKey(KeyCode code) {
System.out.println(code.getName());
}
public static void main(String[] args) {
launch(args);
}
}
Depending on your use case, another option that may make sense for you is to just keep a Map from keys to some representation of the functionality you want, and then to keep a Set of the implementations of those functionality. Then use an AnimationTimer to update the UI depending on which keys are pressed. (An AnimationTimerexecutes its handle method on each frame rendering; the parameter passed in is a timestamp in nanoseconds.).
Obviously if you had many mappings, you would define the mappings elsewhere, but here is the idea:
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.DoubleFunction;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class MultiRepeatKey extends Application {
#Override
public void start(Stage primaryStage) {
Rectangle rect = new Rectangle(20, 20, 50, 50);
rect.setFill(Color.CORNFLOWERBLUE);
Pane pane = new Pane(rect);
Set<DoubleFunction<Point2D>> motions = new HashSet<>();
Map<KeyCode, DoubleFunction<Point2D>> keyMappings = new HashMap<>();
keyMappings.put(KeyCode.UP, delta -> new Point2D(0, -delta));
keyMappings.put(KeyCode.DOWN, delta -> new Point2D(0, delta));
keyMappings.put(KeyCode.LEFT, delta -> new Point2D(-delta, 0));
keyMappings.put(KeyCode.RIGHT, delta -> new Point2D(delta, 0));
double speed = 150.0 ; // pixels / second
AnimationTimer anim = new AnimationTimer() {
private long lastUpdate = 0 ;
#Override
public void handle(long now) {
if (lastUpdate > 0) {
double elapsedSeconds = (now - lastUpdate) / 1_000_000_000.0 ;
double delta = speed * elapsedSeconds ;
Point2D loc = motions.stream()
.map(m -> m.apply(delta))
.reduce(new Point2D(rect.getX(), rect.getY()), Point2D::add);
loc = clamp(loc, 0, 0, pane.getWidth() - rect.getWidth(), pane.getHeight() - rect.getHeight());
rect.setX(loc.getX());
rect.setY(loc.getY());
}
lastUpdate = now ;
}
};
anim.start();
Scene scene = new Scene(pane, 400, 400);
scene.setOnKeyPressed(e -> motions.add(keyMappings.get(e.getCode())));
scene.setOnKeyReleased(e -> motions.remove(keyMappings.get(e.getCode())));
primaryStage.setScene(scene);
primaryStage.show();
}
private Point2D clamp(Point2D p, double minX, double minY, double maxX, double maxY) {
if (p.getX() < minX) {
p = new Point2D(minX, p.getY());
} else if (p.getX() > maxX) {
p = new Point2D(maxX, p.getY());
}
if (p.getY() < minY) {
p = new Point2D(p.getX(), minY);
} else if (p.getY() > maxY) {
p = new Point2D(p.getX(), maxY);
}
return p ;
}
public static void main(String[] args) {
launch(args);
}
}
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