2D Graphics and User InterfacesWhy graphics first?Everything on the screen is graphics. Everything. Without understanding how things get drawn on the screen, one can not understand how interfaces are created, and one can not create new kinds of interfaces at all.
Graphics description modelsStroke model describes images with strokes of specified color and thickness. There are also several other parameters, such as how the line segments are connected, and whether the line is drawn solid, or with dashes. In addition, strokes can be antialiased. Line from (4,5) to (9,7) in red with a thickness of 5 Circle centered at (19,8) in blue with a radius of 8 and a thickness of 3 ...
Pixel model describes images as a discrete number of pixels. Each pixel is specified by a color from one of several possible color models.
Region model describes images with filled areas such as arcs, text, splines, and other shapes - often other stroke objects. The area may be filled with a color, or a more complex fill such as a gradient or texture. Polygon filling (0, 0)-(10, 5)-(5, 10) with yellow ... Solid fill: In practice, graphics are described with a combination of stroke, region, and pixel descriptions. The drawing abstractionEvery computer graphics system (i.e., operating system) offers some notion of a canvas to draw onto. Usually, the canvases are separated into windows that are distinct from each other, which provide a relative coordinate system and isolation. This abstraction allows the same binary-level application to render onto different kinds of surfaces such as screens, off-screen buffers (i.e., clipboards), and printers, plotters, and direct neural implants... Most current systems offer a a resolution-independent (or device-independent) API. This is crucial. If all rendering was done in pixels, a 100 pixel rectangle would be about an inch big on most displays, but would be less than 1/10th of an inch big on some printers. Java offers the Graphics/Graphics2D classes that present this abstraction Graphics objectsGraphics object (device context) provides an interface between the application program and the display device. An uniform set of graphics primitives is provided for very different devices: display screen, printer, image file, ...
In Java AWT (abstract windowing toolkit) the Graphics object is an
instance of the class public void paint(Graphics g) {
g.setColor(Color.red);
g.fillRect(10, 10, 100, 200);
Graphics2D g2 = (Graphics2D)g; // g is actually an instance of a Graphics2D
g2.draw(...);
}
Graphics holds state that prescribes how future Graphics method calls will actually behave. There is a difference in Java & C# between what state Graphics holds, and what values are passed in as parameters to the render methods. Example: Java Graphics has Color state, and uses a Color for stroke and fill (of Graphics), and uses a Paint for fill (of Graphics2D) g.setColor(Color.red); g.drawLine(0, 5, 10, 15); g.drawLine(50, 50, 30, 20); C# Graphics does not have Color state, but instead requires Pen and Brush objects passed as parameters Pen redPen = new Pen(Color.Red); g.DrawLine(redPen, 0, 5, 10, 15); g.DrawLine(redPen, 50, 50, 30, 20); What are the tradeoffs between these two approaches? How to do itThe Paint Method Regardless of how a paint request is triggered, the AWT uses a "callback" mechanism for painting, and this mechanism is the same for both heavyweight and lightweight components. This means that a program should place the component's rendering code inside a particular overridden method, and the toolkit will invoke this method when it's time to paint. The method to be overridden is in java.awt.Component:public void paint(Graphics g)
When AWT invokes this method, the Graphics object parameter is pre-configured with the appropriate state for drawing on this particular component:
Coordinate systemsDevice coordinates - Coordinates of the physical device:
Window coordinates - Coordinates within an operating system window
Physical coordinates ("device-independent coords") - correspond to physical measurements
Model ("local") coordinates - correspond to the object you are defining
Drawing shapesJava Graphics has basic shape support: lines, ellipses, polygons, etc. Java Graphics2D also has generic Shape class with g2.draw() and g2.fill() methods. See java.awt.geom. Lots of Shape subclasses. Rendering - Damage/RedrawOverride the appropriate paint method of your canvas. Render when you are asked to. Request to be rendered with JComponent.repaint() Remember that these only request repaints to happen in the future, they do not happen immediately. Or, just repaint a portion of the canvas - repaint(x, y, w, h) Be careful to not to request a repaint within a paint method. Why? Double BufferingWithout care, animated displays will flicker Due to user seeing sequence of render actions - background cleared, then items drawn back to front Instead, create offscreen buffer (or "back buffer"). Render onto that, and then copy entire back buffer to screen at once. This eliminates flicker, and can be faster for some display hardware - but uses more memory. See here for examples.TextA special kind of graphics for both performance and human reasons. Fonts can be bitmaps or curves (or bitmaps generated from curves) Java g.setFont(font); g.setColor(color); g.drawString(string, x, y); How big is a point? Fonts get measured with Ascent, Descent, Height, Leading, Width, Kerning Higher quality text can be drawn with antialiasing or more recently, sub-pixel antialiasing (e.g., Microsoft Cleartype) |