/**************************************************************************
* Copyright (c) 2001 by Acunia N.V. All rights reserved. *
* *
* This software is copyrighted by and is the sole property of Acunia N.V. *
* and its licensors, if any. All rights, title, ownership, or other *
* interests in the software remain the property of Acunia N.V. and its *
* licensors, if any. *
* *
* This software may only be used in accordance with the corresponding *
* license agreement. Any unauthorized use, duplication, transmission, *
* distribution or disclosure of this software is expressly forbidden. *
* *
* This Copyright notice may not be removed or modified without prior *
* written consent of Acunia N.V. *
* *
* Acunia N.V. reserves the right to modify this software without notice. *
* *
* Acunia N.V. *
* Vanden Tymplestraat 35 info@acunia.com *
* 3000 Leuven http://www.acunia.com *
* Belgium - EUROPE *
**************************************************************************/
// Author: D. Buytaert
// Created: 2001/05/03
package com.acunia.wonka.test.awt.Component;
import com.acunia.wonka.test.awt.*;
import java.awt.*;
import java.awt.event.*;
public class ComponentUpdateBounds extends VisualTestImpl implements ActionListener {
/** variables */
private InnerComponent innerComponent;
private InnerPaintComponent paintComponent;
private InnerBoundsComponent boundsComponent;
private Button repaintAll;
private Button repaintBounds;
List display;
/** constructor */
public ComponentUpdateBounds() {
setLayout(new BorderLayout());
setBackground(new Color(64,64,96));
setForeground(Color.white);
Panel top = new Panel(new FlowLayout() );
repaintAll = new Button("repaint() all");
repaintAll.addActionListener(this);
top.add(repaintAll);
top.add(new Label(" ")); //placeholder
repaintBounds = new Button("repaint(x,y,w,h) selection");
repaintBounds.addActionListener(this);
top.add(repaintBounds);
add(top,BorderLayout.NORTH);
display = new List(5,false);
display.add("Use your mouse to select an update area in the center panel");
display.add("Press <repaint all> to repaint the left and right screen completely");
display.add("Press <repaint selection> to repaint the selected area");
display.add(" on the left and right screen");
add(display,BorderLayout.SOUTH);
Panel components = new Panel(new GridLayout(1,3));
innerComponent = new InnerComponent();
components.add(innerComponent);
boundsComponent = new InnerBoundsComponent(new Color(96,96,144));
components.add(boundsComponent);
paintComponent = new InnerPaintComponent();
components.add(paintComponent);
add(components, BorderLayout.CENTER);
}
/****************************************************************/
/**
* on click repaint
*/
public void actionPerformed(ActionEvent evt) {
display.removeAll();
if(evt.getSource() == repaintAll){
display.add("Sending repaint()-command without bounds for whole screen");
innerComponent.repaint();
paintComponent.repaint();
}
else {
Rectangle selection = boundsComponent.getSelection();
display.add("Sending repaint(bounds) for bounds("+selection.x+", "+selection.y+", "+selection.width+", "+selection.height+")");
innerComponent.repaint(selection.x, selection.y, selection.width, selection.height);
paintComponent.repaint(selection.x, selection.y, selection.width, selection.height);
}
}
/****************************************************************/
/** inner class with painting and mouse movements , based on panel*/
class InnerPaintComponent extends PaintComponent {
private Rectangle bounds;
/** constructor */
public InnerPaintComponent() {
super("extern PaintComponent",display);
}
/** common command for Paint() and update() */
protected boolean paintArea(Color background, Color foreground, Graphics g){
bounds = g.getClipBounds();
boolean calculated = false;
if(frameRect.width<=0){
frameRect.setBounds(0,0,this.getSize().width, this.getSize().height);
calculated=true;
}
if(bounds==null){
bounds = frameRect;
display.add("NULL bounds: Reverting to full screen (0, 0, "+bounds.width+", "+bounds.height+")");
}
else {
display.add("bounds ("+bounds.x+", "+bounds.y+", "+bounds.width+", "+bounds.height+")");
}
g.setColor(background);
g.fillRect(5,5, frameRect.width-10, frameRect.height-10);
g.setColor(foreground);
g.drawString("extern PaintComponent:", 10,20);
g.drawString("updates "+updateCount, 10,35);
g.drawString("paints = "+paintCount, 10,50);
return calculated;
}
//(end inner class)
}
/****************************************************************/
/** inner class with painting and mouse movements , based on panel*/
class InnerComponent extends Panel {
protected Rectangle bounds;
protected int updateCount;
protected int paintCount;
protected Rectangle frameRect;
public InnerComponent() {
super();
updateCount=0;
paintCount=0;
frameRect = new Rectangle();
}
/** paint */
public void paint(Graphics g) {
display.add("Inner class: Received call to paint()");
paintCount++;
if(paintArea(PaintComponent.DARKCOLORS[(paintCount-1)%PaintComponent.COLORCOUNT], Color.white, g) ) {
display.add("Inner class: on paint() calculated sizes");
}
display.add("Inner class: paint() executed, total paints = "+paintCount);
}
/** update */
public void update(Graphics g) {
display.add("Inner class: Received call to update()");
updateCount++;
if(paintArea(PaintComponent.LIGHTCOLORS[(updateCount-1)%PaintComponent.COLORCOUNT], Color.black, g) ) {
display.add("Inner class: on update() calculated sizes");
}
display.add("Inner class: update() executed, total updates = "+updateCount);
}
private boolean paintArea(Color background, Color foreground, Graphics g){
bounds = g.getClipBounds();
boolean calculated = false;
if(frameRect.width<=0){
frameRect.setBounds(0,0,this.getSize().width, this.getSize().height);
calculated=true;
}
if(bounds==null){
bounds = frameRect;
display.add("NULL bounds: Reverting to full screen (0, 0, "+bounds.width+", "+bounds.height+")");
}
else {
display.add("bounds ("+bounds.x+", "+bounds.y+", "+bounds.width+", "+bounds.height+")");
}
g.setColor(background);
g.fillRect(5,5, frameRect.width-10, frameRect.height-10);
g.setColor(foreground);
g.drawString("inner Component:", 10,20);
g.drawString("updates "+updateCount, 10,35);
g.drawString("paints = "+paintCount, 10,50);
return calculated;
}
//(end inner class)
}
/****************************************************************/
/** inner class to get a series of bounds*/
class InnerBoundsComponent extends Component implements MouseListener, MouseMotionListener {
Rectangle frame;
Rectangle bounds;
Color background;
int startX;
int startY;
int mouseX;
int mouseY;
/** constructor: */
public InnerBoundsComponent(Color background){
this.background = background;
this.frame = new Rectangle();
this.bounds = new Rectangle();
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
/** Mouse events :
* => on mouse pressed: new boundaries starting point
* => on mouse dragged: new boundaries ending point
*/
public void mouseEntered(MouseEvent evt) { }
public void mouseExited(MouseEvent evt) { }
public void mousePressed(MouseEvent evt) {
startX = evt.getX();
startY = evt.getY();
mouseX = startX;
mouseY = startY;
bounds.setBounds(mouseX, mouseY, 0, 0);
this.repaint();
}
public void mouseReleased(MouseEvent evt) { }
public void mouseClicked(MouseEvent evt) { }
public void mouseMoved(MouseEvent evt) { }
public void mouseDragged(MouseEvent evt) {
mouseX = evt.getX();
mouseY = evt.getY();
if(mouseX>startX) {
bounds.x = startX;
bounds.width = mouseX-startX;
}
else {
bounds.x = mouseX;
bounds.width = startX - mouseX;
}
if(mouseY>startY) {
bounds.y = startY;
bounds.height = mouseY-startY;
}
else {
bounds.y = mouseY;
bounds.height = startY - mouseY;
}
this.repaint();
}
/** return selection bounds: */
public Rectangle getSelection() {
return bounds;
}
/** screen paint: */
public void paint(Graphics g) {
this.update(g);
}
public void update(Graphics g) {
// on first time paint calculate sizes
if(frame.width <=0) {
frame.setBounds(1, 1, this.getSize().width-2, this.getSize().height-2);
bounds.setBounds(frame.width/3, frame.height/3, frame.width/3, frame.height/3);
}
// clear screen
g.setColor(background);
g.fillRect(1,1, frame.width, frame.height);
g.setColor(Color.white);
g.drawRect(1,1, frame.width, frame.height);
// paint bounds
g.setColor(Color.red);
g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
}
/****************************************************************************************************************************************/
public String getHelpText() {
return "A test on passing the boundaries in a Component.repaint(x,y,w,h) command\n"+
" The main part of this test are the two central Components. To refresh the content of the components, a paint() and an update()"+
" function are implemented, both painting the current clipping bound in a background color and also displaying the number"+
" of paints and updates made:\n"+
"With each paint() or update() the background color changes along the colors of the rainbow (red, orange, yellow....)"+
" Paint commands display white text on dark colors, update-commands black text on light colors. Like this it is possible to see"+
" wether the clipping area is being paint()-ed or update()-ed \n"+
"(If the clipping bound is <NULL>, it is being replaced by the complete screen)\n\n"+
"The <repaint()> button sends an empty repaint() command to both components. the <repaint(x,y,w,h)> sends the special form to"+
" repaint only a selected area. You can specify the area that has to be overpainted in the center panel using your mouse.\n"+
"There are two display component. One derived from Component, the other from an extern class PaintComponent. For some reason the Sun"+
"sdk always sends a call tp paint() to the external PaintComponent, even on a call to repaint() when the inner component receives"+
" a call to update()";
}
public void main(String[] args) {
Frame main=new Frame("Component paint test");
main.setSize(400,234);
main.add(new ComponentUpdate());
main.show();
}
}