Библиотека сайта rus-linux.net
Фреймворк Violet
Глава 22 из книги "Архитектура приложений с открытым исходным кодом", том 1.
Оригинал: "Violet", глава из книги "The Architecture of Open Source Applications"
Автор: Cay Horstmann
Перевод: Н.Ромоданов
22.6. Java 2D
В Violet интенсивно используется библиотека Java2D, один из менее известных драгоценных камней в Java API. Каждый узел и ребро имеет метод getShape
, который выдает java.awt.Shape
- общий интерфейс всех форм Java2D. В этом интерфейсе реализованы прямоугольники, круги, пути и их объединения, пересечения и разности. Класс GeneralPath
используется для создания фигур, которые состоят из сегментов произвольных линий и квадратичных/кубических кривых, например, прямых и закругленных стрелок.
Чтобы оценить гибкость Java2D API, рассмотрим следующий код, рисующий тени в методе AbstractNode.draw
:
Shape shape = getShape(); if (shape == null) return; g2.translate(SHADOW_GAP, SHADOW_GAP); g2.setColor(SHADOW_COLOR); g2.fill(shape); g2.translate(-SHADOW_GAP, -SHADOW_GAP); g2.setColor(BACKGROUND_COLOR); g2.fill(shape);
Несколько строк кода создают тени для любых форм, даже для тех, которые разработчик может добавить на более позднем этапе.
Конечно, в Violet сохраняются растровые изображения в любом формате, который поддерживается пакетом javax.imageio
; то есть, GIF, PNG, JPEG, и так далее. Когда мой издатель спросил меня о векторных изображениях, я обнаружил еще одно преимущество библиотеки Java 2D. При печати на PostScript-принтере, Java2D операции преобразуются в операции векторной графики на языке PostScript. Если печатать в файл, результат можно использовать с такими программами, как ps2eps
, а затем его можно импортировать в Adobe Illustrator или Inkscape. В следующем коде компонент comp из Swing, метод которого paintComponent
используется для рисования графа:
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE; String mimeType = "application/postscript"; StreamPrintServiceFactory[] factories; StreamPrintServiceFactory.lookupStreamPrintServiceFactories(flavor, mimeType); FileOutputStream out = new FileOutputStream(fileName); PrintService service = factories[0].getPrintService(out); SimpleDoc doc = new SimpleDoc(new Printable() { public int print(Graphics g, PageFormat pf, int page) { if (page >= 1) return Printable.NO_SUCH_PAGE; else { double sf1 = pf.getImageableWidth() / (comp.getWidth() + 1); double sf2 = pf.getImageableHeight() / (comp.getHeight() + 1); double s = Math.min(sf1, sf2); Graphics2D g2 = (Graphics2D) g; g2.translate((pf.getWidth() - pf.getImageableWidth()) / 2, (pf.getHeight() - pf.getImageableHeight()) / 2); g2.scale(s, s); comp.paint(g); return Printable.PAGE_EXISTS; } } }, flavor, null); DocPrintJob job = service.createPrintJob(); PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); job.print(doc, attributes);
В начале, я был обеспокоен тем, что использование общих форм может привести к снижению производительности, но, как оказалось, это не так. Операция вырезания фрагментов работает достаточно хорошо, поскольку в действительности выполняются только те операции, которые необходимы для обновления текущей видимой области.
Продолжение статьи: 22.7. Это не фреймворк приложений Swing.