Custom Painting
Gestione
della
Grafica customizzata
Vedi anche:
http://java.sun.com/docs/books/tutorial/uiswing/14painting/index.html
Metodi grafici di Graphics
drawLine()
Draws a line
drawRect()
Draws a rectangle
fillRect()
Draws a filled rectangle
drawRoundRect()Draws a rounded-corner rectangle
fillRoundRect()
Draws a filled, rounded-corner rectangle
draw3DRect()
Draws a highlighted, 3D rectangle
fill3DRect()
Draws a filled, highlighted, 3D rectangle
drawArc()
Draws an arc
fillArc()
Draws a filled arc
drawOval()
Draws an oval
fillOval()
Draws a filled oval
drawPolygon()
Draws a polygon, connecting endpoints
fillPolygon()
Draws a filled polygon
drawPolyline()
Draws a line connecting a polygon's points
Il sistema di coordinate
import
import
import
public
java.awt.*;
javax.swing.*;
java.awt.event.*;
class TestPattern
{
public static void main(String[] args) {
new TestPattern();
}
public TestPattern() {
startGraphics();
}
public void startGraphics();{
JFrame f = new JFrame("TestPattern");
f.setSize(300,300);
f.setContentPane(new MyPanel());
f.setVisible(true);
}
}
Disegno Grafico
class MyPanel extends JPanel {
int theta = 45; int delta = 90;
public void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getSize().width;
int height = getSize().height;
int hWidth = width / 2;
int hHeight = height / 2;
int x = (width - hWidth)/2;
int y = (height - hHeight)/2;
g.setColor(Color.black);
g.fillRect(0, 0, size().width, size().height);
int[] polyx = {0, width / 2, width, width / 2};
int[] polyy = {height / 2, 0, height / 2, height};
Polygon poly = new Polygon(polyx, polyy, 4);
g.setColor(Color.yellow)
g.fillPolygon(poly);
g.setColor(Color.red);
g.fillRect(x, y, hWidth, hHeight);
g.setColor(Color.green);
g.fillOval(x, y, hWidth, hHeight);
g.setColor(Color.blue);
g.fillArc(x, y, hWidth, hHeight, theta, delta);
g.setColor(Color.white);
g.drawLine(x, y, x + hWidth, x + hHeight);
}
}
Disegno Grafico
Animazione
Click!
Click!
Click!
class MyPanel extends JPanel implements MouseListener{
int theta = 45; int delta = 90;
public void paintComponent(Graphics g) {
...
Animazione
}
public void mouseClicked(MouseEvent e) {
theta=theta-90;
this.repaint();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
MyPanel() {this.addMouseListener(this);}
}
Double buffering dietro le quinte!
Repainting
NON SI CHIAMA MAI ESPLICITAMENTE LA
paintComponent(Graphics g)!
[ nè la paint(Graphics g) ]
Si chiama sempre, solo la repaint()
NON SI IMPLEMENTA MAI LA REPAINT!
La repaint viene chiamata anche dal sistema
quando lo ritiene opportuno (resize, unhide...)
class MyPanel extends JPanel implements MouseListener{
public void paintComponent(Graphics g) {
super.paintComponent(g);
int rval, gval, bval;
Colore
for (int j
for (int
rval =
gval =
bval =
= 30; j < (this.size().height
i = 5; i < (this.size().width
(int)Math.floor(Math.random()
(int)Math.floor(Math.random()
(int)Math.floor(Math.random()
-25); j += 30)
-25); i+= 30) {
* 256);
* 256);
* 256);
g.setColor(new Color(rval,gval,bval));
g.fillRect(i,j,25,25);
g.setColor(Color.black);
g.drawRect(i-1,j-1,25,25);
}
}
...
}
Double buffering dietro le quinte!
Animazione
Click!
Resize!
Insets
protected void paintComponent(Graphics g) {
... Insets insets = getInsets();
int currentWidth = getWidth() - insets.left - insets.right;
int currentHeight = getHeight() - insets.top - insets.bottom;
...
/* First painting occurs at (x,y), where x is at least insets.left,
and y is at least insets.top. */... }
Come avviene il “painting”
1.
background
(if opaque)
2. custom
painting
(if any)
3. border
(if any)
4. children
(if any)
paintComponent — The main method for painting.
By default, it first paints the background if
the component is opaque.
Then it performs any custom painting.
paintBorder — Tells the component's border (if any) to paint.
Do not invoke or override this method.
paintChildren — Tells any components contained by this
component to paint themselves.
Do not invoke or override this method.
Regole
When implementing custom painting code for a component,
keep these rules in mind:
•Your custom painting code should be in a method with the
signature protected void paintComponent(Graphics).
To gain access to the power of the 2D graphics API , you can
cast the Graphics parameter into a Graphics2D object.
•You can use a border to paint the outside edges of your
component.
•Except when painting the background of the component, you
should avoid painting over the border area of the component.
You can determine this area using the getInsets method.
•Your component must honor the opaque property. If your
component is opaque, it must paint its complete area using an
opaque color or colors. If its opaque property is false, then you
have the option of not painting over the entire component.
class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Font f = new Font("TimesRoman",
Fonts
Font.PLAIN, 18);
FontMetrics fm = getFontMetrics(f);
g.setFont(f);
String s = "This is a plain font";
int xstart = (getSize().width –
fm.stringWidth(s))/2;
g.drawString(s, xstart, 25);
Font fb = new Font("TimesRoman", Font.BOLD, 18);
Font fi = new Font("TimesRoman", Font.ITALIC, 18);
Font fbi=new Font("TimesRoman",Font.BOLD +Font.ITALIC, 18);
g.setFont(fb);
g.drawString("This is a bold font", 10, 50);
g.setFont(fi);
g.drawString("This is an italic font", 10, 75);
g.setFont(fbi);
g.drawString("This is a bold italic font", 10, 100);
}
...
}
Ancora su repaint…
Quando si modifica la composizione di un
container, per mostrare le variazioni NON
BASTA chiamare la repaint(), prima occorre
chiamare la validate().
Ancora su repaint…
p.addButton();
p.validate();
p.repaint();
Animazione in Java
Problemi che possono nascere,
e loro soluzione
Animazione in Java
Application
MyFrame
(JFrame)
ClockPanel
(JPanel)
public class ClockPanel extends JPanel { …
public void paintComponent(Graphics g) {
Date d=new Date();
int sec=d.getSeconds(); OBSOLETO, ma funziona
double angle=sec*Math.PI/30;
int w=this.getWidth();
int h=this.getHeight();
g.setColor(Color.YELLOW);
g.fillRect(0,0,w,h);
g.setColor(Color.GREEN);
g.fillOval(0,0,w,h);
g.setColor(Color.BLACK);
g.drawLine(w/2,h/2,
(int)(w/2*(1+Math.cos(angle)))
,(int)(h/2*(1+Math.sin(angle))));
} …
ClockPanel - paintComponent
public class MyFrame extends JFrame {
//Component initialization
private void jbInit() throws Exception {
contentPane=new ClockPanel();
this.setContentPane(contentPane);
contentPane.setLayout(borderLayout1);
this.setSize(new Dimension(400, 300));
this.setTitle("Frame Title");
while (true) {
try {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
}
contentPane.repaint();
}
}
...
MyFrame – version 1
Animazione e Threads in Java
Application
Runner
(Runnable)
MyFrame
(JFrame)
ClockPanel
(JPanel)
public class Runner implements Runnable {
ClockPanel cp;
public Runner(ClockPanel cp) {
this.cp=cp;
}
public void run() {
while (true) {
try {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
}
cp.repaint();
}
}
Runner
}
MyFrame – version 2
public class MyFrame extends JFrame {
//Component initialization
private void jbInit() throws Exception {
contentPane=new ClockPanel();
this.setContentPane(contentPane);
contentPane.setLayout(borderLayout1);
this.setSize(new Dimension(400, 300));
this.setTitle("Frame Title");
Runner r=new Runner(contentPane);
new Thread(r).start();
}
...
Sezione: Modificatori
Abstract e Controllo di accesso
Modificatori: abstract
Classi dichiarate abstract non possono
essere istanziate, e devono essere
subclassate.
Metodi dichiarati abstract devono essere
sovrascritti
Una class non abstract non può contenere
abstract metods
Modificatori: visibilità
public
(non def.)
protected
private
visibile da tutti
visibile da tutti nello stesso package
visibile dalle sottoclassi
Uso di metodi “di accesso”:
nascosta da tutti
public class ACorrectClass {
private String aUsefulString;
public String getAUsefulString() {
return aUsefulString; // "get" the
value
}
private void setAUsefulString(String s) {
//protected void setAUsefulString(String
s) {
aUsefulString = s; // "set" the value
}
Matrice degli accessi
Access Levels
Specifier
protected
Class
Y
Y
Y
Package
N
Y
Y
Subclass
N
N
Y
World
N
N
N
public
Y
Y
Y
Y
private
no specifier
Vedi anche
http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html