Воссоздание ранее созданных элементов по созданию новых элементов SWT Draw2d
Я написал код, который позволяет перетаскивать на холст. При "отбрасывании" RectangleFigure рисуется на холсте в этой точке. Проблема в том, что, когда я падаю на холст во второй раз, на экране создается еще одна копия первого отброшенного элемента. Точно так же, в третий раз, первые два элемента воссоздаются (мы знаем, что это правда, потому что если вы перетаскиваете один из элементов из его исходного положения, вы можете увидеть воссозданные элементы под ним). Может кто-нибудь сказать, пожалуйста, как предотвратить этот отдых? * Я добавил короткий тестируемый код, иллюстрирующий проблему
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.MouseMotionListener;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.wb.swt.SWTResourceManager;
import org.eclipse.swt.widgets.Label;
/**
*
*Shortest complete testable code demonstrating the repeated creation problem
*/
public class RepeatDrop
{
/**
* Launch the application.
*
* @param args
*/
private Shell shell;
private Display display;
private Menu menu;
private Group grpPalette;
private final Label lblUnicorn;
private Group grpCanvas;
private final Canvas canvas;
public static void main(String args[]) {
new RepeatDrop();
}
/**
* Create the shell.
*
* @param display
*/
public RepeatDrop() {
display = new Display();
shell = new Shell(display);
shell.setText("SWT Application");
shell.setSize(450, 393);
Group grpPalette = new Group(shell, SWT.NONE);
grpPalette.setText("Palette");
grpPalette.setBounds(0, 0, 88, 325);
lblUnicorn = new Label(grpPalette, SWT.BORDER | SWT.HORIZONTAL
| SWT.CENTER);
lblUnicorn.setText("UNICORN");
// ADDED A FINAL HERE!!
lblUnicorn.setAlignment(SWT.CENTER);
lblUnicorn.setBounds(10, 24, 68, 53);
final Group grpCanvas = new Group(shell, SWT.NONE);
grpCanvas.setText("Canvas");
grpCanvas.setBounds(94, 0, 330, 325);
canvas = new Canvas(grpCanvas, SWT.NONE);
canvas.setBackground(SWTResourceManager.getColor(253, 245, 230));
canvas.setBounds(10, 20, 320, 295);
LightweightSystem lws = new LightweightSystem(canvas); //
final IFigure panel = new Figure(); //
lws.setContents(panel); //
DragSource dragSource1 = new DragSource(lblUnicorn, DND.DROP_COPY);
Transfer[] transfers1 = new Transfer[] { TextTransfer.getInstance() };
dragSource1.setTransfer(transfers1);
dragSource1.addDragListener(new DragSourceListener() {
public void dragStart(DragSourceEvent event) {
if (lblUnicorn.getText().length() == 0) {
event.doit = false;
}
}
public void dragSetData(DragSourceEvent event) {
if (TextTransfer.getInstance().isSupportedType (event.dataType)) {
event.data = lblUnicorn.getText();
}
}
public void dragFinished(DragSourceEvent event) {
}
});
Transfer[] types = new Transfer[] { TextTransfer.getInstance() };
DropTarget dropTarget = new DropTarget(canvas, DND.DROP_COPY
| DND.DROP_DEFAULT);
dropTarget.setTransfer(types);
dropTarget.addDropListener(new DropTargetListener() {
public void dragEnter(DropTargetEvent event) {
if (event.detail == DND.DROP_DEFAULT) {
if ((event.operations & DND.DROP_COPY) != 0) {
event.detail = DND.DROP_COPY;
} else {
event.detail = DND.DROP_NONE;
}
}
}
public void dragLeave(DropTargetEvent event) {
}
public void dragOperationChanged(DropTargetEvent event) {
}
public void dragOver(DropTargetEvent event) {
}
public void drop(DropTargetEvent event) {
}
public void dropAccept(final DropTargetEvent event)
{
if (TextTransfer.getInstance().isSupportedType(
event.currentDataType)) {
String d = (String) TextTransfer.getInstance()
.nativeToJava(event.currentDataType);
final String finald= d;
GC gc = new GC(canvas);
canvas.redraw();
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
org.eclipse.swt.graphics.Point droppoint = canvas.toControl(event.x, event.y);
//DRAW 2D SECTION
RectangleFigure node1 = new RectangleFigure();
Rectangle rect=new Rectangle(droppoint.x, droppoint.y, 20, 20);
Rectangle rect2=new Rectangle(droppoint.x, droppoint.y, 100, 25);
node1.setBounds(rect);
node1.setBackgroundColor(ColorConstants.cyan);
org.eclipse.draw2d.Label droppedName=
new org.eclipse.draw2d.Label(finald);
droppedName.setLocation(new Point(droppoint.x, droppoint.y)); //draw2d. point
droppedName.setBounds(rect2);
node1.add(droppedName);
panel.add(node1);
panel.add(droppedName);
Dragger fig = new Dragger(node1);
Dragger caption = new Dragger(droppedName);
//DRAW 2D SECTION
}
});
}
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
static class Dragger extends MouseMotionListener.Stub implements MouseListener
{
public Dragger(IFigure figure){
figure.addMouseMotionListener(this);
figure.addMouseListener(this);
}
Point last;
public void mouseReleased(MouseEvent e){
}
public void mouseClicked(MouseEvent e){
}
public void mouseDoubleClicked(MouseEvent e){
}
public void mousePressed(MouseEvent e){
last = e.getLocation();
}
public void mouseDragged(MouseEvent e){
Point p = e.getLocation();
Dimension delta = p.getDifference(last);
{
last = p;
Figure f = ((Figure)e.getSource());
f.setBounds(f.getBounds().getTranslated(delta.width, delta.height));
}
}
}
}
1 ответ
Ваша проблема вызвана тем, что вы добавляете новый PaintListener
каждый раз, когда вы добавляете новую фигуру. Это не обязательно. На самом деле, вам не нужно добавлять какие-либо PaintListener
совсем. LightweightSystem
позабочусь об этом за вас.
Вот ваш код теперь работает нормально:
public class RepeatDrop
{
private Shell shell;
private Display display;
private final Label lblUnicorn;
private final Canvas canvas;
public static void main(String args[])
{
new RepeatDrop();
}
public RepeatDrop()
{
display = new Display();
shell = new Shell(display);
shell.setText("SWT Application");
shell.setLayout(new GridLayout(2, false));
Group grpPalette = new Group(shell, SWT.NONE);
grpPalette.setText("Palette");
grpPalette.setLayout(new GridLayout());
grpPalette.setLayoutData(new GridData(SWT.BEGINNING, SWT.FILL, false, true));
lblUnicorn = new Label(grpPalette, SWT.BORDER | SWT.HORIZONTAL | SWT.CENTER);
lblUnicorn.setText("UNICORN");
// ADDED A FINAL HERE!!
lblUnicorn.setAlignment(SWT.CENTER);
final Group grpCanvas = new Group(shell, SWT.NONE);
grpCanvas.setText("Canvas");
grpCanvas.setLayout(new GridLayout());
grpCanvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
canvas = new Canvas(grpCanvas, SWT.NONE);
canvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
LightweightSystem lws = new LightweightSystem(canvas); //
final IFigure panel = new Figure(); //
lws.setContents(panel); //
DragSource dragSource1 = new DragSource(lblUnicorn, DND.DROP_COPY);
Transfer[] transfers1 = new Transfer[] { TextTransfer.getInstance() };
dragSource1.setTransfer(transfers1);
dragSource1.addDragListener(new DragSourceListener()
{
public void dragStart(DragSourceEvent event)
{
if (lblUnicorn.getText().length() == 0)
{
event.doit = false;
}
}
public void dragSetData(DragSourceEvent event)
{
if (TextTransfer.getInstance().isSupportedType(event.dataType))
{
event.data = lblUnicorn.getText();
}
}
public void dragFinished(DragSourceEvent event)
{
}
});
Transfer[] types = new Transfer[] { TextTransfer.getInstance() };
DropTarget dropTarget = new DropTarget(canvas, DND.DROP_COPY | DND.DROP_DEFAULT);
dropTarget.setTransfer(types);
dropTarget.addDropListener(new DropTargetListener()
{
public void dragEnter(DropTargetEvent event)
{
if (event.detail == DND.DROP_DEFAULT)
{
if ((event.operations & DND.DROP_COPY) != 0)
{
event.detail = DND.DROP_COPY;
}
else
{
event.detail = DND.DROP_NONE;
}
}
}
public void dragLeave(DropTargetEvent event)
{
}
public void dragOperationChanged(DropTargetEvent event)
{
}
public void dragOver(DropTargetEvent event)
{
}
public void drop(DropTargetEvent event)
{
}
public void dropAccept(final DropTargetEvent event)
{
if (TextTransfer.getInstance().isSupportedType(event.currentDataType))
{
String d = (String) TextTransfer.getInstance().nativeToJava(event.currentDataType);
org.eclipse.swt.graphics.Point droppoint = canvas.toControl(event.x, event.y);
// DRAW 2D SECTION
RectangleFigure node1 = new RectangleFigure();
Rectangle rect = new Rectangle(droppoint.x, droppoint.y, 20, 20);
Rectangle rect2 = new Rectangle(droppoint.x, droppoint.y, 100, 25);
node1.setBounds(rect);
node1.setBackgroundColor(ColorConstants.cyan);
org.eclipse.draw2d.Label droppedName = new org.eclipse.draw2d.Label(d);
droppedName.setLocation(new Point(droppoint.x, droppoint.y)); // draw2d.
// point
droppedName.setBounds(rect2);
node1.add(droppedName);
panel.add(node1);
panel.add(droppedName);
new Dragger(node1);
new Dragger(droppedName);
canvas.redraw();
}
}
});
shell.pack();
shell.setSize(400, 300);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
}
static class Dragger extends MouseMotionListener.Stub implements MouseListener
{
public Dragger(IFigure figure)
{
figure.addMouseMotionListener(this);
figure.addMouseListener(this);
}
Point last;
public void mouseReleased(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseDoubleClicked(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
last = e.getLocation();
}
public void mouseDragged(MouseEvent e)
{
Point p = e.getLocation();
Dimension delta = p.getDifference(last);
{
last = p;
Figure f = ((Figure) e.getSource());
f.setBounds(f.getBounds().getTranslated(delta.width, delta.height));
}
}
}
}
Пожалуйста, посмотрите, как я использовал Layout
s. Это гораздо надежнее и будет работать лучше при разных размерах окон и разрешениях экрана.
Пожалуйста, прочитайте это: Понимание макетов в SWT