Графические примитивы
Пример с собаками достаточно прост, но далек от реальности. Для практического применения паттернов рассмотрим обширный пример, заключающийся в создании графического редактора. При проектировании редактора возникает необходимость в применении паттернов. Будем описывать эти паттерны, и использовать их в нашем проекте. Создавать редактор будем поэтапно, наращивая функциональность и демонстрируя приемы проектирования. Все особенности графического представления в java.swing описано в. Создадим простую программу, рисующую прямоугольники на экране. Будем рисовать прямоугольники в классе MyPanel. Функция paintComponent(Graphics g) замещает одноименную функцию суперкласса и с помощью функции draw(r) рисует в Graphics2D объект r. Создаем объект r и изменяем его границы, обрабатывая события мыши mousePressed (MouseEvent arg0) и package lesson1;
import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RectangularShape; import javax.swing.JFrame; import javax.swing.JPanel;
/** * * рисуем прямоугольник. * Обработка событий мышки mousePressed и mouseDragged * функция перерисовки окна paintComponent() */ public class Lesson1 {
/** * @param args the command line arguments */ public static void main(String[] args) { MyFrame frame = new MyFrame(); } } class MyFrame extends JFrame{ MyFrame(){ MyPanel panel =new MyPanel(); add(panel); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(500, 500); setVisible(true);
} } class MyPanel extends JPanel{ MyPanel(){ r = new Rectangle2D.Double(); p = new Point2D[2]; addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent arg0){ p[0] = arg0.getPoint(); } }); addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent arg0) { p[1]=arg0.getPoint(); r.setFrameFromDiagonal(p[0],p[1]); repaint();
} }); } @Override public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D G = (Graphics2D)g; G.draw(r);
} RectangularShape r; Point2D []p; } В приведенной программе используется объектно-ориентированная модель, в которой используются классы Line2D, Rectangular2D, RoundRectangle2D, Ellipse2D, Arc2D, QuadCurve2D, CubicCurve2D, GeneralPath, реализующие интерфейс Shape. В наших примерах мы рассматриваем только классы Rectangular2D, Ellipse2D, наследующие общий класс RectangularShape, т.е. мы рассматриваем только фигуры, которые можно вписать в прямоугольник. В этом случае для установки размера фигур можно воспользоваться методом setFrameFromDiagonal. Рассмотрение фигур, которые имеют общий класс RectangularShape, позволяет не загромождать пример дополнительной иерархией классов для описания рисуемых фигур. Можно изменять рисуемый объект. Введем две кнопки, при нажатии на которые присваиваются объекту r либо прямоугольник, либо овал. Конструктор класса MyPanel приведен ниже. public MyPanel(){ p = new Point2D[2];
//buttons JButton rectangleButton = new JButton("прямоугольник"); rectangleButton.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) { r=new Rectangle2D.Double(); } }); JButton ellipseButton = new JButton("эллипс"); ellipseButton.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) { r=new Ellipse2D.Double(); } }); add(rectangleButton); add(ellipseButton); //mouse events addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent arg0){ p[0] = arg0.getPoint(); } }); addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent arg0) { p[1]=arg0.getPoint(); r.setFrameFromDiagonal(p[0],p[1]); repaint();
} }); }
Давайте введем цвет при рисовании фигур. Мы хотим рисовать не только контур фигуры, а еще и закрашенные фигуры. Трудность заключается в том, что для рисования контура используется функция draw, а рисование заполненных цветом фигур осуществляется функцией fill. Воспользуемся паттерном проектирования «стратегия». Создадим интерфейс ColorBehavoir, в котором будет один метод – draw. package strategy; import java.awt.Graphics2D; import java.awt.geom.RectangularShape; public interface ColorBehavoir { void draw(Graphics2D g2, RectangularShape shape); } Создадим два класса, наследующие этот интерфейс ColorShape и NoColorShape. В классе ColorShape заменим функцию draw, так чтобы она могла рисовать цветные фигуры, а также передадим цвет фигуры в конструкторе класса. package strategy; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.RectangularShape; public class ColorShape implements ColorBehavoir { Color color; ColorShape(Color color){ this.color = color; } public void draw(Graphics2D g2,RectangularShape shape) {
g2.setPaint(color); g2.fill(shape); } void setColor(Color color){ this.color=color; } } В классе NoColorShape заменим функцию draw, так чтобы она могла рисовать контуры фигуры. package strategy; import java.awt.Graphics2D; import java.awt.geom.RectangularShape; public class NoColorShape implements ColorBehavoir{ public void draw(Graphics2D g2, RectangularShape shape) { g2.draw(shape); } } Создадим класс MyShape, в котором будет два объекта типа ColorBehavior и RectangularShape. Метод draw этого класса будет вызывать метод draw объекта типа ColorBehavior. package strategy; import java.awt.Graphics2D; import java.awt.geom.Point2D; import java.awt.geom.RectangularShape;
public class MyShape { ColorBehavoir colorBehavior; RectangularShape shape; MyShape(){shape=null;} MyShape(RectangularShape shape,ColorBehavoir colorBehavior){ this.shape = shape; this.colorBehavior = colorBehavior; } MyShape(RectangularShape shape){ this.shape = shape; colorBehavior = new NoColorShape(); } void draw(Graphics2D g2){ if(shape!=null) colorBehavior.draw(g2,shape); } void setShape(Point2D []p){ shape.setFrameFromDiagonal(p[0],p[1]); } void setColorBehavior(ColorBehavoir b){ colorBehavior = b; } } В классе MyPanel будем создавать объект типа MyShape и по щелчку мыши создавать цветной или бесцветный объект. package strategy; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import javax.swing.JPanel;
public class MyPanel extends JPanel{ MyShape shape=null; Point2D []p; MyPanel(){ shape = new MyShape(); p = new Point2D[2];
this.addMouseListener(new MouseAdapter() {
@Override public void mousePressed(MouseEvent arg0) { p[0]=arg0.getPoint(); shape = new MyShape(new Rectangle2D.Double()); //shape = new MyShape(new Rectangle2D.Double(),new ColorShape(Color.GREEN)); }
}); addMouseMotionListener(new MouseMotionAdapter() {
@Override public void mouseDragged(MouseEvent arg0) { p[1]= arg0.getPoint(); shape.setShape(p); repaint(); }
}); } @Override public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; shape.draw(g2); }
}
|