/************************************************************************** * 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.Window; import com.acunia.wonka.test.awt.*; import java.awt.*; import java.awt.event.*; public class WindowUpdate extends VisualTestImpl implements ActionListener { /** definitions */ final static Color[] COLORS = {new Color(128,0,128), new Color(0,0,128), new Color(96,96,255), Color.green, Color.yellow, Color.orange,Color.red}; private final static Color DARKRED = new Color(96,48,48); private final static Color LIGHTRED = new Color(192,96,96); private final static Color DARKGREEN = new Color(48,96,48); private final static Color LIGHTGREEN = new Color(96,192,96); private final static Color DARKBLUE = new Color(48,48,96); private final static Color LIGHTBLUE = new Color(96,96,192); // window size private final static int WINWIDTH=70; private final static int WINHEIGHT=50; private final static int WINSTEP=15; /** variables */ // buttons: private Button leftOne; private Button rightOne; private Button upOne; private Button downOne; private Button frontOne; private Button repaintOne; private Button leftTwo; private Button rightTwo; private Button upTwo; private Button downTwo; private Button frontTwo; private Button repaintTwo; private Button repaintMain; private Button repaintBottom; //windows private Window one; private InnerPaintComponent onePanel; private int framexOne; private int frameyOne; private Window two; private InnerPaintComponent twoPanel; private int framexTwo; private int frameyTwo; //main panel private InnerPaintComponent mainPanel; private int mainWidth; private int mainHeight; private int mainLeft; private int mainRight; private int mainTop; private int mainBottom; // display list private List display; /****************/ /** constructor */ public WindowUpdate() { // build windows one = null; onePanel = new InnerPaintComponent("Red window", LIGHTRED, DARKRED); two = null; twoPanel = new InnerPaintComponent("Blue window", LIGHTBLUE, DARKBLUE); setBackground(new Color(192,192,96)); setLayout(new BorderLayout()); // repaint central on top Panel top = new Panel(new FlowLayout()); top.add(new Label("Main component")); repaintMain = new Button("repaint() main"); repaintMain.setBackground(LIGHTGREEN); repaintMain.addActionListener(this); top.add(repaintMain); repaintBottom = new Button("repaint() bottom half"); repaintBottom.setForeground(Color.white); repaintBottom.setBackground(DARKGREEN); repaintBottom.addActionListener(this); top.add(repaintBottom); add(top, BorderLayout.NORTH); // red window one on the left side Panel onebuttons = new Panel(new GridLayout(8,1) ); onebuttons.setBackground(LIGHTRED); onebuttons.add(new Label("RED WINDOW")); frontOne = new Button("to front"); frontOne.addActionListener(this); onebuttons.add(frontOne); repaintOne = new Button("repaint()"); repaintOne.setForeground(Color.white); repaintOne.setBackground(DARKRED); repaintOne.addActionListener(this); onebuttons.add(repaintOne); onebuttons.add(new Label()); leftOne = new Button("left =>"); leftOne.addActionListener(this); onebuttons.add(leftOne); rightOne = new Button("<= right"); rightOne.addActionListener(this); onebuttons.add(rightOne); upOne = new Button("up =^"); upOne.addActionListener(this); onebuttons.add(upOne); downOne = new Button("down =v"); downOne.addActionListener(this); onebuttons.add(downOne); add(onebuttons, BorderLayout.WEST); // Blue window two on the right side Panel twobuttons = new Panel(new GridLayout(8,1) ); twobuttons.setBackground(LIGHTBLUE); twobuttons.add(new Label("BLUE WINDOW")); frontTwo = new Button("to front"); frontTwo.addActionListener(this); twobuttons.add(frontTwo); repaintTwo = new Button("repaint()"); repaintTwo.setForeground(Color.white); repaintTwo.setBackground(DARKBLUE); repaintTwo.addActionListener(this); twobuttons.add(repaintTwo); twobuttons.add(new Label()); leftTwo = new Button("left =>"); leftTwo.addActionListener(this); twobuttons.add(leftTwo); rightTwo = new Button("<= right"); rightTwo.addActionListener(this); twobuttons.add(rightTwo); upTwo = new Button("up =^"); upTwo.addActionListener(this); twobuttons.add(upTwo); downTwo = new Button("down =v"); downTwo.addActionListener(this); twobuttons.add(downTwo); add(twobuttons, BorderLayout.EAST); // central main display mainPanel = new InnerPaintComponent("Main panel",LIGHTGREEN,DARKGREEN); add(mainPanel, BorderLayout.CENTER); // message display list display = new List(3,false); add(display,BorderLayout.SOUTH); } /****************************************************************************************************************************************/ /** * As vt is only available after building the screen, we have to use this auxilliary function * to build the first window when pressing one of the left-side keys */ public void checkWindowOne() { if(one==null) { if(vt==null){ displayMessage("Skipped windows for lack of VT instance"); } else{ Frame vtframe = vt.getFrame(); if(vtframe==null){ // unable to access the main wonka frame yet displayMessage("Skipped Windows for lack of vt.getFrame()"); } else{ getMainBounds(); framexOne = mainLeft + mainWidth/2 - WINWIDTH/2 - 20; frameyOne = mainTop + mainHeight/2 - WINHEIGHT/2 - 20; one = new Window(vtframe); one.add(onePanel); one.pack(); one.setLocation(framexOne, frameyOne); one.setVisible(true); displayMessage("Built window one"); } } } } /****************************************************************************************************************************************/ /** * As vt is only available after building the screen, we have to use this auxilliary function * to build the second window when pressing one of the right-side keys */ public void checkWindowTwo() { if(two == null) { if(vt==null){ displayMessage("Skipped windows for lack of VT instance"); } else{ Frame vtframe = vt.getFrame(); if(vtframe==null){ // unable to access the main wonka frame yet displayMessage("Skipped Windows for lack of vt.getFrame()"); } else{ getMainBounds(); framexTwo = mainLeft + mainWidth/2 - WINWIDTH/2 + 20; frameyTwo = mainTop + mainHeight/2 - WINHEIGHT/2 + 20; two = new Window(vtframe); two.add(twoPanel); two.pack(); two.setLocation(framexTwo, frameyTwo); two.setVisible(true); displayMessage("Built window two"); } } } } public void getMainBounds() { Rectangle bounds = mainPanel.getBounds(); Point offset = mainPanel.getLocationOnScreen(); mainWidth= bounds.width; mainHeight = bounds.height; mainLeft = offset.x; mainRight = offset.x+ mainWidth-WINWIDTH; mainTop = offset.y; mainBottom = offset.y+ mainHeight-WINHEIGHT; } /****************************************************************************************************************************************/ /** * On button commands: move frames, repaint frames */ public void actionPerformed(ActionEvent evt) { Component source = (Component)evt.getSource(); if(source == repaintMain) { mainPanel.repaint(); } else if(source == repaintBottom) { mainPanel.repaint(0, mainHeight/2, mainWidth, mainHeight/2); } else if(source == rightOne) { checkWindowOne(); framexOne=(framexOne>(mainLeft+WINSTEP))? framexOne-WINSTEP:mainLeft; one.setLocation(framexOne, frameyOne); } else if (source == leftOne) { checkWindowOne(); framexOne=(framexOne<(mainRight-WINSTEP))? framexOne+WINSTEP:mainRight; one.setLocation(framexOne, frameyOne); } else if (source == upOne) { checkWindowOne(); frameyOne = (frameyOne>(mainTop+WINSTEP))? frameyOne-WINSTEP: mainTop; one.setLocation(framexOne, frameyOne); } else if (source == downOne) { checkWindowOne(); frameyOne=(frameyOne<(mainBottom-WINSTEP))? frameyOne+WINSTEP: mainBottom; one.setLocation(framexOne, frameyOne); } else if (source == frontOne) { checkWindowOne(); one.toFront(); } else if (source == repaintOne) { checkWindowOne(); onePanel.repaint(); } else if (source == rightTwo) { checkWindowTwo(); framexTwo = (framexTwo>(mainLeft+WINSTEP))? framexTwo-WINSTEP: mainLeft; two.setLocation(framexTwo, frameyTwo); } else if (source == leftTwo) { checkWindowTwo(); framexTwo=(framexTwo<(mainRight-WINSTEP))? framexTwo+WINSTEP: mainRight; two.setLocation(framexTwo, frameyTwo); } else if (source == upTwo) { checkWindowTwo(); frameyTwo = (frameyTwo>(mainTop+WINSTEP))? frameyTwo-WINSTEP: mainTop; two.setLocation(framexTwo, frameyTwo); } else if (source == downTwo) { checkWindowTwo(); frameyTwo=(frameyTwo<(mainBottom-WINSTEP))? frameyTwo+WINSTEP: mainBottom; two.setLocation(framexTwo, frameyTwo); } else if (source == frontTwo) { checkWindowTwo(); two.toFront(); } else if (source == repaintTwo) { checkWindowTwo(); twoPanel.repaint(); } } /*********************************************************************************/ /** inner class with painting and mouse movements , based on panel*/ class InnerPaintComponent extends Panel { private int updateCount; private int paintCount; private String name; private Color paintColor; private Color updateColor; /** constructor */ public InnerPaintComponent(String componentname, Color paint, Color update) { super(); name = componentname; paintCount=0; updateCount=0; paintColor=paint; updateColor=update; } /*set preferred size to 50 pixels high & wide*/ public Dimension getPreferredSize() { return new Dimension(WINWIDTH, WINHEIGHT); } /** paint */ public void paint(Graphics g) { paintCount++; displayMessage(name+ ": Received call to paint(), total paints = "+paintCount); Rectangle bounds = paintArea(g.getClipBounds(), paintColor, g); displayMessage(name+ ": Executed paint() for bounds ("+bounds.x+", "+bounds.y+", "+bounds.width+", "+bounds.height+")"); } public void update(Graphics g) { updateCount++; displayMessage(name+ ": Received call to update(), total updates = "+updateCount); Rectangle bounds = paintArea(g.getClipBounds(), updateColor, g); displayMessage(name+ ": Executed update() for bounds ("+bounds.x+", "+bounds.y+", "+bounds.width+", "+bounds.height+")"); } private Rectangle paintArea(Rectangle bounds, Color background, Graphics g){ if(bounds==null){ bounds = new Rectangle(0,0,this.getSize().width,this.getSize().height); displayMessage("NULL bounds: Reverting to full screen (0, 0, "+bounds.width+", "+bounds.height+")"); } g.setColor(background); g.fillRect(bounds.x, bounds.y, bounds.width-1, bounds.height-1); g.setColor(Color.white); g.drawRect(bounds.x+1, bounds.y+1, bounds.width-2, bounds.height-2); g.drawString(name, 3, 14); g.setColor(COLORS[updateCount%(COLORS.length)]); g.drawString("Updates "+updateCount, 3, 28); g.setColor(COLORS[paintCount%(COLORS.length)]); g.drawString("Paints = "+paintCount, 3, 42); return bounds; } //(end inner class) } /****************************************************************************************************************************************/ void displayMessage(String message) { if(display.getItemCount()>40) { display.removeAll(); } display.add(message,0); System.out.println(message); } public String getHelpText() { return "A test on the interaction between the update() and paint() commands for systems with overlaying windows in different virtual engines\n"+ " Two windows will be shown on a central panel. Both windows and panel only consists out of one basic paint component."+ " To refresh the content of the component, a paint() and an update() function are implemented, both behaving slightly different:\n"+ "=> the paint() function gets the graphics clipping bounds (Graphics.getClipBounds()) and repaints the area inside this clipping bounds in a light color"+ " (it also draws a white line around the clipping rectangle). Then it displays a message <Executed paint()> in the display list below\n"+ "=> the update() function also gets the graphics clipping bounds but repaints the area inside this clipping bounds in a darker color"+ " and displays an <Executed update()> message. (it also draws a white line around the clipping rectangle) \n"+ "(If the clipping bound is <NULL>, it is being replaced by the complete screen)\n\n"+ "Move the windows over the screen, bring them to front and to back, repaint them, repaint the screen andwatch when a paint()"+ " and when an update() is called for what area. Play around with different virtual engines and note the differences"; } /** ** on stop, close all windows that aren't closed yet */ public void stop(java.awt.Panel p){ if(one != null) { one.dispose(); one = null; } if(two != null) { two.dispose(); two = null; } } }