#java #drawing #swt #eclipse-gef #zest
#java #рисование #swt #eclipse-gef #zest
Вопрос:
Я разрабатываю новый подключаемый модуль Eclipse, используя GEF (Draw2d 3.9, Zest 1.5.0) с пользовательскими рисунками для представления некоторых данных. Сейчас я пытаюсь разработать настраиваемый вид объектива. Желаемая функциональность заключается в том, что мышь будет перетаскиваться в главное окно, а «окно просмотра объектива» будет представлять выбранную область.
Для этого я использую окно с SWT canvas для просмотра в объективе. Содержимое главного окна (графика) отображается на холсте lens. Затем я копирую другую область (может находиться за пределами видимой области) холста объектива в точку 0,0 (холста объектива). Проблема в том, что lens canvas игнорирует все, что нарисовано за пределами его видимой области, и когда я копирую вышеупомянутую область, я получаю черный цвет вместо содержимого.
Копирование содержимого графика в изображение и после этого рисование части изображения не является решением, потому что мой график может быть гигантским (> 200000 x 200000).
Ниже вы можете найти часть моего кода:
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.zest.core.widgets.Graph;
public class LensView {
private final Shell shell;
private final Canvas canvas;
private final Point focalPoint;
private float lensScaleFactor;
private float mainScaleFactor;
public LensView(final Graph graph, Display d) {
this.visualizer = visualizer;
focalPoint = new Point(0, 0);
lensScaleFactor = 1.0f;
mainScaleFactor = 1.0f;
shell = new Shell(d, SWT.SHELL_TRIM);
shell.setSize(640, 480);
shell.setLayout(new FillLayout());
canvas = new Canvas(shell, SWT.NO_REDRAW_RESIZE);
canvas.setLayout(new FillLayout());
canvas.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
Rectangle area = canvas.getClientArea();
//Scale the origin to 1.0 and apply our scale factor
float scale = lensScaleFactor/mainScaleFactor;
Point viewLocation = graph.getViewport().getViewLocation();
int tmpx = normaliseDec(Math.round((focalPoint.x viewLocation.x) * scale) - Math.round(area.width/2.0f));
int tmpy = normaliseDec(Math.round((focalPoint.y viewLocation.y) * scale) - Math.round(area.height/2.0f));
GC gc = new GC(canvas);
SWTGraphics graphics = new SWTGraphics(gc);
graphics.scale(scale);
graph.getContents().paint(graphics);
e.gc.copyArea(tmpx, tmpy, area.width, area.height, 0, 0);
graphics.dispose();
gc.dispose();
}
});
}
public void redraw (int x, int y) {
focalPoint.x = normaliseDec(x);
focalPoint.y = normaliseDec(y);
canvas.redraw();
canvas.update();
}
private int normaliseDec (int i) {
return i < 0 ? 0 : i;
}
}
Ответ №1:
Думаю, все, что вам нужно сделать, это создать объект ScaledGraphics из GC, который поставляется с paintEvent, установить коэффициент масштабирования для графики, установить прямоугольник обрезки, а затем нарисовать свой график. Что-то вроде этого (не тестировал, примерно что-то вроде этого):
ScaledGraphics graphics = new ScaledGraphics(e.gc);
graphics.scale(scale);
graphics.setClip(new Rectangle(focalPoint, getClientArea().getSize()));
graph.getContents().paint(graphics);
graphics.dispose();
Несколько моментов:
— ScaledGraphics должна выполнить масштабирование обтравочного прямоугольника за вас
— Следует рисовать на элементах управления GC, а не создавать новый
Комментарии:
1. Здравствуйте, спасибо за помощь, но, к сожалению, это не сработало. Метод setClip обрезает одну определенную область, но не переносит ее на 0, 0 холста объектива 🙁 .
2. Да, действительно, вам нужно было бы выполнить перевод, прежде чем начинать рисовать. Вызовите graphics.translate(-myX, -myY)
3. Я хотел бы поблагодарить вас за вашу ценную помощь. Метод graphics.translate был решением моей проблемы ;).