Saturday, May 8, 2010

JMusic API

http://www.jfugue.org/examples.html

ne of the best ways to learn something new is to see it in action. The following samples are complete programs that show how to use JFugue. More examples are available in the JFugue Music Exchange.

List of examples below:




Example 1: Exploring the MusicString

The features of the JFugue MusicString are discussed in detail in Chapter 2 of The Complete Guide to JFugue. Chapter 2 is available for free on the Getting Started page.

Player player = new Player();
Play the notes of an octaveplayer.play("C D E F G A B");
Play notes and rests in different octaves (0-10),
with different durations (w, h, q, etc)
player.play("C3w D6h E3q F#5i Rs Ab7q Bb2i");
Play notes using different instrumentsplayer.play("I[Piano] C5q D5q I[Flute] G5q F5q");
Play notes in harmony using different voicesplayer.play("V0 A3q B3q C3q B3q V1 A2h C2h");
Play some chords, and chord inversionsplayer.play("Cmaj5q F#min2h Bbmin13^^^");
For more examples, see The Complete Guide to JFugue or the Getting Started page



Example 2: Sample Transcription of Music to JFugue

Excerpt from Inventio 13 (J. S. Bach)Player player = new Player();
player.play("E5s A5s C6s B5s E5s B5s D6s C6i E6i G#5i E6i | A5s E5s A5s C6s B5s E5s B5s D6s C6i A5i Ri");



Example 3: Using Patterns to Build a Song

Sheet music for "Frere Jacques"
// "Frere Jacques"
Pattern pattern1 = new Pattern("C5q D5q E5q C5q");

// "Dormez-vous?"
Pattern pattern2 = new Pattern("E5q F5q G5h");

// "Sonnez les matines"
Pattern pattern3 = new Pattern("G5i A5i G5i F5i E5q C5q");

// "Ding ding dong"
Pattern pattern4 = new Pattern("C5q G4q C5h");

// Put all of the patters together to form the song
Pattern song = new Pattern();
song.add(pattern1, 2); // Adds 'pattern1' to 'song' twice
song.add(pattern2, 2); // Adds 'pattern2' to 'song' twice
song.add(pattern3, 2); // Adds 'pattern3' to 'song' twice
song.add(pattern4, 2); // Adds 'pattern4' to 'song' twice

// Play the song!
Player player = new Player(); player.play(song);



Example 4: Using Patterns to Create a Round or Fugue

Building on the "Frere Jacques" example above.
Listen to the song this program generates: frerejacques.mid
Pattern doubleMeasureRest = new Pattern("Rw Rw");

// Create the first voice
Pattern round1 = new Pattern("V0");
round1.add(song);

// Create the second voice
Pattern round2 = new Pattern("V1");
round2.add(doubleMeasureRest);
round2.add(song);

// Create the third voice
Pattern round3 = new Pattern("V2");
round3.add(doubleMeasureRest, 2);
round3.add(song);

// Put the voices together
Pattern roundSong = new Pattern();
roundSong.add(round1);
roundSong.add(round2);
roundSong.add(round3);

// Play the song!
player.play(roundSong);



Example 5: Create a Rhythm

Listen to the beat this program generates: beat16.mid
The Rhythm feature is explained in detail in The Complete Guide to JFugue.
Rhythm rhythm = new Rhythm();
Bang out your drum beatrhythm.setLayer(1, "O..oO...O..oOO..");
rhythm.setLayer(2, "..*...*...*...*.");
rhythm.setLayer(3, "^^^^^^^^^^^^^^^^");
rhythm.setLayer(4, "...............!");
Associate percussion notes with your beatrhythm.addSubstitution('O', "[BASS_DRUM]i");
rhythm.addSubstitution('o', "Rs [BASS_DRUM]s");
rhythm.addSubstitution('*', "[ACOUSTIC_SNARE]i");
rhythm.addSubstitution('^', "[PEDAL_HI_HAT]s Rs");
rhythm.addSubstitution('!', "[CRASH_CYMBAL_1]s Rs");
rhythm.addSubstitution('.', "Ri");
Play the rhythm!Pattern pattern = rhythm.getPattern();
pattern.repeat(4);
Player player = new Player();
player.play(pattern);

Monday, May 3, 2010

Event Programming Fundamentals

Event Programming Fundamentals

http://csis.pace.edu/~bergin/Java/eventfundamentals.html

Let's adopt a bit of a myth when thinking about objects. Let's think of objects as if they were people. Each object (person) will have three capabilities. First a memory capability. This is represented by the instance variables of the object. Second, the ability to communicate by asking other objects (people) for services. Third, the ability to carry out some task or perform some service. This service is often the suplying of some information. Carrying out the service may require communicating with other objects to get them to provide their service and obtain the required information. Getting a request for service may also require remembering something (storing something in the object's memory).

Sometimes we want one object to perform its task as soon as something special happens in another object. This "something special" is called an event. An example of an event is the user of a computer pressing a button on the screen. Another is the typing of any key on the keyboard. Another kind of event is information arriving at a communication port on a server, indicating a communication from a client, such as when the text typed in a chat room application arrives at the server.

The object in which the event actually occurs is called the event generator. This might be a button on the screen. The event occurs when the user presses the button.

The object that will perform the task when the event occurs is called the event handler. There may actually be several event handlers for a given event. Each event handler may need to do something different when the event occurs. How do the event handlers find out that the event has occured so that they can carry out the proper task?

An object (person) that generates events can perform a "registration service" for its event handlers. An event handler can ask an event generator to simply inform it when the event occurs. This request is called a registration. The event generator remembers who all of the registered event handlers are.

In the following picture the man acts as an event handler and the woman as a generator of time events.

The woman remembers who has registered for the "time service," namely the man.

When the event occurs (and each time it occurs), the event generator sends a message to each of its event handlers saying that the event of interest occured. The event handler can then carry out the task.

In our little scenario, after a while the event (becoming 9 o'clock) occurs. Then we have:

The man then carries out the task required at 9 o'clock, perhaps putting the chess set away and leaving, perhaps proposing marriage.

Here is a somewhat more technical picture of the time flow in such a system. Time flows vertically downward. The arrows indicate messages. Each vertical line represents a single object that sends or receives a message. There is no time scale. In the above pictures the event handler asks to have itself registered, but in general there is no need for this restriction. In fact any object can register an event handler. This would be like a relative of the woman asking that the man be informed when 9 o'clock occurs, rather than the man asking for himself. In either case the man is the handler.

Event Sequence Figure

When programming in Java, the event generators are for the most part already part of the Java system and don't need to be modified. The programmer developing an applet or application will write event handlers, however. The programmer will also need to register the handler with the appropriate event generator.

In java there are several ways to register, depending on what kind of event generator we have. One of the most common is the Java Button. Buttons generate ActionEvents. There are several other kinds of events generated by other component types in Java. An event handler is technically called a listener in Java. A listener is registered with a button, by some object sending it the addActionListener message, with a parameter indicating who the listener (handler) is going to be. The button remembers who is registered. This is done automatically by code in the Java libraries.

Later, when the event occurs, the button informs the listeners (there may be several) that the event occured by sending the actionPerformed message to each of the listeners. This is also done automatically by Java library code. To be a listener you must have such a message implemented, of course. It is in this method that the listener carries out the task that is supposed to be done when the event occurs.

The action performed message has a paremeter that gives information about the event that occured. For action events this includes where the mouse was clicked and other information.

Here is an example of what the Java code might look like in a simple case.

...
Button myButton = new Button("Click Me");
myButton.addActionListener(new Clicker()); // register
...

class Clicker implements ActionListener
{ public void actionPerformed(ActionEvent e)
{ System.out.println("Click Me was clicked."); // perfrom task
}
}

An object becomes an action listener (handler for action events) by implementing the ActionListener interface and therefore the required actionPerformed public method.

Here is our picture redrawn to show the names of the Java messages. Note that we didn't give the listener a name in the avove code. Nor do we have a name for the object in which the addActionListener code appears. We use generic names for these two objects.

Also note that if the event occurs several times, the listener will be informed each time it occurs.

For more on events see the paper on event handling patterns.

Chapter 7 of Java in a Nutshell has a complete discussion of Java Events. This discussion tells which components generate events and what kind of events each can generate. It also gives the interfaces that handlers much implement in order to handle those kinds of events.

April 15, 2000

Sunday, May 2, 2010

Graphics and Imaging

Tutorial 16 - Graphics and Imaging

http://home.cogeco.ca/~ve3ll/jatutorg.htm

Graphics brings life to applications. Java allows creation and modification of images using both awt and the newerJFC 2D architecture. Artists tend to think in terms of a canvas as the foundation for their images and graphics. Swing (JPanel and JFrame) and awt (Canvas) objects can be extended for use as the basic canvas. Java applets and applications tie the canvas to the window frame. Output to the canvas takes place through a graphics context encapsulated by the Graphics class. This tutorial introduces some fundamental concepts of graphics and imaging.

The Canvas

The canvas origin (0,0) is set at the upper left corner position of its container. The graphics context is passed when thepaint() or update() method is called. Use either setSize(x,y) or setBounds(x,y,w,h) to set the canvas dimensions. Use the getGraphics() method of the Component object to get the context.

Shapes and Paths

2D shapes are contained in the awt.geom library which must be imported. The paint() method must be overridden and its Graphics object cast to a Graphics2D object. Objects are first defined with one of the following 2D constructors and then drawn with either draw(obj) [outlined shape] or fill(obj) [filled shape].

Antialiasing provides cleaner graphics and text rendition. To turn antialiasing on use:setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

ShapeawtJFC 2D
  • Line
  • Rectangle
  • (rounded)
  • Ellipse
  • Arc
  • Polygon
  • drawLine(x1,y1,x2,y2)
  • drawRect(x1,y1,x2,y2)
  • drawRoundRect(x1,y1,x2,y2,r1,r2)
  • drawOval(x,y,w,h)
  • drawArc(x,y,w,h,sdeg,ndeg)
  • drawPolygon(x[],y[],numPoints)
  • Line2D.Float(x1,y1,x2,y2)
  • Rectangle2D.Float(x1,y1,x2,y2)
  • RoundedRectangle2D.Float(x1,y1,x2,y2)
  • Ellipse2D.Float(x,y,w,h)
  • Arc2D.Float(x,y,w,h,sdeg,ndeg,clos)

2D polygons are represented by paths or series of line segments that enclose the polygon. A GeneralPath object is created and the start point set with the moveTo(x,y) method. The line segments are defined with lineTo(x,y). The polygon is then completed with ClosePath().

2D arcs are built starting with an elliptical shape, then clipped by using a start angle and degree of rotation (think compass or clock). The final parameter defines closure using one of the Arc2D constants OPEN, CHORD or PIE.

Styles and Patterns

Pen strokes control the width, endpoint and junction renderings of drawn lines. A pen nib (ie. stroke style) is constructed with BasicStroke(width,endCap,joint). Width is in pixels expressed with type float. endCap and joint are optional parameters for decorative features. The BasicStroke class has special constants for these parameters. A pen nib is changed with setStroke(nib).

Fill patterns control how a drawn object is filled in with ink. Color, gradients and textures are the common fill patterns used. A gradient fill is a gradual change of color between points. It can be acyclic (default) or cyclic (ie. repeating). Two color gradient patterns are constructed with GradientPaint(x1,y1,c1,x2,y2,c2) . Adding a parameter of true will make the pattern cyclic. Multiple color patterns use the LinearGradientPaint class. Texture patterns are constructed with TexturePaint(bufferedImage, shape). Inkwells are filled withsetPaint(patternOrColor) or setColor(color).

Project: Checkerboard Tilings

Create an applet that draws a checkerboard in black and white. Use parameters for tile dimensions and the number of tiles in each direction.

Extension #1: Randomly choose from list of color pairs.

Extension #2: Cycle through a list of color pairs.

Tile.java (found in jp8graphics.zip) is an application demo that can easily be converted into an applet.

Transforms&Composites

Affine Transforms offer complex geometric control over shapes such as translation, rotation, scaling and shearing.

Clipping can be applied to any canvas, including outlined text. setClip(shape) and clip(appendedShape) are the appropriate methods.

Using Images

Create images with img=canvasObj.createImage(iwidth,iheight);.
Load images with img=ImageIO.read(new File("fileName"));.
Warning: Use try/catch trapping techniques as exception errors can occur.
Display images with drawImage(imgObj,x,y,this).
Other useful Graphics methods are getWidth(), getHeight() and getType().

ShowImg.java (found in jp8graphics.zip) is a simple applet that displays an image.

The Applet class getImage() method can also be used for fetching images.

Image img=getImage(new URL("http://www.server.com/~user/images/image.gif")); //fetches image from absolute path Image img1=getImage(getDocumentBase(),"image.gif"); //fetches image from the html folder Image img2=getImage(getCodeBase(),"image.gif"); //fetches image from the applet folder

Adding Text

Font and FontMetrics classes allow selection of different typefaces and sizes as well as providing information on the geometry of the type. The TextLayout class can be used to add simple textual messages to graphics. The methodgetOutline(transformHandle) returns an outline of the text as a shape. This can then be displayed withdraw(shapevar). The method drawString() is used to write simple text to the canvas.

The following is a simple awt Hello Graphics World application that demonstrates how to use JFC 2D objects for text display. Included are gradient text, textured text and outlined text.

Adding Drop Shadows

jroller.com provides a great demo of drop shadows (with source code) with variable opacity.



JR's HomePage | Comments [jatutorg.htm:2009 02 11]

JFileChooser

Java: JFileChooser

Use javax.swing.JFileChooser to create a file chooser for selecting a file or directory to open or save.

http://leepoint.net/notes-java/GUI/containers/20dialogs/30filechooser.html

To Create an Open File Chooser

The code below creates a window with an Open... menu item, whose listener pops up a JFileChooser dialog.

The JFileChooser dialog box looks like the following.

  1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59   60   61   62   63   64   65   66   67   68   69   70   71   72   73   74   75   76   77   78   79   80   81   82   83   84   85   86   87   88   89   90   91   92   93   94   95   96   97   98   99  100  
// File   : gui/containers/dialogs/filechooser/CountWords.java // Purpose: Counts words in file. //          Illustrates menus, JFileChooser, Scanner.. // Author : Fred Swartz - 2006-10-10 - Placed in public domain.  import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.util.*;  //////////////////////////////////////////////////////// CountWords public class CountWords extends JFrame {      //====================================================== fields     JTextField   _fileNameTF  = new JTextField(15);     JTextField   _wordCountTF = new JTextField(4);     JFileChooser _fileChooser = new JFileChooser();      //================================================= constructor     CountWords() {         //... Create / set component characteristics.         _fileNameTF.setEditable(false);         _wordCountTF.setEditable(false);          //... Add listeners          //... Create content pane, layout components         JPanel content = new JPanel();         content.setLayout(new FlowLayout());         content.add(new JLabel("File:"));         content.add(_fileNameTF);         content.add(new JLabel("Word Count:"));         content.add(_wordCountTF);          //... Create menu elements (menubar, menu, menu item)         JMenuBar menubar  = new JMenuBar();         JMenu    fileMenu = new JMenu("File");         JMenuItem openItem = new JMenuItem("Open...");         openItem.addActionListener(new OpenAction());          //... Assemble the menu         menubar.add(fileMenu);         fileMenu.add(openItem);          //... Set window characteristics         this.setJMenuBar(menubar);         this.setContentPane(content);         this.setTitle("Count Words");         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         this.pack();                      // Layout components.         this.setLocationRelativeTo(null); // Center window.     }      //============================================= countWordsInFile     private int countWordsInFile(File f) {          int numberOfWords = 0;  // Count of words.          try {             Scanner in = new Scanner(f);              while (in.hasNext()) {                 String word = in.next();  // Read a "token".                 numberOfWords++;             }             in.close();        // Close Scanner's file.          } catch (FileNotFoundException fnfex) {             // ... We just got the file from the JFileChooser,             //     so it's hard to believe there's problem, but...             JOptionPane.showMessageDialog(CountWords.this,                         fnfex.getMessage());         }         return numberOfWords;     }       ///////////////////////////////////////////////////// OpenAction     class OpenAction implements ActionListener {         public void actionPerformed(ActionEvent ae) {             //... Open a file dialog.             int retval = _fileChooser.showOpenDialog(CountWords.this);             if (retval == JFileChooser.APPROVE_OPTION) {                 //... The user selected a file, get it, use it.                 File file = _fileChooser.getSelectedFile();                  //... Update user interface.                 _fileNameTF.setText(file.getName());                 _wordCountTF.setText("" + countWordsInFile(file));             }         }     }      //========================================================= main     public static void main(String[] args) {         JFrame window = new CountWords();         window.setVisible(true);     } } 

To display a file chooser

Use one of three methods to display the dialog after it has been created.

     r = fc.showOpenDialog(owner); // button labeled "Open"    r = fc.showSaveDialog(owner); // button labeled "Save"    r = fc.showDialog(owner, title); 

The owner parameter is the component (eg, JFrame, JPanel, ...) over which the dialog should be centered. You can use null for the owner, which will put the dialog in the center of the screen. To get the enclosing class's instance, as in this example, write the enclosing class name followed by ".this". The title parameter is a string that is used as the dialog's title and accept button text.

Checking the return value

The user may either select a file or directory, or click CANCEL or close the file chooser window. If the user selected a file or directory, the value returned will be JFileChooser.APPROVE_OPTION. Always check this value. For example,

int retval = fc.showOpenDialog(null); if (retval == JFileChooser.APPROVE_OPTION) {     . . . // The user did select a file.; 

Getting the selected file or directory

After checking for JFileChooser.APPROVE_OPTION, the File value of the selection is returned from a call ongetSelectedFile.

int retval = fc.showOpenDialog(null); if (retval == JFileChooser.APPROVE_OPTION) {     File myFile = fc.getSelectedFile();     // DO YOUR PROCESSING HERE. OPEN FILE OR ... } 

Why a file chooser is often an instance variable

Altho a new file chooser can be created inside a listener, there are advantages to creating it once outside and reusing it.

  • A file chooser remembers the directory that was last used so any reuse opens in the same directory.
  • It is also more efficient since it is created only once and customizations only have to be done once. This increases the response speed.

Files, directories, or both

By default a file chooser allows the user to select only files. To allow selection of either files or directories, or only directories, use one of the following calls.

   fc.setFileSelectionMode(JFileChooser.FILES_ONLY);   // default    fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);    fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 

Filtering files

You can specify the kinds of files that should be shown (eg, with a specific extension, ...), by supplying aJFileFilter.

  myChooser.setFileFilter(FileFilter filter);

See FileFilter. [NEEDS MORE WORK]

Specify a start directory in the constructor

The file chooser will start the file dialog at some default directory, for example, "C:\My Documents". To start the dialog at a different directory (called the current directory), specify the directory path as a String or File value in the JFileChooser constructor.

JFileChooser m_fileChooser = new JFileChooser("C:\home");

The current directory is ".".

Portability warning: If you put system specific file paths in your code, the program will not be portable to other systems. Note that the above call is therefore not portable.