This commit is contained in:
David Dehaven 2014-08-19 10:32:16 -07:00
commit b0860e6b99
243 changed files with 10166 additions and 4557 deletions

View file

@ -164,15 +164,15 @@ $(foreach R, $(JAVAX_SOUND_RULES), $(eval $(call addto_meta-inf_services, $R)))
################################################################################ ################################################################################
ifneq ($(OPENJDK_TARGET_OS), macosx) ifneq ($(OPENJDK_TARGET_OS), macosx)
OPENJDK_TARGET_OS_FLAVORMAP_PROPERTIES = $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/classes/sun/awt/datatransfer/flavormap.properties OPENJDK_TARGET_OS_FLAVORMAP_PROPERTIES = $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_API_DIR)/classes/sun/datatransfer/resources/flavormap.properties
else else
OPENJDK_TARGET_OS_FLAVORMAP_PROPERTIES = $(JDK_TOPDIR)/src/macosx/classes/sun/awt/datatransfer/flavormap.properties OPENJDK_TARGET_OS_FLAVORMAP_PROPERTIES = $(JDK_TOPDIR)/src/java.desktop/macosx/classes/sun/datatransfer/resources/flavormap.properties
endif endif
$(JDK_OUTPUTDIR)/classes/sun/awt/datatransfer/flavormap.properties: $(OPENJDK_TARGET_OS_FLAVORMAP_PROPERTIES) $(JDK_OUTPUTDIR)/classes/sun/datatransfer/resources/flavormap.properties: $(OPENJDK_TARGET_OS_FLAVORMAP_PROPERTIES)
$(install-file) $(install-file)
COPY_EXTRA += $(JDK_OUTPUTDIR)/classes/sun/awt/datatransfer/flavormap.properties COPY_EXTRA += $(JDK_OUTPUTDIR)/classes/sun/datatransfer/resources/flavormap.properties
################################################################################ ################################################################################

View file

@ -1 +0,0 @@
string=This is Java 2D! (Default)

View file

@ -1 +0,0 @@
string=This is Java 2D! (German) \u00f6 \u00df \u00dc

View file

@ -1 +0,0 @@
string=This is Java 2D! (English) A B C

View file

@ -1 +0,0 @@
string=This is Java 2D! (English in Great Britain) \u0075 \u006b Z

View file

@ -1 +0,0 @@
string=Java 2D\u3067\u3059\u3002(\u30C7\u30D5\u30A9\u30EB\u30C8)

View file

@ -1 +0,0 @@
string=This is Java 2D! (Korean)

View file

@ -1 +0,0 @@
string=\u8FD9\u662F Java 2D! (\u9ED8\u8BA4\u503C)

View file

@ -1,5 +0,0 @@
en US
en GB
ko KO
ab KO
de DE

View file

@ -114,7 +114,7 @@ public final class JRSUIControl {
changes.putAll(other.changes); changes.putAll(other.changes);
} }
protected synchronized final void finalize() throws Throwable { protected synchronized void finalize() throws Throwable {
if (cfDictionaryPtr == 0) return; if (cfDictionaryPtr == 0) return;
disposeCFDictionary(cfDictionaryPtr); disposeCFDictionary(cfDictionaryPtr);
cfDictionaryPtr = 0; cfDictionaryPtr = 0;

View file

@ -938,7 +938,11 @@ public class AquaInternalFrameUI extends BasicInternalFrameUI implements SwingCo
final Point pt = new Point(); final Point pt = new Point();
final Component c = getComponentToForwardTo(e, pt); final Component c = getComponentToForwardTo(e, pt);
if (c == null) return; if (c == null) return;
c.dispatchEvent(new MouseWheelEvent(c, e.getID(), e.getWhen(), e.getModifiers(), pt.x, pt.y, e.getClickCount(), e.isPopupTrigger(), e.getScrollType(), e.getScrollAmount(), e.getWheelRotation())); c.dispatchEvent(new MouseWheelEvent(c, e.getID(), e.getWhen(),
e.getModifiers(), pt.x, pt.y, e.getXOnScreen(), e.getYOnScreen(),
e.getClickCount(), e.isPopupTrigger(), e.getScrollType(),
e.getScrollAmount(), e.getWheelRotation(),
e.getPreciseWheelRotation()));
} }
public void componentResized(final ComponentEvent e) { public void componentResized(final ComponentEvent e) {

View file

@ -3307,7 +3307,7 @@ public class AquaTabbedPaneCopyFromBasicUI extends TabbedPaneUI implements Swing
pane.repaint(); pane.repaint();
} else if (name == "indexForTitle") { } else if (name == "indexForTitle") {
calculatedBaseline = false; calculatedBaseline = false;
updateHtmlViews((Integer) e.getNewValue()); updateHtmlViews((Integer) e.getNewValue(), false);
} else if (name == "tabLayoutPolicy") { } else if (name == "tabLayoutPolicy") {
AquaTabbedPaneCopyFromBasicUI.this.uninstallUI(pane); AquaTabbedPaneCopyFromBasicUI.this.uninstallUI(pane);
AquaTabbedPaneCopyFromBasicUI.this.installUI(pane); AquaTabbedPaneCopyFromBasicUI.this.installUI(pane);
@ -3345,7 +3345,7 @@ public class AquaTabbedPaneCopyFromBasicUI extends TabbedPaneUI implements Swing
calculatedBaseline = false; calculatedBaseline = false;
} else if (name == "indexForNullComponent") { } else if (name == "indexForNullComponent") {
isRunsDirty = true; isRunsDirty = true;
updateHtmlViews((Integer) e.getNewValue()); updateHtmlViews((Integer) e.getNewValue(), true);
} else if (name == "font") { } else if (name == "font") {
calculatedBaseline = false; calculatedBaseline = false;
} }
@ -3464,10 +3464,10 @@ public class AquaTabbedPaneCopyFromBasicUI extends TabbedPaneUI implements Swing
return; return;
} }
isRunsDirty = true; isRunsDirty = true;
updateHtmlViews(tp.indexOfComponent(child)); updateHtmlViews(tp.indexOfComponent(child), true);
} }
private void updateHtmlViews(int index) { private void updateHtmlViews(int index, boolean inserted) {
final String title = tabPane.getTitleAt(index); final String title = tabPane.getTitleAt(index);
final boolean isHTML = BasicHTML.isHTMLString(title); final boolean isHTML = BasicHTML.isHTMLString(title);
if (isHTML) { if (isHTML) {
@ -3475,16 +3475,24 @@ public class AquaTabbedPaneCopyFromBasicUI extends TabbedPaneUI implements Swing
htmlViews = createHTMLVector(); htmlViews = createHTMLVector();
} else { // Vector already exists } else { // Vector already exists
final View v = BasicHTML.createHTMLView(tabPane, title); final View v = BasicHTML.createHTMLView(tabPane, title);
htmlViews.insertElementAt(v, index); setHtmlView(v, inserted, index);
} }
} else { // Not HTML } else { // Not HTML
if (htmlViews != null) { // Add placeholder if (htmlViews != null) { // Add placeholder
htmlViews.insertElementAt(null, index); setHtmlView(null, inserted, index);
} // else nada! } // else nada!
} }
updateMnemonics(); updateMnemonics();
} }
private void setHtmlView(View v, boolean inserted, int index) {
if (inserted || index >= htmlViews.size()) {
htmlViews.insertElementAt(v, index);
} else {
htmlViews.setElementAt(v, index);
}
}
public void componentRemoved(final ContainerEvent e) { public void componentRemoved(final ContainerEvent e) {
final JTabbedPane tp = (JTabbedPane)e.getContainer(); final JTabbedPane tp = (JTabbedPane)e.getContainer();
final Component child = e.getChild(); final Component child = e.getChild();

View file

@ -43,7 +43,7 @@ import sun.awt.HeadlessToolkit;
import sun.awt.util.ThreadGroupUtils; import sun.awt.util.ThreadGroupUtils;
import sun.lwawt.macosx.*; import sun.lwawt.macosx.*;
public class CFontManager extends SunFontManager { public final class CFontManager extends SunFontManager {
private FontConfigManager fcManager = null; private FontConfigManager fcManager = null;
private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>(); private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>();
@ -61,20 +61,14 @@ public class CFontManager extends SunFontManager {
return new CFontConfiguration(this, preferLocaleFonts, preferPropFonts); return new CFontConfiguration(this, preferLocaleFonts, preferPropFonts);
} }
private static String[] defaultPlatformFont = null;
/* /*
* Returns an array of two strings. The first element is the * Returns an array of two strings. The first element is the
* name of the font. The second element is the file name. * name of the font. The second element is the file name.
*/ */
@Override @Override
public synchronized String[] getDefaultPlatformFont() { protected String[] getDefaultPlatformFont() {
if (defaultPlatformFont == null) { return new String[]{"Lucida Grande",
defaultPlatformFont = new String[2]; "/System/Library/Fonts/LucidaGrande.ttc"};
defaultPlatformFont[0] = "Lucida Grande";
defaultPlatformFont[1] = "/System/Library/Fonts/LucidaGrande.ttc";
}
return defaultPlatformFont;
} }
// This is a way to register any kind of Font2D, not just files and composites. // This is a way to register any kind of Font2D, not just files and composites.

View file

@ -1233,11 +1233,13 @@ public abstract class LWComponentPeer<T extends Component, D extends JComponent>
delegate, me.getID(), me.getWhen(), delegate, me.getID(), me.getWhen(),
me.getModifiers(), me.getModifiers(),
me.getX(), me.getY(), me.getX(), me.getY(),
me.getXOnScreen(), me.getYOnScreen(),
me.getClickCount(), me.getClickCount(),
me.isPopupTrigger(), me.isPopupTrigger(),
me.getScrollType(), me.getScrollType(),
me.getScrollAmount(), me.getScrollAmount(),
me.getWheelRotation()); me.getWheelRotation(),
me.getPreciseWheelRotation());
} else if (e instanceof MouseEvent) { } else if (e instanceof MouseEvent) {
MouseEvent me = (MouseEvent) e; MouseEvent me = (MouseEvent) e;

View file

@ -105,6 +105,8 @@ public class LWWindowPeer
private final SecurityWarningWindow warningWindow; private final SecurityWarningWindow warningWindow;
private volatile boolean targetFocusable;
/** /**
* Current modal blocker or null. * Current modal blocker or null.
* *
@ -240,13 +242,12 @@ public class LWWindowPeer
if (!visible && warningWindow != null) { if (!visible && warningWindow != null) {
warningWindow.setVisible(false, false); warningWindow.setVisible(false, false);
} }
updateFocusableWindowState();
super.setVisibleImpl(visible); super.setVisibleImpl(visible);
// TODO: update graphicsConfig, see 4868278 // TODO: update graphicsConfig, see 4868278
platformWindow.setVisible(visible); platformWindow.setVisible(visible);
if (isSimpleWindow()) { if (isSimpleWindow()) {
KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance(); KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
if (visible) { if (visible) {
if (!getTarget().isAutoRequestFocus()) { if (!getTarget().isAutoRequestFocus()) {
return; return;
@ -397,6 +398,7 @@ public class LWWindowPeer
@Override @Override
public void updateFocusableWindowState() { public void updateFocusableWindowState() {
targetFocusable = getTarget().isFocusableWindow();
platformWindow.updateFocusableWindowState(); platformWindow.updateFocusableWindowState();
} }
@ -1220,13 +1222,13 @@ public class LWWindowPeer
} }
private boolean isFocusableWindow() { private boolean isFocusableWindow() {
boolean focusable = getTarget().isFocusableWindow(); boolean focusable = targetFocusable;
if (isSimpleWindow()) { if (isSimpleWindow()) {
LWWindowPeer ownerPeer = getOwnerFrameDialog(this); LWWindowPeer ownerPeer = getOwnerFrameDialog(this);
if (ownerPeer == null) { if (ownerPeer == null) {
return false; return false;
} }
return focusable && ownerPeer.getTarget().isFocusableWindow(); return focusable && ownerPeer.targetFocusable;
} }
return focusable; return focusable;
} }

View file

@ -38,7 +38,8 @@ public class CEmbeddedFrame extends EmbeddedFrame {
private CPlatformResponder responder; private CPlatformResponder responder;
private static final Object classLock = new Object(); private static final Object classLock = new Object();
private static volatile CEmbeddedFrame focusedWindow; private static volatile CEmbeddedFrame globalFocusedWindow;
private CEmbeddedFrame browserWindowFocusedApplet;
private boolean parentWindowActive = true; private boolean parentWindowActive = true;
public CEmbeddedFrame() { public CEmbeddedFrame() {
@ -111,10 +112,10 @@ public class CEmbeddedFrame extends EmbeddedFrame {
synchronized (classLock) { synchronized (classLock) {
// In some cases an applet may not receive the focus lost event // In some cases an applet may not receive the focus lost event
// from the parent window (see 8012330) // from the parent window (see 8012330)
focusedWindow = (focused) ? this globalFocusedWindow = (focused) ? this
: ((focusedWindow == this) ? null : focusedWindow); : ((globalFocusedWindow == this) ? null : globalFocusedWindow);
} }
if (focusedWindow == this) { if (globalFocusedWindow == this) {
// see bug 8010925 // see bug 8010925
// we can't put this to handleWindowFocusEvent because // we can't put this to handleWindowFocusEvent because
// it won't be invoced if focuse is moved to a html element // it won't be invoced if focuse is moved to a html element
@ -145,9 +146,23 @@ public class CEmbeddedFrame extends EmbeddedFrame {
// non-focused applet. This method can be called from different threads. // non-focused applet. This method can be called from different threads.
public void handleWindowFocusEvent(boolean parentWindowActive) { public void handleWindowFocusEvent(boolean parentWindowActive) {
this.parentWindowActive = parentWindowActive; this.parentWindowActive = parentWindowActive;
// If several applets are running in different browser's windows, it is necessary to
// detect the switching between the parent windows and update globalFocusedWindow accordingly.
synchronized (classLock) {
if (!parentWindowActive) {
this.browserWindowFocusedApplet = globalFocusedWindow;
}
if (parentWindowActive && globalFocusedWindow != this && isParentWindowChanged()) {
// It looks like we have switched to another browser window, let's restore focus to
// the previously focused applet in this window. If no applets were focused in the
// window, we will set focus to the first applet in the window.
globalFocusedWindow = (this.browserWindowFocusedApplet != null) ? this.browserWindowFocusedApplet
: this;
}
}
// ignore focus "lost" native request as it may mistakenly // ignore focus "lost" native request as it may mistakenly
// deactivate active window (see 8001161) // deactivate active window (see 8001161)
if (focusedWindow == this && parentWindowActive) { if (globalFocusedWindow == this && parentWindowActive) {
responder.handleWindowFocusEvent(parentWindowActive, null); responder.handleWindowFocusEvent(parentWindowActive, null);
} }
} }
@ -155,4 +170,10 @@ public class CEmbeddedFrame extends EmbeddedFrame {
public boolean isParentWindowActive() { public boolean isParentWindowActive() {
return parentWindowActive; return parentWindowActive;
} }
private boolean isParentWindowChanged() {
// If globalFocusedWindow is located at inactive parent window or null, we have swithed to
// another window.
return globalFocusedWindow != null ? !globalFocusedWindow.isParentWindowActive() : true;
}
} }

View file

@ -54,11 +54,11 @@ public final class NSPrintInfo implements PrintJobAttribute, PrintRequestAttribu
return "" + fNSPrintInfo; return "" + fNSPrintInfo;
} }
public final Class<? extends Attribute> getCategory() { public Class<? extends Attribute> getCategory() {
return NSPrintInfo.class; return NSPrintInfo.class;
} }
public final String getName() { public String getName() {
return "nsPrintInfo"; return "nsPrintInfo";
} }
} }

View file

@ -1108,7 +1108,10 @@ static NSObject *sAttributeNamesLOCK = nil;
JNIEnv *env = [ThreadUtilities getJNIEnv]; JNIEnv *env = [ThreadUtilities getJNIEnv];
id value = nil; id value = nil;
NSWindow* hostWindow = [[self->fView window] retain];
jobject focused = JNFCallStaticObjectMethod(env, jm_getFocusOwner, fComponent); // AWT_THREADING Safe (AWTRunLoop) jobject focused = JNFCallStaticObjectMethod(env, jm_getFocusOwner, fComponent); // AWT_THREADING Safe (AWTRunLoop)
[hostWindow release];
if (focused != NULL) { if (focused != NULL) {
if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) { if (JNFIsInstanceOf(env, focused, &sjc_Accessible)) {
value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView]; value = [JavaComponentAccessibility createWithAccessible:focused withEnv:env withView:fView];

View file

@ -68,7 +68,7 @@ public final class FFT {
calc(fftFrameSize, data, sign, w); calc(fftFrameSize, data, sign, w);
} }
private final static double[] computeTwiddleFactors(int fftFrameSize, private static double[] computeTwiddleFactors(int fftFrameSize,
int sign) { int sign) {
int imax = (int) (Math.log(fftFrameSize) / Math.log(2.)); int imax = (int) (Math.log(fftFrameSize) / Math.log(2.));
@ -122,7 +122,7 @@ public final class FFT {
return warray; return warray;
} }
private final static void calc(int fftFrameSize, double[] data, int sign, private static void calc(int fftFrameSize, double[] data, int sign,
double[] w) { double[] w) {
final int fftFrameSize2 = fftFrameSize << 1; final int fftFrameSize2 = fftFrameSize << 1;
@ -139,7 +139,7 @@ public final class FFT {
} }
private final static void calcF2E(int fftFrameSize, double[] data, int i, private static void calcF2E(int fftFrameSize, double[] data, int i,
int nstep, double[] w) { int nstep, double[] w) {
int jmax = nstep; int jmax = nstep;
for (int n = 0; n < jmax; n += 2) { for (int n = 0; n < jmax; n += 2) {
@ -163,7 +163,7 @@ public final class FFT {
// Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
// complex operators // complex operators
private final static void calcF4F(int fftFrameSize, double[] data, int i, private static void calcF4F(int fftFrameSize, double[] data, int i,
int nstep, double[] w) { int nstep, double[] w) {
final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
// Factor-4 Decomposition // Factor-4 Decomposition
@ -331,7 +331,7 @@ public final class FFT {
// Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
// complex operators // complex operators
private final static void calcF4I(int fftFrameSize, double[] data, int i, private static void calcF4I(int fftFrameSize, double[] data, int i,
int nstep, double[] w) { int nstep, double[] w) {
final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
// Factor-4 Decomposition // Factor-4 Decomposition
@ -499,7 +499,7 @@ public final class FFT {
// Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
// complex operators // complex operators
private final static void calcF4FE(int fftFrameSize, double[] data, int i, private static void calcF4FE(int fftFrameSize, double[] data, int i,
int nstep, double[] w) { int nstep, double[] w) {
final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
// Factor-4 Decomposition // Factor-4 Decomposition
@ -593,7 +593,7 @@ public final class FFT {
// Perform Factor-4 Decomposition with 3 * complex operators and 8 +/- // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
// complex operators // complex operators
private final static void calcF4IE(int fftFrameSize, double[] data, int i, private static void calcF4IE(int fftFrameSize, double[] data, int i,
int nstep, double[] w) { int nstep, double[] w) {
final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize; final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
// Factor-4 Decomposition // Factor-4 Decomposition
@ -685,7 +685,7 @@ public final class FFT {
} }
private final void bitreversal(double[] data) { private void bitreversal(double[] data) {
if (fftFrameSize < 4) if (fftFrameSize < 4)
return; return;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,8 @@
package com.sun.media.sound; package com.sun.media.sound;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -176,11 +178,11 @@ public final class JDK13Services {
&& !Sequencer.class.equals(typeClass)) { && !Sequencer.class.equals(typeClass)) {
return null; return null;
} }
String value; String name = typeClass.getName();
String propertyName = typeClass.getName(); String value = AccessController.doPrivileged(
value = JSSecurityManager.getProperty(propertyName); (PrivilegedAction<String>) () -> System.getProperty(name));
if (value == null) { if (value == null) {
value = getProperties().getProperty(propertyName); value = getProperties().getProperty(name);
} }
if ("".equals(value)) { if ("".equals(value)) {
value = null; value = null;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -73,33 +73,6 @@ final class JSSecurityManager {
} }
} }
static String getProperty(final String propertyName) {
String propertyValue;
if (hasSecurityManager()) {
if(Printer.debug) Printer.debug("using JDK 1.2 security to get property");
try{
PrivilegedAction<String> action = new PrivilegedAction<String>() {
public String run() {
try {
return System.getProperty(propertyName);
} catch (Throwable t) {
return null;
}
}
};
propertyValue = AccessController.doPrivileged(action);
} catch( Exception e ) {
if(Printer.debug) Printer.debug("not using JDK 1.2 security to get properties");
propertyValue = System.getProperty(propertyName);
}
} else {
if(Printer.debug) Printer.debug("not using JDK 1.2 security to get properties");
propertyValue = System.getProperty(propertyName);
}
return propertyValue;
}
/** Load properties from a file. /** Load properties from a file.
This method tries to load properties from the filename give into This method tries to load properties from the filename give into
the passed properties object. the passed properties object.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -74,17 +74,6 @@ final class Platform {
// intel is little-endian. sparc is big-endian. // intel is little-endian. sparc is big-endian.
private static boolean bigEndian; private static boolean bigEndian;
// this is the value of the "java.home" system property. i am looking it up here
// for use when trying to load the soundbank, just so
// that all the privileged code is localized in this file....
private static String javahome;
// this is the value of the "java.class.path" system property
private static String classpath;
static { static {
if(Printer.trace)Printer.trace(">> Platform.java: static"); if(Printer.trace)Printer.trace(">> Platform.java: static");
@ -129,26 +118,6 @@ final class Platform {
return signed8; return signed8;
} }
/**
* Obtain javahome.
* $$kk: 04.16.99: this is *bad*!!
*/
static String getJavahome() {
return javahome;
}
/**
* Obtain classpath.
* $$jb: 04.21.99: this is *bad* too!!
*/
static String getClasspath() {
return classpath;
}
// PRIVATE METHODS // PRIVATE METHODS
/** /**
@ -157,21 +126,13 @@ final class Platform {
private static void loadLibraries() { private static void loadLibraries() {
if(Printer.trace)Printer.trace(">>Platform.loadLibraries"); if(Printer.trace)Printer.trace(">>Platform.loadLibraries");
try {
// load the main library // load the main library
AccessController.doPrivileged(new PrivilegedAction<Void>() { AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
@Override
public Void run() {
System.loadLibrary(libNameMain); System.loadLibrary(libNameMain);
return null; return null;
}
}); });
// just for the heck of it... // just for the heck of it...
loadedLibs |= LIB_MAIN; loadedLibs |= LIB_MAIN;
} catch (SecurityException e) {
if(Printer.err)Printer.err("Security exception loading main native library. JavaSound requires access to these resources.");
throw(e);
}
// now try to load extra libs. They are defined at compile time in the Makefile // now try to load extra libs. They are defined at compile time in the Makefile
// with the define EXTRA_SOUND_JNI_LIBS // with the define EXTRA_SOUND_JNI_LIBS
@ -181,12 +142,9 @@ final class Platform {
while (st.hasMoreTokens()) { while (st.hasMoreTokens()) {
final String lib = st.nextToken(); final String lib = st.nextToken();
try { try {
AccessController.doPrivileged(new PrivilegedAction<Void>() { AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
@Override
public Void run() {
System.loadLibrary(lib); System.loadLibrary(lib);
return null; return null;
}
}); });
if (lib.equals(libNameALSA)) { if (lib.equals(libNameALSA)) {
@ -239,7 +197,5 @@ final class Platform {
// $$fb 2002-03-06: implement check for endianness in native. Facilitates porting ! // $$fb 2002-03-06: implement check for endianness in native. Facilitates porting !
bigEndian = nIsBigEndian(); bigEndian = nIsBigEndian();
signed8 = nIsSigned8(); // Solaris on Sparc: signed, all others unsigned signed8 = nIsSigned8(); // Solaris on Sparc: signed, all others unsigned
javahome = JSSecurityManager.getProperty("java.home");
classpath = JSSecurityManager.getProperty("java.class.path");
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,21 +39,20 @@ public final class RIFFReader extends InputStream {
private long filepointer = 0; private long filepointer = 0;
private final String fourcc; private final String fourcc;
private String riff_type = null; private String riff_type = null;
private long ckSize = 0; private long ckSize = Integer.MAX_VALUE;
private InputStream stream; private InputStream stream;
private long avail; private long avail = Integer.MAX_VALUE;
private RIFFReader lastiterator = null; private RIFFReader lastiterator = null;
public RIFFReader(InputStream stream) throws IOException { public RIFFReader(InputStream stream) throws IOException {
if (stream instanceof RIFFReader) if (stream instanceof RIFFReader) {
root = ((RIFFReader) stream).root; root = ((RIFFReader) stream).root;
else } else {
root = this; root = this;
}
this.stream = stream; this.stream = stream;
avail = Integer.MAX_VALUE;
ckSize = Integer.MAX_VALUE;
// Check for RIFF null paddings, // Check for RIFF null paddings,
int b; int b;
@ -76,10 +75,12 @@ public final class RIFFReader extends InputStream {
readFully(fourcc, 1, 3); readFully(fourcc, 1, 3);
this.fourcc = new String(fourcc, "ascii"); this.fourcc = new String(fourcc, "ascii");
ckSize = readUnsignedInt(); ckSize = readUnsignedInt();
avail = ckSize;
avail = this.ckSize;
if (getFormat().equals("RIFF") || getFormat().equals("LIST")) { if (getFormat().equals("RIFF") || getFormat().equals("LIST")) {
if (avail > Integer.MAX_VALUE) {
throw new RIFFInvalidDataException("Chunk size too big");
}
byte[] format = new byte[4]; byte[] format = new byte[4];
readFully(format); readFully(format);
this.riff_type = new String(format, "ascii"); this.riff_type = new String(format, "ascii");
@ -118,19 +119,23 @@ public final class RIFFReader extends InputStream {
} }
public int read() throws IOException { public int read() throws IOException {
if (avail == 0) if (avail == 0) {
return -1; return -1;
}
int b = stream.read(); int b = stream.read();
if (b == -1) if (b == -1) {
avail = 0;
return -1; return -1;
}
avail--; avail--;
filepointer++; filepointer++;
return b; return b;
} }
public int read(byte[] b, int offset, int len) throws IOException { public int read(byte[] b, int offset, int len) throws IOException {
if (avail == 0) if (avail == 0) {
return -1; return -1;
}
if (len > avail) { if (len > avail) {
int rlen = stream.read(b, offset, (int)avail); int rlen = stream.read(b, offset, (int)avail);
if (rlen != -1) if (rlen != -1)
@ -139,19 +144,21 @@ public final class RIFFReader extends InputStream {
return rlen; return rlen;
} else { } else {
int ret = stream.read(b, offset, len); int ret = stream.read(b, offset, len);
if (ret == -1) if (ret == -1) {
avail = 0;
return -1; return -1;
}
avail -= ret; avail -= ret;
filepointer += ret; filepointer += ret;
return ret; return ret;
} }
} }
public final void readFully(byte b[]) throws IOException { public void readFully(byte b[]) throws IOException {
readFully(b, 0, b.length); readFully(b, 0, b.length);
} }
public final void readFully(byte b[], int off, int len) throws IOException { public void readFully(byte b[], int off, int len) throws IOException {
if (len < 0) if (len < 0)
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
while (len > 0) { while (len > 0) {
@ -165,7 +172,7 @@ public final class RIFFReader extends InputStream {
} }
} }
public final long skipBytes(long n) throws IOException { public long skipBytes(long n) throws IOException {
if (n < 0) if (n < 0)
return 0; return 0;
long skipped = 0; long skipped = 0;
@ -191,8 +198,10 @@ public final class RIFFReader extends InputStream {
return len; return len;
} else { } else {
long ret = stream.skip(n); long ret = stream.skip(n);
if (ret == -1) if (ret == -1) {
avail = 0;
return -1; return -1;
}
avail -= ret; avail -= ret;
filepointer += ret; filepointer += ret;
return ret; return ret;
@ -210,8 +219,13 @@ public final class RIFFReader extends InputStream {
} }
// Read ASCII chars from stream // Read ASCII chars from stream
public String readString(int len) throws IOException { public String readString(final int len) throws IOException {
byte[] buff = new byte[len]; final byte[] buff;
try {
buff = new byte[len];
} catch (final OutOfMemoryError oom) {
throw new IOException("Length too big", oom);
}
readFully(buff); readFully(buff);
for (int i = 0; i < buff.length; i++) { for (int i = 0; i < buff.length; i++) {
if (buff[i] == 0) { if (buff[i] == 0) {

View file

@ -276,6 +276,9 @@ public final class SF2Soundbank implements Soundbank {
count--; count--;
} }
if (presets_bagNdx.isEmpty()) {
throw new RIFFInvalidDataException();
}
int offset = presets_bagNdx.get(0); int offset = presets_bagNdx.get(0);
// Offset should be 0 (but just case) // Offset should be 0 (but just case)
for (int i = 0; i < offset; i++) { for (int i = 0; i < offset; i++) {
@ -360,6 +363,9 @@ public final class SF2Soundbank implements Soundbank {
count--; count--;
} }
if (instruments_bagNdx.isEmpty()) {
throw new RIFFInvalidDataException();
}
int offset = instruments_bagNdx.get(0); int offset = instruments_bagNdx.get(0);
// Offset should be 0 (but just case) // Offset should be 0 (but just case)
for (int i = 0; i < offset; i++) { for (int i = 0; i < offset; i++) {
@ -401,6 +407,9 @@ public final class SF2Soundbank implements Soundbank {
modulator.amount = chunk.readShort(); modulator.amount = chunk.readShort();
modulator.amountSourceOperator = chunk.readUnsignedShort(); modulator.amountSourceOperator = chunk.readUnsignedShort();
modulator.transportOperator = chunk.readUnsignedShort(); modulator.transportOperator = chunk.readUnsignedShort();
if (i < 0 || i >= instruments_splits_gen.size()) {
throw new RIFFInvalidDataException();
}
SF2LayerRegion split = instruments_splits_gen.get(i); SF2LayerRegion split = instruments_splits_gen.get(i);
if (split != null) if (split != null)
split.modulators.add(modulator); split.modulators.add(modulator);
@ -424,6 +433,7 @@ public final class SF2Soundbank implements Soundbank {
sample.name = chunk.readString(20); sample.name = chunk.readString(20);
long start = chunk.readUnsignedInt(); long start = chunk.readUnsignedInt();
long end = chunk.readUnsignedInt(); long end = chunk.readUnsignedInt();
if (sampleData != null)
sample.data = sampleData.subbuffer(start * 2, end * 2, true); sample.data = sampleData.subbuffer(start * 2, end * 2, true);
if (sampleData24 != null) if (sampleData24 != null)
sample.data24 = sampleData24.subbuffer(start, end, true); sample.data24 = sampleData24.subbuffer(start, end, true);
@ -462,6 +472,9 @@ public final class SF2Soundbank implements Soundbank {
int sampleid = split.generators.get( int sampleid = split.generators.get(
SF2LayerRegion.GENERATOR_SAMPLEID); SF2LayerRegion.GENERATOR_SAMPLEID);
split.generators.remove(SF2LayerRegion.GENERATOR_SAMPLEID); split.generators.remove(SF2LayerRegion.GENERATOR_SAMPLEID);
if (sampleid < 0 || sampleid >= samples.size()) {
throw new RIFFInvalidDataException();
}
split.sample = samples.get(sampleid); split.sample = samples.get(sampleid);
} else { } else {
globalsplit = split; globalsplit = split;
@ -488,6 +501,9 @@ public final class SF2Soundbank implements Soundbank {
int instrumentid = split.generators.get( int instrumentid = split.generators.get(
SF2InstrumentRegion.GENERATOR_INSTRUMENT); SF2InstrumentRegion.GENERATOR_INSTRUMENT);
split.generators.remove(SF2LayerRegion.GENERATOR_INSTRUMENT); split.generators.remove(SF2LayerRegion.GENERATOR_INSTRUMENT);
if (instrumentid < 0 || instrumentid >= layers.size()) {
throw new RIFFInvalidDataException();
}
split.layer = layers.get(instrumentid); split.layer = layers.get(instrumentid);
} else { } else {
globalsplit = split; globalsplit = split;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,6 +22,7 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package com.sun.media.sound; package com.sun.media.sound;
import java.io.File; import java.io.File;
@ -39,14 +40,14 @@ import javax.sound.midi.Receiver;
import javax.sound.midi.Sequence; import javax.sound.midi.Sequence;
import javax.sound.midi.Track; import javax.sound.midi.Track;
import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFileFormat.Type;
import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.UnsupportedAudioFileException; import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.AudioFileFormat.Type;
import javax.sound.sampled.spi.AudioFileReader; import javax.sound.sampled.spi.AudioFileReader;
/** /**
* MIDI File Audio Renderer/Reader * MIDI File Audio Renderer/Reader.
* *
* @author Karl Helgason * @author Karl Helgason
*/ */
@ -109,6 +110,9 @@ public final class SoftMidiAudioFileReader extends AudioFileReader {
if (divtype == Sequence.PPQ) { if (divtype == Sequence.PPQ) {
if (((MetaMessage) msg).getType() == 0x51) { if (((MetaMessage) msg).getType() == 0x51) {
byte[] data = ((MetaMessage) msg).getData(); byte[] data = ((MetaMessage) msg).getData();
if (data.length < 3) {
throw new UnsupportedAudioFileException();
}
mpq = ((data[0] & 0xff) << 16) mpq = ((data[0] & 0xff) << 16)
| ((data[1] & 0xff) << 8) | (data[2] & 0xff); | ((data[1] & 0xff) << 8) | (data[2] & 0xff);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,7 @@ package com.sun.media.sound;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -732,31 +733,28 @@ public final class SoftSynthesizer implements AudioSynthesizer,
* Save generated soundbank to disk for faster future use. * Save generated soundbank to disk for faster future use.
*/ */
OutputStream out = AccessController OutputStream out = AccessController
.doPrivileged(new PrivilegedAction<OutputStream>() { .doPrivileged((PrivilegedAction<OutputStream>) () -> {
public OutputStream run() {
try { try {
File userhome = new File(System File userhome = new File(System
.getProperty("user.home"), .getProperty("user.home"), ".gervill");
".gervill"); if (!userhome.exists()) {
if (!userhome.exists())
userhome.mkdirs(); userhome.mkdirs();
}
File emg_soundbank_file = new File( File emg_soundbank_file = new File(
userhome, "soundbank-emg.sf2"); userhome, "soundbank-emg.sf2");
if (emg_soundbank_file.exists()) if (emg_soundbank_file.exists()) {
return null;
return new FileOutputStream(
emg_soundbank_file);
} catch (IOException e) {
} catch (SecurityException e) {
}
return null; return null;
} }
return new FileOutputStream(emg_soundbank_file);
} catch (final FileNotFoundException ignored) {
}
return null;
}); });
if (out != null) { if (out != null) {
try { try {
((SF2Soundbank) defaultSoundBank).save(out); ((SF2Soundbank) defaultSoundBank).save(out);
out.close(); out.close();
} catch (IOException e) { } catch (final IOException ignored) {
} }
} }
} }
@ -846,8 +844,7 @@ public final class SoftSynthesizer implements AudioSynthesizer,
private Properties getStoredProperties() { private Properties getStoredProperties() {
return AccessController return AccessController
.doPrivileged(new PrivilegedAction<Properties>() { .doPrivileged((PrivilegedAction<Properties>) () -> {
public Properties run() {
Properties p = new Properties(); Properties p = new Properties();
String notePath = "/com/sun/media/sound/softsynthesizer"; String notePath = "/com/sun/media/sound/softsynthesizer";
try { try {
@ -857,15 +854,14 @@ public final class SoftSynthesizer implements AudioSynthesizer,
String[] prefs_keys = prefs.keys(); String[] prefs_keys = prefs.keys();
for (String prefs_key : prefs_keys) { for (String prefs_key : prefs_keys) {
String val = prefs.get(prefs_key, null); String val = prefs.get(prefs_key, null);
if (val != null) if (val != null) {
p.setProperty(prefs_key, val); p.setProperty(prefs_key, val);
} }
} }
} catch (BackingStoreException e) { }
} catch (SecurityException e) { } catch (final BackingStoreException ignored) {
} }
return p; return p;
}
}); });
} }
@ -1044,7 +1040,6 @@ public final class SoftSynthesizer implements AudioSynthesizer,
return; return;
} }
synchronized (control_mutex) { synchronized (control_mutex) {
Throwable causeException = null;
try { try {
if (line != null) { if (line != null) {
// can throw IllegalArgumentException // can throw IllegalArgumentException
@ -1117,24 +1112,17 @@ public final class SoftSynthesizer implements AudioSynthesizer,
weakstream.sourceDataLine = sourceDataLine; weakstream.sourceDataLine = sourceDataLine;
} }
} catch (LineUnavailableException e) { } catch (final LineUnavailableException | SecurityException
causeException = e; | IllegalArgumentException e) {
} catch (IllegalArgumentException e) { if (isOpen()) {
causeException = e;
} catch (SecurityException e) {
causeException = e;
}
if (causeException != null) {
if (isOpen())
close(); close();
}
// am: need MidiUnavailableException(Throwable) ctor! // am: need MidiUnavailableException(Throwable) ctor!
MidiUnavailableException ex = new MidiUnavailableException( MidiUnavailableException ex = new MidiUnavailableException(
"Can not open line"); "Can not open line");
ex.initCause(causeException); ex.initCause(e);
throw ex; throw ex;
} }
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,27 +25,25 @@
package com.sun.media.sound; package com.sun.media.sound;
import java.io.BufferedInputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.EOFException; import java.io.InputStream;
import java.io.BufferedInputStream;
import java.net.URL; import java.net.URL;
import javax.sound.midi.MidiFileFormat;
import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MetaMessage; import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiEvent; import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiFileFormat;
import javax.sound.midi.MidiMessage; import javax.sound.midi.MidiMessage;
import javax.sound.midi.Sequence; import javax.sound.midi.Sequence;
import javax.sound.midi.SysexMessage; import javax.sound.midi.SysexMessage;
import javax.sound.midi.Track; import javax.sound.midi.Track;
import javax.sound.midi.spi.MidiFileReader; import javax.sound.midi.spi.MidiFileReader;
/** /**
* MIDI file reader. * MIDI file reader.
* *
@ -53,19 +51,23 @@ import javax.sound.midi.spi.MidiFileReader;
* @author Jan Borgersen * @author Jan Borgersen
* @author Florian Bomers * @author Florian Bomers
*/ */
public final class StandardMidiFileReader extends MidiFileReader { public final class StandardMidiFileReader extends MidiFileReader {
private static final int MThd_MAGIC = 0x4d546864; // 'MThd' private static final int MThd_MAGIC = 0x4d546864; // 'MThd'
private static final int bisBufferSize = 1024; // buffer size in buffered input streams private static final int bisBufferSize = 1024; // buffer size in buffered input streams
public MidiFileFormat getMidiFileFormat(InputStream stream) throws InvalidMidiDataException, IOException { public MidiFileFormat getMidiFileFormat(InputStream stream)
throws InvalidMidiDataException, IOException {
return getMidiFileFormatFromStream(stream, MidiFileFormat.UNKNOWN_LENGTH, null); return getMidiFileFormatFromStream(stream, MidiFileFormat.UNKNOWN_LENGTH, null);
} }
// $$fb 2002-04-17: part of fix for 4635286: MidiSystem.getMidiFileFormat() returns format having invalid length // $$fb 2002-04-17: part of fix for 4635286: MidiSystem.getMidiFileFormat()
private MidiFileFormat getMidiFileFormatFromStream(InputStream stream, int fileLength, SMFParser smfParser) throws InvalidMidiDataException, IOException { // returns format having invalid length
private MidiFileFormat getMidiFileFormatFromStream(InputStream stream,
int fileLength,
SMFParser smfParser)
throws InvalidMidiDataException, IOException{
int maxReadLength = 16; int maxReadLength = 16;
int duration = MidiFileFormat.UNKNOWN_LENGTH; int duration = MidiFileFormat.UNKNOWN_LENGTH;
DataInputStream dis; DataInputStream dis;
@ -230,7 +232,7 @@ public final class StandardMidiFileReader extends MidiFileReader {
//============================================================================================================= //=============================================================================================================
/** /**
* State variables during parsing of a MIDI file * State variables during parsing of a MIDI file.
*/ */
final class SMFParser { final class SMFParser {
private static final int MTrk_MAGIC = 0x4d54726b; // 'MTrk' private static final int MTrk_MAGIC = 0x4d54726b; // 'MTrk'
@ -297,7 +299,11 @@ final class SMFParser {
} }
} }
// now read track in a byte array // now read track in a byte array
try {
trackData = new byte[trackLength]; trackData = new byte[trackLength];
} catch (final OutOfMemoryError oom) {
throw new IOException("Track length too big", oom);
}
try { try {
// $$fb 2003-08-20: fix for 4910986: MIDI file parser breaks up on http connection // $$fb 2003-08-20: fix for 4910986: MIDI file parser breaks up on http connection
stream.readFully(trackData); stream.readFully(trackData);
@ -386,8 +392,13 @@ final class SMFParser {
// meta // meta
int metaType = readUnsigned(); int metaType = readUnsigned();
int metaLength = (int) readVarInt(); int metaLength = (int) readVarInt();
final byte[] metaData;
try {
metaData = new byte[metaLength];
} catch (final OutOfMemoryError oom) {
throw new IOException("Meta length too big", oom);
}
byte[] metaData = new byte[metaLength];
read(metaData); read(metaData);
MetaMessage metaMessage = new MetaMessage(); MetaMessage metaMessage = new MetaMessage();
@ -413,5 +424,4 @@ final class SMFParser {
throw new EOFException("invalid MIDI file"); throw new EOFException("invalid MIDI file");
} }
} }
} }

View file

@ -25,7 +25,7 @@
package java.awt.datatransfer; package java.awt.datatransfer;
import java.awt.EventQueue; import sun.datatransfer.DataFlavorUtil;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@ -130,7 +130,8 @@ public class Clipboard {
this.contents = contents; this.contents = contents;
if (oldOwner != null && oldOwner != owner) { if (oldOwner != null && oldOwner != owner) {
EventQueue.invokeLater(() -> oldOwner.lostOwnership(Clipboard.this, oldContents)); DataFlavorUtil.getDesktopService().invokeOnEventThread(() ->
oldOwner.lostOwnership(Clipboard.this, oldContents));
} }
fireFlavorsChanged(); fireFlavorsChanged();
} }
@ -324,7 +325,7 @@ public class Clipboard {
return; return;
} }
flavorListeners.forEach(listener -> flavorListeners.forEach(listener ->
EventQueue.invokeLater(() -> DataFlavorUtil.getDesktopService().invokeOnEventThread(() ->
listener.flavorsChanged(new FlavorEvent(Clipboard.this)))); listener.flavorsChanged(new FlavorEvent(Clipboard.this))));
} }

View file

@ -25,7 +25,7 @@
package java.awt.datatransfer; package java.awt.datatransfer;
import sun.awt.datatransfer.DataTransferer; import sun.datatransfer.DataFlavorUtil;
import sun.reflect.misc.ReflectUtil; import sun.reflect.misc.ReflectUtil;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -44,7 +44,6 @@ import java.nio.ByteBuffer;
import java.nio.CharBuffer; import java.nio.CharBuffer;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.Objects; import java.util.Objects;
import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION; import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION;
@ -582,12 +581,12 @@ public class DataFlavor implements Externalizable, Cloneable {
} else { } else {
params += representationClass.getName(); params += representationClass.getName();
} }
if (DataTransferer.isFlavorCharsetTextType(this) && if (DataFlavorUtil.isFlavorCharsetTextType(this) &&
(isRepresentationClassInputStream() || (isRepresentationClassInputStream() ||
isRepresentationClassByteBuffer() || isRepresentationClassByteBuffer() ||
byte[].class.equals(representationClass))) byte[].class.equals(representationClass)))
{ {
params += ";charset=" + DataTransferer.getTextCharset(this); params += ";charset=" + DataFlavorUtil.getTextCharset(this);
} }
return params; return params;
} }
@ -609,13 +608,8 @@ public class DataFlavor implements Externalizable, Cloneable {
* @since 1.3 * @since 1.3
*/ */
public static final DataFlavor getTextPlainUnicodeFlavor() { public static final DataFlavor getTextPlainUnicodeFlavor() {
String encoding = null;
DataTransferer transferer = DataTransferer.getInstance();
if (transferer != null) {
encoding = transferer.getDefaultUnicodeEncoding();
}
return new DataFlavor( return new DataFlavor(
"text/plain;charset="+encoding "text/plain;charset=" + DataFlavorUtil.getDesktopService().getDefaultUnicodeEncoding()
+";class=java.io.InputStream", "Plain Text"); +";class=java.io.InputStream", "Plain Text");
} }
@ -741,12 +735,8 @@ public class DataFlavor implements Externalizable, Cloneable {
return null; return null;
} }
if (textFlavorComparator == null) {
textFlavorComparator = new TextFlavorComparator();
}
DataFlavor bestFlavor = Collections.max(Arrays.asList(availableFlavors), DataFlavor bestFlavor = Collections.max(Arrays.asList(availableFlavors),
textFlavorComparator); DataFlavorUtil.getTextFlavorComparator());
if (!bestFlavor.isFlavorTextType()) { if (!bestFlavor.isFlavorTextType()) {
return null; return null;
@ -755,46 +745,6 @@ public class DataFlavor implements Externalizable, Cloneable {
return bestFlavor; return bestFlavor;
} }
private static Comparator<DataFlavor> textFlavorComparator;
static class TextFlavorComparator
extends DataTransferer.DataFlavorComparator {
/**
* Compares two <code>DataFlavor</code> objects. Returns a negative
* integer, zero, or a positive integer as the first
* <code>DataFlavor</code> is worse than, equal to, or better than the
* second.
* <p>
* <code>DataFlavor</code>s are ordered according to the rules outlined
* for <code>selectBestTextFlavor</code>.
*
* @param flavor1 the first <code>DataFlavor</code> to be compared
* @param flavor2 the second <code>DataFlavor</code> to be compared
* @return a negative integer, zero, or a positive integer as the first
* argument is worse, equal to, or better than the second
* @throws ClassCastException if either of the arguments is not an
* instance of <code>DataFlavor</code>
* @throws NullPointerException if either of the arguments is
* <code>null</code>
*
* @see #selectBestTextFlavor
*/
public int compare(DataFlavor flavor1, DataFlavor flavor2) {
if (flavor1.isFlavorTextType()) {
if (flavor2.isFlavorTextType()) {
return super.compare(flavor1, flavor2);
} else {
return 1;
}
} else if (flavor2.isFlavorTextType()) {
return -1;
} else {
return 0;
}
}
}
/** /**
* Gets a Reader for a text flavor, decoded, if necessary, for the expected * Gets a Reader for a text flavor, decoded, if necessary, for the expected
* charset (encoding). The supported representation classes are * charset (encoding). The supported representation classes are
@ -1015,13 +965,13 @@ public class DataFlavor implements Externalizable, Cloneable {
} }
if ("text".equals(getPrimaryType())) { if ("text".equals(getPrimaryType())) {
if (DataTransferer.doesSubtypeSupportCharset(this) if (DataFlavorUtil.doesSubtypeSupportCharset(this)
&& representationClass != null && representationClass != null
&& !isStandardTextRepresentationClass()) { && !isStandardTextRepresentationClass()) {
String thisCharset = String thisCharset =
DataTransferer.canonicalName(this.getParameter("charset")); DataFlavorUtil.canonicalName(this.getParameter("charset"));
String thatCharset = String thatCharset =
DataTransferer.canonicalName(that.getParameter("charset")); DataFlavorUtil.canonicalName(that.getParameter("charset"));
if (!Objects.equals(thisCharset, thatCharset)) { if (!Objects.equals(thisCharset, thatCharset)) {
return false; return false;
} }
@ -1088,10 +1038,10 @@ public class DataFlavor implements Externalizable, Cloneable {
// subTypes is '*', regardless of the other subType. // subTypes is '*', regardless of the other subType.
if ("text".equals(primaryType)) { if ("text".equals(primaryType)) {
if (DataTransferer.doesSubtypeSupportCharset(this) if (DataFlavorUtil.doesSubtypeSupportCharset(this)
&& representationClass != null && representationClass != null
&& !isStandardTextRepresentationClass()) { && !isStandardTextRepresentationClass()) {
String charset = DataTransferer.canonicalName(getParameter("charset")); String charset = DataFlavorUtil.canonicalName(getParameter("charset"));
if (charset != null) { if (charset != null) {
total += charset.hashCode(); total += charset.hashCode();
} }
@ -1280,9 +1230,8 @@ public class DataFlavor implements Externalizable, Cloneable {
* Returns true if the representation class is <code>Remote</code>. * Returns true if the representation class is <code>Remote</code>.
* @return true if the representation class is <code>Remote</code> * @return true if the representation class is <code>Remote</code>
*/ */
public boolean isRepresentationClassRemote() { public boolean isRepresentationClassRemote() {
return DataTransferer.isRemote(representationClass); return DataFlavorUtil.RMI.isRemote(representationClass);
} }
/** /**
@ -1356,8 +1305,8 @@ public class DataFlavor implements Externalizable, Cloneable {
* @since 1.4 * @since 1.4
*/ */
public boolean isFlavorTextType() { public boolean isFlavorTextType() {
return (DataTransferer.isFlavorCharsetTextType(this) || return (DataFlavorUtil.isFlavorCharsetTextType(this) ||
DataTransferer.isFlavorNoncharsetTextType(this)); DataFlavorUtil.isFlavorNoncharsetTextType(this));
} }
/** /**

View file

@ -25,22 +25,15 @@
package java.awt.datatransfer; package java.awt.datatransfer;
import java.awt.Toolkit; import sun.datatransfer.DataFlavorUtil;
import sun.datatransfer.DesktopDatatransferService;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.URL; import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.lang.ref.SoftReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -48,12 +41,8 @@ import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Properties;
import java.util.Set; import java.util.Set;
import sun.awt.AppContext;
import sun.awt.datatransfer.DataTransferer;
/** /**
* The SystemFlavorMap is a configurable map between "natives" (Strings), which * The SystemFlavorMap is a configurable map between "natives" (Strings), which
* correspond to platform-specific data formats, and "flavors" (DataFlavors), * correspond to platform-specific data formats, and "flavors" (DataFlavors),
@ -73,13 +62,6 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
private static final Object FLAVOR_MAP_KEY = new Object(); private static final Object FLAVOR_MAP_KEY = new Object();
/**
* Copied from java.util.Properties.
*/
private static final String keyValueSeparators = "=: \t\r\n\f";
private static final String strictKeyValueSeparators = "=:";
private static final String whiteSpaceChars = " \t\r\n\f";
/** /**
* The list of valid, decoded text flavor representation classes, in order * The list of valid, decoded text flavor representation classes, in order
* from best to worst. * from best to worst.
@ -198,16 +180,11 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
/** /**
* Returns the default FlavorMap for this thread's ClassLoader. * Returns the default FlavorMap for this thread's ClassLoader.
*
* @return the default FlavorMap for this thread's ClassLoader * @return the default FlavorMap for this thread's ClassLoader
*/ */
public static FlavorMap getDefaultFlavorMap() { public static FlavorMap getDefaultFlavorMap() {
AppContext context = AppContext.getAppContext(); return DataFlavorUtil.getDesktopService().getFlavorMap(SystemFlavorMap::new);
FlavorMap fm = (FlavorMap) context.get(FLAVOR_MAP_KEY);
if (fm == null) {
fm = new SystemFlavorMap();
context.put(FLAVOR_MAP_KEY, fm);
}
return fm;
} }
private SystemFlavorMap() { private SystemFlavorMap() {
@ -223,7 +200,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
} }
isMapInitialized = true; isMapInitialized = true;
InputStream is = SystemFlavorMap.class.getResourceAsStream("/sun/awt/datatransfer/flavormap.properties"); InputStream is = SystemFlavorMap.class.getResourceAsStream("/sun/datatransfer/resources/flavormap.properties");
if (is == null) { if (is == null) {
throw new InternalError("Default flavor mapping not found"); throw new InternalError("Default flavor mapping not found");
} }
@ -238,22 +215,25 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
line = line.substring(0, line.length() - 1) + reader.readLine().trim(); line = line.substring(0, line.length() - 1) + reader.readLine().trim();
} }
int delimiterPosition = line.indexOf('='); int delimiterPosition = line.indexOf('=');
String key = line.substring(0, delimiterPosition).replace("\\ ", " "); String key = line.substring(0, delimiterPosition).replaceAll("\\ ", " ");
String[] values = line.substring(delimiterPosition + 1, line.length()).split(","); String[] values = line.substring(delimiterPosition + 1, line.length()).split(",");
for (String value : values) { for (String value : values) {
try { try {
value = loadConvert(value);
MimeType mime = new MimeType(value); MimeType mime = new MimeType(value);
if ("text".equals(mime.getPrimaryType())) { if ("text".equals(mime.getPrimaryType())) {
String charset = mime.getParameter("charset"); String charset = mime.getParameter("charset");
if (DataTransferer.doesSubtypeSupportCharset(mime.getSubType(), charset)) if (DataFlavorUtil.doesSubtypeSupportCharset(mime.getSubType(), charset))
{ {
// We need to store the charset and eoln // We need to store the charset and eoln
// parameters, if any, so that the // parameters, if any, so that the
// DataTransferer will have this information // DataTransferer will have this information
// for conversion into the native format. // for conversion into the native format.
DataTransferer transferer = DataTransferer.getInstance(); DesktopDatatransferService desktopService =
if (transferer != null) { DataFlavorUtil.getDesktopService();
transferer.registerTextFlavorProperties(key, charset, if (desktopService.isDesktopPresent()) {
desktopService.registerTextFlavorProperties(
key, charset,
mime.getParameter("eoln"), mime.getParameter("eoln"),
mime.getParameter("terminators")); mime.getParameter("terminators"));
} }
@ -305,6 +285,63 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
} }
} }
// Copied from java.util.Properties
private static String loadConvert(String theString) {
char aChar;
int len = theString.length();
StringBuilder outBuffer = new StringBuilder(len);
for (int x = 0; x < len; ) {
aChar = theString.charAt(x++);
if (aChar == '\\') {
aChar = theString.charAt(x++);
if (aChar == 'u') {
// Read the xxxx
int value = 0;
for (int i = 0; i < 4; i++) {
aChar = theString.charAt(x++);
switch (aChar) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
value = (value << 4) + aChar - '0';
break;
}
case 'a': case 'b': case 'c':
case 'd': case 'e': case 'f': {
value = (value << 4) + 10 + aChar - 'a';
break;
}
case 'A': case 'B': case 'C':
case 'D': case 'E': case 'F': {
value = (value << 4) + 10 + aChar - 'A';
break;
}
default: {
throw new IllegalArgumentException(
"Malformed \\uxxxx encoding.");
}
}
}
outBuffer.append((char)value);
} else {
if (aChar == 't') {
aChar = '\t';
} else if (aChar == 'r') {
aChar = '\r';
} else if (aChar == 'n') {
aChar = '\n';
} else if (aChar == 'f') {
aChar = '\f';
}
outBuffer.append(aChar);
}
} else {
outBuffer.append(aChar);
}
}
return outBuffer.toString();
}
/** /**
* Stores the listed object under the specified hash key in map. Unlike a * Stores the listed object under the specified hash key in map. Unlike a
* standard map, the listed object will not replace any object already at * standard map, the listed object will not replace any object already at
@ -332,10 +369,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(nat); LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(nat);
if (nat != null && !disabledMappingGenerationKeys.contains(nat)) { if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
DataTransferer transferer = DataTransferer.getInstance(); DesktopDatatransferService desktopService = DataFlavorUtil.getDesktopService();
if (transferer != null) { if (desktopService.isDesktopPresent()) {
LinkedHashSet<DataFlavor> platformFlavors = LinkedHashSet<DataFlavor> platformFlavors =
transferer.getPlatformMappingsForNative(nat); desktopService.getPlatformMappingsForNative(nat);
if (!platformFlavors.isEmpty()) { if (!platformFlavors.isEmpty()) {
if (flavors != null) { if (flavors != null) {
// Prepending the platform-specific mappings ensures // Prepending the platform-specific mappings ensures
@ -395,10 +432,10 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
LinkedHashSet<String> natives = getFlavorToNative().get(flav); LinkedHashSet<String> natives = getFlavorToNative().get(flav);
if (flav != null && !disabledMappingGenerationKeys.contains(flav)) { if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
DataTransferer transferer = DataTransferer.getInstance(); DesktopDatatransferService desktopService = DataFlavorUtil.getDesktopService();
if (transferer != null) { if (desktopService.isDesktopPresent()) {
LinkedHashSet<String> platformNatives = LinkedHashSet<String> platformNatives =
transferer.getPlatformMappingsForFlavor(flav); desktopService.getPlatformMappingsForFlavor(flav);
if (!platformNatives.isEmpty()) { if (!platformNatives.isEmpty()) {
if (natives != null) { if (natives != null) {
// Prepend the platform-specific mappings to ensure // Prepend the platform-specific mappings to ensure
@ -474,7 +511,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
// In this case we shouldn't synthesize a native for this flavor, // In this case we shouldn't synthesize a native for this flavor,
// since its mappings were explicitly specified. // since its mappings were explicitly specified.
retval = flavorToNativeLookup(flav, false); retval = flavorToNativeLookup(flav, false);
} else if (DataTransferer.isFlavorCharsetTextType(flav)) { } else if (DataFlavorUtil.isFlavorCharsetTextType(flav)) {
retval = new LinkedHashSet<>(0); retval = new LinkedHashSet<>(0);
// For text/* flavors, flavor-to-native mappings specified in // For text/* flavors, flavor-to-native mappings specified in
@ -502,7 +539,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
// addUnencodedNativeForFlavor(), so they have lower priority. // addUnencodedNativeForFlavor(), so they have lower priority.
retval.addAll(flavorToNativeLookup(flav, false)); retval.addAll(flavorToNativeLookup(flav, false));
} }
} else if (DataTransferer.isFlavorNoncharsetTextType(flav)) { } else if (DataFlavorUtil.isFlavorNoncharsetTextType(flav)) {
retval = getTextTypeToNative().get(flav.mimeType.getBaseType()); retval = getTextTypeToNative().get(flav.mimeType.getBaseType());
if (retval == null || retval.isEmpty()) { if (retval == null || retval.isEmpty()) {
@ -602,7 +639,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
// on load from flavormap.properties. // on load from flavormap.properties.
} }
if (DataTransferer.doesSubtypeSupportCharset(subType, null)) { if (DataFlavorUtil.doesSubtypeSupportCharset(subType, null)) {
if (TEXT_PLAIN_BASE_TYPE.equals(baseType)) if (TEXT_PLAIN_BASE_TYPE.equals(baseType))
{ {
returnValue.add(DataFlavor.stringFlavor); returnValue.add(DataFlavor.stringFlavor);
@ -624,7 +661,7 @@ public final class SystemFlavorMap implements FlavorMap, FlavorTable {
} }
} }
for (String charset : DataTransferer.standardEncodings()) { for (String charset : DataFlavorUtil.standardEncodings()) {
for (String encodedTextClass : ENCODED_TEXT_CLASSES) { for (String encodedTextClass : ENCODED_TEXT_CLASSES) {
final String mimeType = final String mimeType =

View file

@ -1811,7 +1811,7 @@ public final class TextLayout implements Cloneable {
* should be logical or visual counterparts. They are not * should be logical or visual counterparts. They are not
* checked for validity. * checked for validity.
*/ */
private final TextHitInfo getStrongHit(TextHitInfo hit1, TextHitInfo hit2) { private TextHitInfo getStrongHit(TextHitInfo hit1, TextHitInfo hit2) {
// right now we're using the following rule for strong hits: // right now we're using the following rule for strong hits:
// A hit on a character with a lower level // A hit on a character with a lower level

View file

@ -544,7 +544,7 @@ public class PropertyChangeSupport implements Serializable {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public final PropertyChangeListener extract(PropertyChangeListener listener) { public PropertyChangeListener extract(PropertyChangeListener listener) {
while (listener instanceof PropertyChangeListenerProxy) { while (listener instanceof PropertyChangeListenerProxy) {
listener = ((PropertyChangeListenerProxy) listener).getListener(); listener = ((PropertyChangeListenerProxy) listener).getListener();
} }

View file

@ -533,7 +533,7 @@ public class VetoableChangeSupport implements Serializable {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public final VetoableChangeListener extract(VetoableChangeListener listener) { public VetoableChangeListener extract(VetoableChangeListener listener) {
while (listener instanceof VetoableChangeListenerProxy) { while (listener instanceof VetoableChangeListenerProxy) {
listener = ((VetoableChangeListenerProxy) listener).getListener(); listener = ((VetoableChangeListenerProxy) listener).getListener();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,38 +27,35 @@ package javax.sound.midi;
import java.util.EventListener; import java.util.EventListener;
/** /**
* The <code>ControllerEventListener</code> interface should be implemented * The {@code ControllerEventListener} interface should be implemented by
* by classes whose instances need to be notified when a <code>Sequencer</code> * classes whose instances need to be notified when a {@link Sequencer} has
* has processed a requested type of MIDI control-change event. * processed a requested type of MIDI control-change event. To register a
* To register a <code>ControllerEventListener</code> object to receive such * {@code ControllerEventListener} object to receive such notifications, invoke
* notifications, invoke the * the
* {@link Sequencer#addControllerEventListener(ControllerEventListener, int[]) * {@link Sequencer#addControllerEventListener(ControllerEventListener, int[])
* addControllerEventListener} method of <code>Sequencer</code>, * addControllerEventListener} method of {@code Sequencer}, specifying the types
* specifying the types of MIDI controllers about which you are interested in * of MIDI controllers about which you are interested in getting control-change
* getting control-change notifications. * notifications.
*
* @see MidiChannel#controlChange(int, int)
* *
* @author Kara Kytle * @author Kara Kytle
* @see MidiChannel#controlChange(int, int)
*/ */
public interface ControllerEventListener extends EventListener { public interface ControllerEventListener extends EventListener {
/** /**
* Invoked when a <code>Sequencer</code> has encountered and processed * Invoked when a {@link Sequencer} has encountered and processed a
* a control-change event of interest to this listener. The event passed * control-change event of interest to this listener. The event passed in is
* in is a <code>ShortMessage</code> whose first data byte indicates * a {@code ShortMessage} whose first data byte indicates the controller
* the controller number and whose second data byte is the value to which * number and whose second data byte is the value to which the controller
* the controller was set. * was set.
* *
* @param event the control-change event that the sequencer encountered in * @param event the control-change event that the sequencer encountered in
* the sequence it is processing * the sequence it is processing
*
* @see Sequencer#addControllerEventListener(ControllerEventListener, int[]) * @see Sequencer#addControllerEventListener(ControllerEventListener, int[])
* @see MidiChannel#controlChange(int, int) * @see MidiChannel#controlChange(int, int)
* @see ShortMessage#getData1 * @see ShortMessage#getData1
* @see ShortMessage#getData2 * @see ShortMessage#getData2
*/ */
public void controlChange(ShortMessage event); void controlChange(ShortMessage event);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,49 +25,41 @@
package javax.sound.midi; package javax.sound.midi;
import java.net.URL;
/** /**
* An instrument is a sound-synthesis algorithm with certain parameter * An instrument is a sound-synthesis algorithm with certain parameter settings,
* settings, usually designed to emulate a specific real-world * usually designed to emulate a specific real-world musical instrument or to
* musical instrument or to achieve a specific sort of sound effect. * achieve a specific sort of sound effect. Instruments are typically stored in
* Instruments are typically stored in collections called soundbanks. * collections called soundbanks. Before the instrument can be used to play
* Before the instrument can be used to play notes, it must first be loaded * notes, it must first be loaded onto a synthesizer, and then it must be
* onto a synthesizer, and then it must be selected for use on * selected for use on one or more channels, via a program-change command. MIDI
* one or more channels, via a program-change command. MIDI notes * notes that are subsequently received on those channels will be played using
* that are subsequently received on those channels will be played using
* the sound of the selected instrument. * the sound of the selected instrument.
* *
* @author Kara Kytle
* @see Soundbank * @see Soundbank
* @see Soundbank#getInstruments * @see Soundbank#getInstruments
* @see Patch * @see Patch
* @see Synthesizer#loadInstrument(Instrument) * @see Synthesizer#loadInstrument(Instrument)
* @see MidiChannel#programChange(int, int) * @see MidiChannel#programChange(int, int)
* @author Kara Kytle
*/ */
public abstract class Instrument extends SoundbankResource { public abstract class Instrument extends SoundbankResource {
/** /**
* Instrument patch * Instrument patch.
*/ */
private final Patch patch; private final Patch patch;
/** /**
* Constructs a new MIDI instrument from the specified <code>Patch</code>. * Constructs a new MIDI instrument from the specified {@code Patch}. When a
* When a subsequent request is made to load the * subsequent request is made to load the instrument, the sound bank will
* instrument, the sound bank will search its contents for this instrument's <code>Patch</code>, * search its contents for this instrument's {@code Patch}, and the
* and the instrument will be loaded into the synthesizer at the * instrument will be loaded into the synthesizer at the bank and program
* bank and program location indicated by the <code>Patch</code> object. * location indicated by the {@code Patch} object.
*
* @param soundbank sound bank containing the instrument * @param soundbank sound bank containing the instrument
* @param patch the patch of this instrument * @param patch the patch of this instrument
* @param name the name of this instrument * @param name the name of this instrument
* @param dataClass the class used to represent the sample's data. * @param dataClass the class used to represent the sample's data
*
* @see Synthesizer#loadInstrument(Instrument) * @see Synthesizer#loadInstrument(Instrument)
*/ */
protected Instrument(Soundbank soundbank, Patch patch, String name, Class<?> dataClass) { protected Instrument(Soundbank soundbank, Patch patch, String name, Class<?> dataClass) {
@ -76,10 +68,10 @@ public abstract class Instrument extends SoundbankResource {
this.patch = patch; this.patch = patch;
} }
/** /**
* Obtains the <code>Patch</code> object that indicates the bank and program * Obtains the {@code Patch} object that indicates the bank and program
* numbers where this instrument is to be stored in the synthesizer. * numbers where this instrument is to be stored in the synthesizer.
*
* @return this instrument's patch * @return this instrument's patch
*/ */
public Patch getPatch() { public Patch getPatch() {

View file

@ -25,25 +25,25 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* An <code>InvalidMidiDataException</code> indicates that inappropriate MIDI * An {@code InvalidMidiDataException} indicates that inappropriate MIDI data
* data was encountered. This often means that the data is invalid in and of * was encountered. This often means that the data is invalid in and of itself,
* itself, from the perspective of the MIDI specification. An example would * from the perspective of the MIDI specification. An example would be an
* be an undefined status byte. However, the exception might simply * undefined status byte. However, the exception might simply mean that the data
* mean that the data was invalid in the context it was used, or that * was invalid in the context it was used, or that the object to which the data
* the object to which the data was given was unable to parse or use it. * was given was unable to parse or use it. For example, a file reader might not
* For example, a file reader might not be able to parse a Type 2 MIDI file, even * be able to parse a Type 2 MIDI file, even though that format is defined in
* though that format is defined in the MIDI specification. * the MIDI specification.
* *
* @author Kara Kytle * @author Kara Kytle
*/ */
public class InvalidMidiDataException extends Exception { public class InvalidMidiDataException extends Exception {
private static final long serialVersionUID = 2780771756789932067L; private static final long serialVersionUID = 2780771756789932067L;
/** /**
* Constructs an <code>InvalidMidiDataException</code> with * Constructs an {@code InvalidMidiDataException} with {@code null} for its
* <code>null</code> for its error detail message. * error detail message.
*/ */
public InvalidMidiDataException() { public InvalidMidiDataException() {
@ -51,8 +51,8 @@ public class InvalidMidiDataException extends Exception {
} }
/** /**
* Constructs an <code>InvalidMidiDataException</code> with the * Constructs an {@code InvalidMidiDataException} with the specified detail
* specified detail message. * message.
* *
* @param message the string to display as an error detail message * @param message the string to display as an error detail message
*/ */

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,24 +27,23 @@ package javax.sound.midi;
import java.util.EventListener; import java.util.EventListener;
/** /**
* The <code>MetaEventListener</code> interface should be implemented * The {@code MetaEventListener} interface should be implemented by classes
* by classes whose instances need to be notified when a <code>{@link Sequencer}</code> * whose instances need to be notified when a {@link Sequencer} has processed a
* has processed a <code>{@link MetaMessage}</code>. * {@link MetaMessage}. To register a {@code MetaEventListener} object to
* To register a <code>MetaEventListener</code> object to receive such * receive such notifications, pass it as the argument to the
* notifications, pass it as the argument to the * {@link Sequencer#addMetaEventListener(MetaEventListener)
* <code>{@link Sequencer#addMetaEventListener(MetaEventListener) addMetaEventListener}</code> * addMetaEventListener} method of {@code Sequencer}.
* method of <code>Sequencer</code>.
* *
* @author Kara Kytle * @author Kara Kytle
*/ */
public interface MetaEventListener extends EventListener { public interface MetaEventListener extends EventListener {
/** /**
* Invoked when a <code>{@link Sequencer}</code> has encountered and processed * Invoked when a {@link Sequencer} has encountered and processed a
* a <code>MetaMessage</code> in the <code>{@link Sequence}</code> it is processing. * {@code MetaMessage} in the {@code Sequence} it is processing.
*
* @param meta the meta-message that the sequencer encountered * @param meta the meta-message that the sequencer encountered
*/ */
public void meta(MetaMessage meta); void meta(MetaMessage meta);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,65 +25,54 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* A <code>MetaMessage</code> is a <code>{@link MidiMessage}</code> that is not meaningful to synthesizers, but * A {@code MetaMessage} is a {@link MidiMessage} that is not meaningful to
* that can be stored in a MIDI file and interpreted by a sequencer program. * synthesizers, but that can be stored in a MIDI file and interpreted by a
* (See the discussion in the <code>MidiMessage</code> * sequencer program. (See the discussion in the {@code MidiMessage} class
* class description.) The Standard MIDI Files specification defines * description.) The Standard MIDI Files specification defines various types of
* various types of meta-events, such as sequence number, lyric, cue point, * meta-events, such as sequence number, lyric, cue point, and set tempo. There
* and set tempo. There are also meta-events * are also meta-events for such information as lyrics, copyrights, tempo
* for such information as lyrics, copyrights, tempo indications, time and key * indications, time and key signatures, markers, etc. For more information, see
* signatures, markers, etc. For more information, see the Standard MIDI Files 1.0 * the Standard MIDI Files 1.0 specification, which is part of the Complete MIDI
* specification, which is part of the Complete MIDI 1.0 Detailed Specification * 1.0 Detailed Specification published by the MIDI Manufacturer's Association
* published by the MIDI Manufacturer's Association
* (<a href = http://www.midi.org>http://www.midi.org</a>). * (<a href = http://www.midi.org>http://www.midi.org</a>).
*
* <p> * <p>
* When data is being transported using MIDI wire protocol, * When data is being transported using MIDI wire protocol, a
* a <code>{@link ShortMessage}</code> with the status value <code>0xFF</code> represents * {@link ShortMessage} with the status value {@code 0xFF} represents a system
* a system reset message. In MIDI files, this same status value denotes a <code>MetaMessage</code>. * reset message. In MIDI files, this same status value denotes a
* The types of meta-message are distinguished from each other by the first byte * {@code MetaMessage}. The types of meta-message are distinguished from each
* that follows the status byte <code>0xFF</code>. The subsequent bytes are data * other by the first byte that follows the status byte {@code 0xFF}. The
* bytes. As with system exclusive messages, there are an arbitrary number of * subsequent bytes are data bytes. As with system exclusive messages, there are
* data bytes, depending on the type of <code>MetaMessage</code>. * an arbitrary number of data bytes, depending on the type of
* * {@code MetaMessage}.
* @see MetaEventListener
* *
* @author David Rivas * @author David Rivas
* @author Kara Kytle * @author Kara Kytle
* @see MetaEventListener
*/ */
public class MetaMessage extends MidiMessage { public class MetaMessage extends MidiMessage {
// Status byte defines
/** /**
* Status byte for <code>MetaMessage</code> (0xFF, or 255), which is used * Status byte for {@code MetaMessage} (0xFF, or 255), which is used in MIDI
* in MIDI files. It has the same value as SYSTEM_RESET, which * files. It has the same value as SYSTEM_RESET, which is used in the
* is used in the real-time "MIDI wire" protocol. * real-time "MIDI wire" protocol.
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int META = 0xFF; // 255 public static final int META = 0xFF; // 255
// Instance variables
/** /**
* The length of the actual message in the data array. * The length of the actual message in the data array. This is used to
* This is used to determine how many bytes of the data array * determine how many bytes of the data array is the message, and how many
* is the message, and how many are the status byte, the * are the status byte, the type byte, and the variable-length-int
* type byte, and the variable-length-int describing the * describing the length of the message.
* length of the message.
*/ */
private int dataLength = 0; private int dataLength = 0;
/** /**
* Constructs a new <code>MetaMessage</code>. The contents of * Constructs a new {@code MetaMessage}. The contents of the message are not
* the message are not set here; use * set here; use {@link #setMessage(int, byte[], int) setMessage} to set
* {@link #setMessage(int, byte[], int) setMessage} * them subsequently.
* to set them subsequently.
*/ */
public MetaMessage() { public MetaMessage() {
// Default meta message data: just the META status byte value // Default meta message data: just the META status byte value
@ -91,17 +80,17 @@ public class MetaMessage extends MidiMessage {
} }
/** /**
* Constructs a new {@code MetaMessage} and sets the message parameters. * Constructs a new {@code MetaMessage} and sets the message parameters. The
* The contents of the message can be changed by using * contents of the message can be changed by using the {@code setMessage}
* the {@code setMessage} method. * method.
* *
* @param type meta-message type (must be less than 128) * @param type meta-message type (must be less than 128)
* @param data the data bytes in the MIDI message * @param data the data bytes in the MIDI message
* @param length an amount of bytes in the {@code data} byte array; * @param length an amount of bytes in the {@code data} byte array; it
* it should be non-negative and less than or equal to * should be non-negative and less than or equal to
* {@code data.length} * {@code data.length}
* @throws InvalidMidiDataException if the parameter values do not specify * @throws InvalidMidiDataException if the parameter values do not specify a
* a valid MIDI meta message * valid MIDI meta message
* @see #setMessage(int, byte[], int) * @see #setMessage(int, byte[], int)
* @see #getType() * @see #getType()
* @see #getData() * @see #getData()
@ -113,12 +102,11 @@ public class MetaMessage extends MidiMessage {
setMessage(type, data, length); // can throw InvalidMidiDataException setMessage(type, data, length); // can throw InvalidMidiDataException
} }
/** /**
* Constructs a new <code>MetaMessage</code>. * Constructs a new {@code MetaMessage}.
* @param data an array of bytes containing the complete message. *
* The message data may be changed using the <code>setMessage</code> * @param data an array of bytes containing the complete message. The
* method. * message data may be changed using the {@code setMessage} method.
* @see #setMessage * @see #setMessage
*/ */
protected MetaMessage(byte[] data) { protected MetaMessage(byte[] data) {
@ -133,24 +121,24 @@ public class MetaMessage extends MidiMessage {
} }
} }
/** /**
* Sets the message parameters for a <code>MetaMessage</code>. * Sets the message parameters for a {@code MetaMessage}. Since only one
* Since only one status byte value, <code>0xFF</code>, is allowed for meta-messages, * status byte value, {@code 0xFF}, is allowed for meta-messages, it does
* it does not need to be specified here. Calls to <code>{@link MidiMessage#getStatus getStatus}</code> return * not need to be specified here. Calls to
* <code>0xFF</code> for all meta-messages. * {@link MidiMessage#getStatus getStatus} return {@code 0xFF} for all
* meta-messages.
* <p> * <p>
* The <code>type</code> argument should be a valid value for the byte that * The {@code type} argument should be a valid value for the byte that
* follows the status byte in the <code>MetaMessage</code>. The <code>data</code> argument * follows the status byte in the {@code MetaMessage}. The {@code data}
* should contain all the subsequent bytes of the <code>MetaMessage</code>. In other words, * argument should contain all the subsequent bytes of the
* the byte that specifies the type of <code>MetaMessage</code> is not considered a data byte. * {@code MetaMessage}. In other words, the byte that specifies the type of
* {@code MetaMessage} is not considered a data byte.
* *
* @param type meta-message type (must be less than 128) * @param type meta-message type (must be less than 128)
* @param data the data bytes in the MIDI message * @param data the data bytes in the MIDI message
* @param length the number of bytes in the <code>data</code> * @param length the number of bytes in the {@code data} byte array
* byte array * @throws InvalidMidiDataException if the parameter values do not specify a
* @throws InvalidMidiDataException if the * valid MIDI meta message
* parameter values do not specify a valid MIDI meta message
*/ */
public void setMessage(int type, byte[] data, int length) throws InvalidMidiDataException { public void setMessage(int type, byte[] data, int length) throws InvalidMidiDataException {
@ -172,10 +160,10 @@ public class MetaMessage extends MidiMessage {
} }
} }
/** /**
* Obtains the type of the <code>MetaMessage</code>. * Obtains the type of the {@code MetaMessage}.
* @return an integer representing the <code>MetaMessage</code> type *
* @return an integer representing the {@code MetaMessage} type
*/ */
public int getType() { public int getType() {
if (length>=2) { if (length>=2) {
@ -184,16 +172,15 @@ public class MetaMessage extends MidiMessage {
return 0; return 0;
} }
/** /**
* Obtains a copy of the data for the meta message. The returned * Obtains a copy of the data for the meta message. The returned array of
* array of bytes does not include the status byte or the message * bytes does not include the status byte or the message length data. The
* length data. The length of the data for the meta message is * length of the data for the meta message is the length of the array. Note
* the length of the array. Note that the length of the entire * that the length of the entire message includes the status byte and the
* message includes the status byte and the meta message type * meta message type byte, and therefore may be longer than the returned
* byte, and therefore may be longer than the returned array. * array.
* @return array containing the meta message data. *
* @return array containing the meta message data
* @see MidiMessage#getLength * @see MidiMessage#getLength
*/ */
public byte[] getData() { public byte[] getData() {
@ -202,10 +189,10 @@ public class MetaMessage extends MidiMessage {
return returnedArray; return returnedArray;
} }
/** /**
* Creates a new object of the same class and with the same contents * Creates a new object of the same class and with the same contents as this
* as this object. * object.
*
* @return a clone of this instance * @return a clone of this instance
*/ */
public Object clone() { public Object clone() {
@ -240,5 +227,4 @@ public class MetaMessage extends MidiMessage {
} }
data[off] = (byte) (value & mask); data[off] = (byte) (value & mask);
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,513 +25,450 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* A <code>MidiChannel</code> object represents a single MIDI channel. * A {@code MidiChannel} object represents a single MIDI channel. Generally,
* Generally, each <code>MidiChannel</code> method processes a like-named MIDI * each {@code MidiChannel} method processes a like-named MIDI "channel voice"
* "channel voice" or "channel mode" message as defined by the MIDI specification. However, * or "channel mode" message as defined by the MIDI specification. However,
* <code>MidiChannel</code> adds some "get" methods that retrieve the value * {@code MidiChannel} adds some "get" methods that retrieve the value most
* most recently set by one of the standard MIDI channel messages. Similarly, * recently set by one of the standard MIDI channel messages. Similarly, methods
* methods for per-channel solo and mute have been added. * for per-channel solo and mute have been added.
* <p> * <p>
* A <code>{@link Synthesizer}</code> object has a collection * A {@link Synthesizer} object has a collection of {@code MidiChannels},
* of <code>MidiChannels</code>, usually one for each of the 16 channels * usually one for each of the 16 channels prescribed by the MIDI 1.0
* prescribed by the MIDI 1.0 specification. The <code>Synthesizer</code> * specification. The {@code Synthesizer} generates sound when its
* generates sound when its <code>MidiChannels</code> receive * {@code MidiChannels} receive {@code noteOn} messages.
* <code>noteOn</code> messages.
* <p> * <p>
* See the MIDI 1.0 Specification for more information about the prescribed * See the MIDI 1.0 Specification for more information about the prescribed
* behavior of the MIDI channel messages, which are not exhaustively * behavior of the MIDI channel messages, which are not exhaustively documented
* documented here. The specification is titled <code>MIDI Reference: * here. The specification is titled
* The Complete MIDI 1.0 Detailed Specification</code>, and is published by * {@code MIDI Reference: The Complete MIDI 1.0 Detailed Specification}, and is
* the MIDI Manufacturer's Association (<a href = http://www.midi.org> * published by the MIDI Manufacturer's Association
* http://www.midi.org</a>). * (<a href = http://www.midi.org>http://www.midi.org</a>).
* <p> * <p>
* MIDI was originally a protocol for reporting the gestures of a keyboard * MIDI was originally a protocol for reporting the gestures of a keyboard
* musician. This genesis is visible in the <code>MidiChannel</code> API, which * musician. This genesis is visible in the {@code MidiChannel} API, which
* preserves such MIDI concepts as key number, key velocity, and key pressure. * preserves such MIDI concepts as key number, key velocity, and key pressure.
* It should be understood that the MIDI data does not necessarily originate * It should be understood that the MIDI data does not necessarily originate
* with a keyboard player (the source could be a different kind of musician, or * with a keyboard player (the source could be a different kind of musician, or
* software). Some devices might generate constant values for velocity * software). Some devices might generate constant values for velocity and
* and pressure, regardless of how the note was performed. * pressure, regardless of how the note was performed. Also, the MIDI
* Also, the MIDI specification often leaves it up to the * specification often leaves it up to the synthesizer to use the data in the
* synthesizer to use the data in the way the implementor sees fit. For * way the implementor sees fit. For example, velocity data need not always be
* example, velocity data need not always be mapped to volume and/or brightness. * mapped to volume and/or brightness.
*
* @see Synthesizer#getChannels
* *
* @author David Rivas * @author David Rivas
* @author Kara Kytle * @author Kara Kytle
* @see Synthesizer#getChannels
*/ */
public interface MidiChannel { public interface MidiChannel {
/** /**
* Starts the specified note sounding. The key-down velocity * Starts the specified note sounding. The key-down velocity usually
* usually controls the note's volume and/or brightness. * controls the note's volume and/or brightness. If {@code velocity} is
* If <code>velocity</code> is zero, this method instead acts like * zero, this method instead acts like {@link #noteOff(int)}, terminating
* {@link #noteOff(int)}, terminating the note. * the note.
* *
* @param noteNumber the MIDI note number, from 0 to 127 (60 = Middle C) * @param noteNumber the MIDI note number, from 0 to 127 (60 = Middle C)
* @param velocity the speed with which the key was depressed * @param velocity the speed with which the key was depressed
*
* @see #noteOff(int, int) * @see #noteOff(int, int)
*/ */
public void noteOn(int noteNumber, int velocity); void noteOn(int noteNumber, int velocity);
/** /**
* Turns the specified note off. The key-up velocity, if not ignored, can * Turns the specified note off. The key-up velocity, if not ignored, can be
* be used to affect how quickly the note decays. * used to affect how quickly the note decays. In any case, the note might
* In any case, the note might not die away instantaneously; its decay * not die away instantaneously; its decay rate is determined by the
* rate is determined by the internals of the <code>Instrument</code>. * internals of the {@code Instrument}. If the Hold Pedal (a controller; see
* If the Hold Pedal (a controller; see * {@link #controlChange(int, int) controlChange}) is down, the effect of
* {@link #controlChange(int, int) controlChange}) * this method is deferred until the pedal is released.
* is down, the effect of this method is deferred until the pedal is
* released.
*
* *
* @param noteNumber the MIDI note number, from 0 to 127 (60 = Middle C) * @param noteNumber the MIDI note number, from 0 to 127 (60 = Middle C)
* @param velocity the speed with which the key was released * @param velocity the speed with which the key was released
*
* @see #noteOff(int) * @see #noteOff(int)
* @see #noteOn * @see #noteOn
* @see #allNotesOff * @see #allNotesOff
* @see #allSoundOff * @see #allSoundOff
*/ */
public void noteOff(int noteNumber, int velocity); void noteOff(int noteNumber, int velocity);
/** /**
* Turns the specified note off. * Turns the specified note off.
* *
* @param noteNumber the MIDI note number, from 0 to 127 (60 = Middle C) * @param noteNumber the MIDI note number, from 0 to 127 (60 = Middle C)
*
* @see #noteOff(int, int) * @see #noteOff(int, int)
*/ */
public void noteOff(int noteNumber); void noteOff(int noteNumber);
/** /**
* Reacts to a change in the specified note's key pressure. * Reacts to a change in the specified note's key pressure. Polyphonic key
* Polyphonic key pressure * pressure allows a keyboard player to press multiple keys simultaneously,
* allows a keyboard player to press multiple keys simultaneously, each * each with a different amount of pressure. The pressure, if not ignored,
* with a different amount of pressure. The pressure, if not ignored, * is typically used to vary such features as the volume, brightness, or
* is typically used to vary such features as the volume, brightness, * vibrato of the note.
* or vibrato of the note. * <p>
* * It is possible that the underlying synthesizer does not support this MIDI
* It is possible that the underlying synthesizer * message. In order to verify that {@code setPolyPressure} was successful,
* does not support this MIDI message. In order * use {@code getPolyPressure}.
* to verify that <code>setPolyPressure</code>
* was successful, use <code>getPolyPressure</code>.
* *
* @param noteNumber the MIDI note number, from 0 to 127 (60 = Middle C) * @param noteNumber the MIDI note number, from 0 to 127 (60 = Middle C)
* @param pressure value for the specified key, from 0 to 127 (127 = * @param pressure value for the specified key, from 0 to 127
* maximum pressure) * (127 = maximum pressure)
*
* @see #getPolyPressure(int) * @see #getPolyPressure(int)
*/ */
public void setPolyPressure(int noteNumber, int pressure); void setPolyPressure(int noteNumber, int pressure);
/** /**
* Obtains the pressure with which the specified key is being depressed. * Obtains the pressure with which the specified key is being depressed.
* <p>
* If the device does not support setting poly pressure, this method always
* returns 0. Calling {@code setPolyPressure} will have no effect then.
* *
* @param noteNumber the MIDI note number, from 0 to 127 (60 = Middle C) * @param noteNumber the MIDI note number, from 0 to 127 (60 = Middle C)
*
* If the device does not support setting poly pressure,
* this method always returns 0. Calling
* <code>setPolyPressure</code> will have no effect then.
*
* @return the amount of pressure for that note, from 0 to 127 * @return the amount of pressure for that note, from 0 to 127
* (127 = maximum pressure) * (127 = maximum pressure)
*
* @see #setPolyPressure(int, int) * @see #setPolyPressure(int, int)
*/ */
public int getPolyPressure(int noteNumber); int getPolyPressure(int noteNumber);
/** /**
* Reacts to a change in the keyboard pressure. Channel * Reacts to a change in the keyboard pressure. Channel pressure indicates
* pressure indicates how hard the keyboard player is depressing * how hard the keyboard player is depressing the entire keyboard. This can
* the entire keyboard. This can be the maximum or * be the maximum or average of the per-key pressure-sensor values, as set
* average of the per-key pressure-sensor values, as set by * by {@code setPolyPressure}. More commonly, it is a measurement of a
* <code>setPolyPressure</code>. More commonly, it is a measurement of * single sensor on a device that doesn't implement polyphonic key pressure.
* a single sensor on a device that doesn't implement polyphonic key * Pressure can be used to control various aspects of the sound, as
* pressure. Pressure can be used to control various aspects of the sound, * described under {@link #setPolyPressure(int, int) setPolyPressure}.
* as described under {@link #setPolyPressure(int, int) setPolyPressure}. * <p>
* * It is possible that the underlying synthesizer does not support this MIDI
* It is possible that the underlying synthesizer * message. In order to verify that {@code setChannelPressure} was
* does not support this MIDI message. In order * successful, use {@code getChannelPressure}.
* to verify that <code>setChannelPressure</code>
* was successful, use <code>getChannelPressure</code>.
* *
* @param pressure the pressure with which the keyboard is being depressed, * @param pressure the pressure with which the keyboard is being depressed,
* from 0 to 127 (127 = maximum pressure) * from 0 to 127 (127 = maximum pressure)
* @see #setPolyPressure(int, int) * @see #setPolyPressure(int, int)
* @see #getChannelPressure * @see #getChannelPressure
*/ */
public void setChannelPressure(int pressure); void setChannelPressure(int pressure);
/** /**
* Obtains the channel's keyboard pressure. * Obtains the channel's keyboard pressure.
* If the device does not support setting channel pressure, * <p>
* this method always returns 0. Calling * If the device does not support setting channel pressure, this method
* <code>setChannelPressure</code> will have no effect then. * always returns 0. Calling {@code setChannelPressure} will have no effect
* * then.
* @return the amount of pressure for that note,
* from 0 to 127 (127 = maximum pressure)
* *
* @return the amount of pressure for that note, from 0 to 127
* (127 = maximum pressure)
* @see #setChannelPressure(int) * @see #setChannelPressure(int)
*/ */
public int getChannelPressure(); int getChannelPressure();
/** /**
* Reacts to a change in the specified controller's value. A controller * Reacts to a change in the specified controller's value. A controller is
* is some control other than a keyboard key, such as a * some control other than a keyboard key, such as a switch, slider, pedal,
* switch, slider, pedal, wheel, or breath-pressure sensor. * wheel, or breath-pressure sensor. The MIDI 1.0 Specification provides
* The MIDI 1.0 Specification provides standard numbers for typical * standard numbers for typical controllers on MIDI devices, and describes
* controllers on MIDI devices, and describes the intended effect * the intended effect for some of the controllers. The way in which an
* for some of the controllers. * {@code Instrument} reacts to a controller change may be specific to the
* The way in which an * {@code Instrument}.
* <code>Instrument</code> reacts to a controller change may be
* specific to the <code>Instrument</code>.
* <p> * <p>
* The MIDI 1.0 Specification defines both 7-bit controllers * The MIDI 1.0 Specification defines both 7-bit controllers and 14-bit
* and 14-bit controllers. Continuous controllers, such * controllers. Continuous controllers, such as wheels and sliders,
* as wheels and sliders, typically have 14 bits (two MIDI bytes), * typically have 14 bits (two MIDI bytes), while discrete controllers, such
* while discrete controllers, such as switches, typically have 7 bits * as switches, typically have 7 bits (one MIDI byte). Refer to the
* (one MIDI byte). Refer to the specification to see the * specification to see the expected resolution for each type of control.
* expected resolution for each type of control.
* <p> * <p>
* Controllers 64 through 95 (0x40 - 0x5F) allow 7-bit precision. * Controllers 64 through 95 (0x40 - 0x5F) allow 7-bit precision. The value
* The value of a 7-bit controller is set completely by the * of a 7-bit controller is set completely by the {@code value} argument. An
* <code>value</code> argument. An additional set of controllers * additional set of controllers provide 14-bit precision by using two
* provide 14-bit precision by using two controller numbers, one * controller numbers, one for the most significant 7 bits and another for
* for the most significant 7 bits and another for the least significant * the least significant 7 bits. Controller numbers 0 through 31
* 7 bits. Controller numbers 0 through 31 (0x00 - 0x1F) control the * (0x00 - 0x1F) control the most significant 7 bits of 14-bit controllers;
* most significant 7 bits of 14-bit controllers; controller numbers * controller numbers 32 through 63 (0x20 - 0x3F) control the least
* 32 through 63 (0x20 - 0x3F) control the least significant 7 bits of * significant 7 bits of these controllers. For example, controller number 7
* these controllers. For example, controller number 7 (0x07) controls * (0x07) controls the upper 7 bits of the channel volume controller, and
* the upper 7 bits of the channel volume controller, and controller * controller number 39 (0x27) controls the lower 7 bits. The value of a
* number 39 (0x27) controls the lower 7 bits. * 14-bit controller is determined by the interaction of the two halves.
* The value of a 14-bit controller is determined * When the most significant 7 bits of a controller are set (using
* by the interaction of the two halves. When the most significant 7 bits * controller numbers 0 through 31), the lower 7 bits are automatically set
* of a controller are set (using controller numbers 0 through 31), the * to 0. The corresponding controller number for the lower 7 bits may then
* lower 7 bits are automatically set to 0. The corresponding controller * be used to further modulate the controller value.
* number for the lower 7 bits may then be used to further modulate the * <p>
* controller value. * It is possible that the underlying synthesizer does not support a
* * specific controller message. In order to verify that a call to
* It is possible that the underlying synthesizer * {@code controlChange} was successful, use {@code getController}.
* does not support a specific controller message. In order
* to verify that a call to <code>controlChange</code>
* was successful, use <code>getController</code>.
*
* @param controller the controller number (0 to 127; see the MIDI
* 1.0 Specification for the interpretation)
* @param value the value to which the specified controller is changed (0 to 127)
* *
* @param controller the controller number (0 to 127; see the MIDI 1.0
* Specification for the interpretation)
* @param value the value to which the specified controller is changed
* (0 to 127)
* @see #getController(int) * @see #getController(int)
*/ */
public void controlChange(int controller, int value); void controlChange(int controller, int value);
/** /**
* Obtains the current value of the specified controller. The return * Obtains the current value of the specified controller. The return value
* value is represented with 7 bits. For 14-bit controllers, the MSB and * is represented with 7 bits. For 14-bit controllers, the MSB and LSB
* LSB controller value needs to be obtained separately. For example, * controller value needs to be obtained separately. For example, the 14-bit
* the 14-bit value of the volume controller can be calculated by * value of the volume controller can be calculated by multiplying the value
* multiplying the value of controller 7 (0x07, channel volume MSB) * of controller 7 (0x07, channel volume MSB) with 128 and adding the value
* with 128 and adding the * of controller 39 (0x27, channel volume LSB).
* value of controller 39 (0x27, channel volume LSB). * <p>
* * If the device does not support setting a specific controller, this method
* If the device does not support setting a specific controller, * returns 0 for that controller. Calling {@code controlChange} will have no
* this method returns 0 for that controller. * effect then.
* Calling <code>controlChange</code> will have no effect then.
* *
* @param controller the number of the controller whose value is desired. * @param controller the number of the controller whose value is desired.
* The allowed range is 0-127; see the MIDI * The allowed range is 0-127; see the MIDI 1.0 Specification for
* 1.0 Specification for the interpretation. * the interpretation.
*
* @return the current value of the specified controller (0 to 127) * @return the current value of the specified controller (0 to 127)
*
* @see #controlChange(int, int) * @see #controlChange(int, int)
*/ */
public int getController(int controller); int getController(int controller);
/** /**
* Changes a program (patch). This selects a specific * Changes a program (patch). This selects a specific instrument from the
* instrument from the currently selected bank of instruments. * currently selected bank of instruments.
* <p> * <p>
* The MIDI specification does not * The MIDI specification does not dictate whether notes that are already
* dictate whether notes that are already sounding should switch * sounding should switch to the new instrument (timbre) or continue with
* to the new instrument (timbre) or continue with their original timbre * their original timbre until terminated by a note-off.
* until terminated by a note-off.
* <p> * <p>
* The program number is zero-based (expressed from 0 to 127). * The program number is zero-based (expressed from 0 to 127). Note that
* Note that MIDI hardware displays and literature about MIDI * MIDI hardware displays and literature about MIDI typically use the range
* typically use the range 1 to 128 instead. * 1 to 128 instead.
* * <p>
* It is possible that the underlying synthesizer * It is possible that the underlying synthesizer does not support a
* does not support a specific program. In order * specific program. In order to verify that a call to {@code programChange}
* to verify that a call to <code>programChange</code> * was successful, use {@code getProgram}.
* was successful, use <code>getProgram</code>.
* *
* @param program the program number to switch to (0 to 127) * @param program the program number to switch to (0 to 127)
*
* @see #programChange(int, int) * @see #programChange(int, int)
* @see #getProgram() * @see #getProgram()
*/ */
public void programChange(int program); void programChange(int program);
/** /**
* Changes the program using bank and program (patch) numbers. * Changes the program using bank and program (patch) numbers.
* * <p>
* It is possible that the underlying synthesizer * It is possible that the underlying synthesizer does not support a
* does not support a specific bank, or program. In order * specific bank, or program. In order to verify that a call to
* to verify that a call to <code>programChange</code> * {@code programChange} was successful, use {@code getProgram} and
* was successful, use <code>getProgram</code> and * {@code getController}. Since banks are changed by way of control changes,
* <code>getController</code>. * you can verify the current bank with the following statement:
* Since banks are changed by way of control changes,
* you can verify the current bank with the following
* statement:
* <pre> * <pre>
* int bank = (getController(0) * 128) * int bank = (getController(0) * 128) + getController(32);
* + getController(32);
* </pre> * </pre>
* *
* @param bank the bank number to switch to (0 to 16383) * @param bank the bank number to switch to (0 to 16383)
* @param program the program (patch) to use in the specified bank (0 to 127) * @param program the program (patch) to use in the specified bank
* (0 to 127)
* @see #programChange(int) * @see #programChange(int)
* @see #getProgram() * @see #getProgram()
*/ */
public void programChange(int bank, int program); void programChange(int bank, int program);
/** /**
* Obtains the current program number for this channel. * Obtains the current program number for this channel.
*
* @return the program number of the currently selected patch * @return the program number of the currently selected patch
* @see Patch#getProgram * @see Patch#getProgram
* @see Synthesizer#loadInstrument * @see Synthesizer#loadInstrument
* @see #programChange(int) * @see #programChange(int)
*/ */
public int getProgram(); int getProgram();
/** /**
* Changes the pitch offset for all notes on this channel. * Changes the pitch offset for all notes on this channel. This affects all
* This affects all currently sounding notes as well as subsequent ones. * currently sounding notes as well as subsequent ones. (For pitch bend to
* (For pitch bend to cease, the value needs to be reset to the * cease, the value needs to be reset to the center position.)
* center position.) * <p>
* <p> The MIDI specification * The MIDI specification stipulates that pitch bend be a 14-bit value,
* stipulates that pitch bend be a 14-bit value, where zero * where zero is maximum downward bend, 16383 is maximum upward bend, and
* is maximum downward bend, 16383 is maximum upward bend, and * 8192 is the center (no pitch bend). The actual amount of pitch change is
* 8192 is the center (no pitch bend). The actual * not specified; it can be changed by a pitch-bend sensitivity setting.
* amount of pitch change is not specified; it can be changed by * However, the General MIDI specification says that the default range
* a pitch-bend sensitivity setting. However, the General MIDI * should be two semitones up and down from center.
* specification says that the default range should be two semitones * <p>
* up and down from center. * It is possible that the underlying synthesizer does not support this MIDI
* * message. In order to verify that {@code setPitchBend} was successful, use
* It is possible that the underlying synthesizer * {@code getPitchBend}.
* does not support this MIDI message. In order
* to verify that <code>setPitchBend</code>
* was successful, use <code>getPitchBend</code>.
* *
* @param bend the amount of pitch change, as a nonnegative 14-bit value * @param bend the amount of pitch change, as a nonnegative 14-bit value
* (8192 = no bend) * (8192 = no bend)
*
* @see #getPitchBend * @see #getPitchBend
*/ */
public void setPitchBend(int bend); void setPitchBend(int bend);
/** /**
* Obtains the upward or downward pitch offset for this channel. * Obtains the upward or downward pitch offset for this channel. If the
* If the device does not support setting pitch bend, * device does not support setting pitch bend, this method always returns
* this method always returns 8192. Calling * 8192. Calling {@code setPitchBend} will have no effect then.
* <code>setPitchBend</code> will have no effect then.
* *
* @return bend amount, as a nonnegative 14-bit value (8192 = no bend) * @return bend amount, as a nonnegative 14-bit value (8192 = no bend)
*
* @see #setPitchBend(int) * @see #setPitchBend(int)
*/ */
public int getPitchBend(); int getPitchBend();
/** /**
* Resets all the implemented controllers to their default values. * Resets all the implemented controllers to their default values.
* *
* @see #controlChange(int, int) * @see #controlChange(int, int)
*/ */
public void resetAllControllers(); void resetAllControllers();
/** /**
* Turns off all notes that are currently sounding on this channel. * Turns off all notes that are currently sounding on this channel. The
* The notes might not die away instantaneously; their decay * notes might not die away instantaneously; their decay rate is determined
* rate is determined by the internals of the <code>Instrument</code>. * by the internals of the {@code Instrument}. If the Hold Pedal controller
* If the Hold Pedal controller (see * (see {@link #controlChange(int, int) controlChange}) is down, the effect
* {@link #controlChange(int, int) controlChange}) * of this method is deferred until the pedal is released.
* is down, the effect of this method is deferred until the pedal is
* released.
* *
* @see #allSoundOff * @see #allSoundOff
* @see #noteOff(int) * @see #noteOff(int)
*/ */
public void allNotesOff(); void allNotesOff();
/** /**
* Immediately turns off all sounding notes on this channel, ignoring the * Immediately turns off all sounding notes on this channel, ignoring the
* state of the Hold Pedal and the internal decay rate of the current * state of the Hold Pedal and the internal decay rate of the current
* <code>Instrument</code>. * {@code Instrument}.
* *
* @see #allNotesOff * @see #allNotesOff
*/ */
public void allSoundOff(); void allSoundOff();
/** /**
* Turns local control on or off. The default is for local control * Turns local control on or off. The default is for local control to be on.
* to be on. The "on" setting means that if a device is capable * The "on" setting means that if a device is capable of both synthesizing
* of both synthesizing sound and transmitting MIDI messages, * sound and transmitting MIDI messages, it will synthesize sound in
* it will synthesize sound in response to the note-on and * response to the note-on and note-off messages that it itself transmits.
* note-off messages that it itself transmits. It will also respond * It will also respond to messages received from other transmitting
* to messages received from other transmitting devices. * devices. The "off" setting means that the synthesizer will ignore its own
* The "off" setting means that the synthesizer will ignore its * transmitted MIDI messages, but not those received from other devices.
* own transmitted MIDI messages, but not those received from other devices.
*
* It is possible that the underlying synthesizer
* does not support local control. In order
* to verify that a call to <code>localControl</code>
* was successful, check the return value.
*
* @param on <code>true</code> to turn local control on, <code>false</code>
* to turn local control off
* @return the new local-control value, or false
* if local control is not supported
*
*/
public boolean localControl(boolean on);
/**
* Turns mono mode on or off. In mono mode, the channel synthesizes
* only one note at a time. In poly mode (identical to mono mode off),
* the channel can synthesize multiple notes simultaneously.
* The default is mono off (poly mode on).
* <p> * <p>
* "Mono" is short for the word "monophonic," which in this context * It is possible that the underlying synthesizer does not support local
* is opposed to the word "polyphonic" and refers to a single synthesizer * control. In order to verify that a call to {@code localControl} was
* voice per MIDI channel. It * successful, check the return value.
* has nothing to do with how many audio channels there might be
* (as in "monophonic" versus "stereophonic" recordings).
* *
* It is possible that the underlying synthesizer * @param on {@code true} to turn local control on, {@code false} to turn
* does not support mono mode. In order * local control off
* to verify that a call to <code>setMono</code> * @return the new local-control value, or false if local control is not
* was successful, use <code>getMono</code>. * supported
* */
* @param on <code>true</code> to turn mono mode on, <code>false</code> to boolean localControl(boolean on);
* turn it off (which means turning poly mode on).
/**
* Turns mono mode on or off. In mono mode, the channel synthesizes only one
* note at a time. In poly mode (identical to mono mode off), the channel
* can synthesize multiple notes simultaneously. The default is mono off
* (poly mode on).
* <p>
* "Mono" is short for the word "monophonic," which in this context is
* opposed to the word "polyphonic" and refers to a single synthesizer voice
* per MIDI channel. It has nothing to do with how many audio channels there
* might be (as in "monophonic" versus "stereophonic" recordings).
* <p>
* It is possible that the underlying synthesizer does not support mono
* mode. In order to verify that a call to {@code setMono} was successful,
* use {@code getMono}.
* *
* @param on {@code true} to turn mono mode on, {@code false} to turn it
* off (which means turning poly mode on)
* @see #getMono * @see #getMono
* @see VoiceStatus * @see VoiceStatus
*/ */
public void setMono(boolean on); void setMono(boolean on);
/** /**
* Obtains the current mono/poly mode. * Obtains the current mono/poly mode. Synthesizers that do not allow
* Synthesizers that do not allow changing mono/poly mode * changing mono/poly mode will always return the same value, regardless of
* will always return the same value, regardless * calls to {@code setMono}.
* of calls to <code>setMono</code>.
* @return <code>true</code> if mono mode is on, otherwise
* <code>false</code> (meaning poly mode is on).
* *
* @return {@code true} if mono mode is on, otherwise {@code false} (meaning
* poly mode is on)
* @see #setMono(boolean) * @see #setMono(boolean)
*/ */
public boolean getMono(); boolean getMono();
/** /**
* Turns omni mode on or off. In omni mode, the channel responds * Turns omni mode on or off. In omni mode, the channel responds to messages
* to messages sent on all channels. When omni is off, the channel * sent on all channels. When omni is off, the channel responds only to
* responds only to messages sent on its channel number. * messages sent on its channel number. The default is omni off.
* The default is omni off. * <p>
* * It is possible that the underlying synthesizer does not support omni
* It is possible that the underlying synthesizer * mode. In order to verify that {@code setOmni} was successful, use
* does not support omni mode. In order * {@code getOmni}.
* to verify that <code>setOmni</code>
* was successful, use <code>getOmni</code>.
*
* @param on <code>true</code> to turn omni mode on, <code>false</code> to
* turn it off.
* *
* @param on {@code true} to turn omni mode on, {@code false} to turn it
* off
* @see #getOmni * @see #getOmni
* @see VoiceStatus * @see VoiceStatus
*/ */
public void setOmni(boolean on); void setOmni(boolean on);
/** /**
* Obtains the current omni mode. * Obtains the current omni mode. Synthesizers that do not allow changing
* Synthesizers that do not allow changing the omni mode * the omni mode will always return the same value, regardless of calls to
* will always return the same value, regardless * {@code setOmni}.
* of calls to <code>setOmni</code>.
* @return <code>true</code> if omni mode is on, otherwise
* <code>false</code> (meaning omni mode is off).
* *
* @return {@code true} if omni mode is on, otherwise {@code false} (meaning
* omni mode is off)
* @see #setOmni(boolean) * @see #setOmni(boolean)
*/ */
public boolean getOmni(); boolean getOmni();
/** /**
* Sets the mute state for this channel. A value of * Sets the mute state for this channel. A value of {@code true} means the
* <code>true</code> means the channel is to be muted, <code>false</code> * channel is to be muted, {@code false} means the channel can sound (if
* means the channel can sound (if other channels are not soloed). * other channels are not soloed).
* <p> * <p>
* Unlike {@link #allSoundOff()}, this method * Unlike {@link #allSoundOff()}, this method applies to only a specific
* applies to only a specific channel, not to all channels. Further, it * channel, not to all channels. Further, it silences not only currently
* silences not only currently sounding notes, but also subsequently * sounding notes, but also subsequently received notes.
* received notes. * <p>
* * It is possible that the underlying synthesizer does not support muting
* It is possible that the underlying synthesizer * channels. In order to verify that a call to {@code setMute} was
* does not support muting channels. In order * successful, use {@code getMute}.
* to verify that a call to <code>setMute</code>
* was successful, use <code>getMute</code>.
* *
* @param mute the new mute state * @param mute the new mute state
*
* @see #getMute * @see #getMute
* @see #setSolo(boolean) * @see #setSolo(boolean)
*/ */
public void setMute(boolean mute); void setMute(boolean mute);
/** /**
* Obtains the current mute state for this channel. * Obtains the current mute state for this channel. If the underlying
* If the underlying synthesizer does not support * synthesizer does not support muting this channel, this method always
* muting this channel, this method always returns * returns {@code false}.
* <code>false</code>.
*
* @return <code>true</code> the channel is muted,
* or <code>false</code> if not
* *
* @return {@code true} the channel is muted, or {@code false} if not
* @see #setMute(boolean) * @see #setMute(boolean)
*/ */
public boolean getMute(); boolean getMute();
/** /**
* Sets the solo state for this channel. * Sets the solo state for this channel. If {@code solo} is {@code true}
* If <code>solo</code> is <code>true</code> only this channel * only this channel and other soloed channels will sound. If {@code solo}
* and other soloed channels will sound. If <code>solo</code> * is {@code false} then only other soloed channels will sound, unless no
* is <code>false</code> then only other soloed channels will * channels are soloed, in which case all unmuted channels will sound.
* sound, unless no channels are soloed, in which case all * <p>
* unmuted channels will sound. * It is possible that the underlying synthesizer does not support solo
* * channels. In order to verify that a call to {@code setSolo} was
* It is possible that the underlying synthesizer * successful, use {@code getSolo}.
* does not support solo channels. In order
* to verify that a call to <code>setSolo</code>
* was successful, use <code>getSolo</code>.
* *
* @param soloState new solo state for the channel * @param soloState new solo state for the channel
* @see #getSolo() * @see #getSolo()
*/ */
public void setSolo(boolean soloState); void setSolo(boolean soloState);
/** /**
* Obtains the current solo state for this channel. * Obtains the current solo state for this channel. If the underlying
* If the underlying synthesizer does not support * synthesizer does not support solo on this channel, this method always
* solo on this channel, this method always returns * returns {@code false}.
* <code>false</code>.
*
* @return <code>true</code> the channel is solo,
* or <code>false</code> if not
* *
* @return {@code true} the channel is solo, or {@code false} if not
* @see #setSolo(boolean) * @see #setSolo(boolean)
*/ */
public boolean getSolo(); boolean getSolo();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,63 +28,51 @@ package javax.sound.midi;
import java.util.List; import java.util.List;
/** /**
* <code>MidiDevice</code> is the base interface for all MIDI devices. * {@code MidiDevice} is the base interface for all MIDI devices. Common devices
* Common devices include synthesizers, sequencers, MIDI input ports, and MIDI * include synthesizers, sequencers, MIDI input ports, and MIDI output ports.
* output ports. * <p>
* * A {@code MidiDevice} can be a transmitter or a receiver of MIDI events, or
* <p>A <code>MidiDevice</code> can be a transmitter or a receiver of * both. Therefore, it can provide {@link Transmitter} or {@link Receiver}
* MIDI events, or both. Therefore, it can provide {@link Transmitter} * instances (or both). Typically, MIDI IN ports provide transmitters, MIDI OUT
* or {@link Receiver} instances (or both). Typically, MIDI IN ports * ports and synthesizers provide receivers. A Sequencer typically provides
* provide transmitters, MIDI OUT ports and synthesizers provide * transmitters for playback and receivers for recording.
* receivers. A Sequencer typically provides transmitters for playback * <p>
* and receivers for recording. * A {@code MidiDevice} can be opened and closed explicitly as well as
* * implicitly. Explicit opening is accomplished by calling {@link #open},
* <p>A <code>MidiDevice</code> can be opened and closed explicitly as * explicit closing is done by calling {@link #close} on the {@code MidiDevice}
* well as implicitly. Explicit opening is accomplished by calling * instance. If an application opens a {@code MidiDevice} explicitly, it has to
* {@link #open}, explicit closing is done by calling {@link * close it explicitly to free system resources and enable the application to
* #close} on the <code>MidiDevice</code> instance. * exit cleanly. Implicit opening is done by calling
* If an application opens a <code>MidiDevice</code> * {@link MidiSystem#getReceiver} and {@link MidiSystem#getTransmitter}. The
* explicitly, it has to close it explicitly to free system resources * {@code MidiDevice} used by {@code MidiSystem.getReceiver} and
* and enable the application to exit cleanly. Implicit opening is * {@code MidiSystem.getTransmitter} is implementation-dependant unless the
* done by calling {@link javax.sound.midi.MidiSystem#getReceiver * properties {@code javax.sound.midi.Receiver} and
* MidiSystem.getReceiver} and {@link * {@code javax.sound.midi.Transmitter} are used (see the description of
* javax.sound.midi.MidiSystem#getTransmitter * properties to select default providers in {@link MidiSystem}). A
* MidiSystem.getTransmitter}. The <code>MidiDevice</code> used by * {@code MidiDevice} that was opened implicitly, is closed implicitly by
* <code>MidiSystem.getReceiver</code> and * closing the {@code Receiver} or {@code Transmitter} that resulted in opening
* <code>MidiSystem.getTransmitter</code> is implementation-dependant * it. If more than one implicitly opening {@code Receiver} or
* unless the properties <code>javax.sound.midi.Receiver</code> * {@code Transmitter} were obtained by the application, the device is closed
* and <code>javax.sound.midi.Transmitter</code> are used (see the * after the last {@code Receiver} or {@code Transmitter} has been closed. On
* description of properties to select default providers in * the other hand, calling {@code getReceiver} or {@code getTransmitter} on the
* {@link javax.sound.midi.MidiSystem}). A <code>MidiDevice</code> * device instance directly does not open the device implicitly. Closing these
* that was opened implicitly, is closed implicitly by closing the * {@code Transmitter}s and {@code Receiver}s does not close the device
* <code>Receiver</code> or <code>Transmitter</code> that resulted in * implicitly. To use a device with {@code Receiver}s or {@code Transmitter}s
* opening it. If more than one implicitly opening * obtained this way, the device has to be opened and closed explicitly.
* <code>Receiver</code> or <code>Transmitter</code> were obtained by * <p>
* the application, the device is closed after the last * If implicit and explicit opening and closing are mixed on the same
* <code>Receiver</code> or <code>Transmitter</code> has been * {@code MidiDevice} instance, the following rules apply:
* closed. On the other hand, calling <code>getReceiver</code> or
* <code>getTransmitter</code> on the device instance directly does
* not open the device implicitly. Closing these
* <code>Transmitter</code>s and <code>Receiver</code>s does not close
* the device implicitly. To use a device with <code>Receiver</code>s
* or <code>Transmitter</code>s obtained this way, the device has to
* be opened and closed explicitly.
*
* <p>If implicit and explicit opening and closing are mixed on the
* same <code>MidiDevice</code> instance, the following rules apply:
* *
* <ul> * <ul>
* <li>After an explicit open (either before or after implicit * <li>After an explicit open (either before or after implicit opens), the
* opens), the device will not be closed by implicit closing. The only * device will not be closed by implicit closing. The only way to close an
* way to close an explicitly opened device is an explicit close.</li> * explicitly opened device is an explicit close.</li>
* * <li>An explicit close always closes the device, even if it also has been
* <li>An explicit close always closes the device, even if it also has * opened implicitly. A subsequent implicit close has no further effect.</li>
* been opened implicitly. A subsequent implicit close has no further
* effect.</li>
* </ul> * </ul>
* *
* To detect if a MidiDevice represents a hardware MIDI port, the * To detect if a MidiDevice represents a hardware MIDI port, the following
* following programming technique can be used: * programming technique can be used:
* *
* <pre>{@code * <pre>{@code
* MidiDevice device = ...; * MidiDevice device = ...;
@ -95,193 +83,171 @@ import java.util.List;
* }</pre> * }</pre>
* *
* <p> * <p>
* A <code>MidiDevice</code> includes a <code>{@link MidiDevice.Info}</code> object * A {@code MidiDevice} includes a {@link Info} object to provide manufacturer
* to provide manufacturer information and so on. * information and so on.
* *
* @author Kara Kytle
* @author Florian Bomers
* @see Synthesizer * @see Synthesizer
* @see Sequencer * @see Sequencer
* @see Receiver * @see Receiver
* @see Transmitter * @see Transmitter
*
* @author Kara Kytle
* @author Florian Bomers
*/ */
public interface MidiDevice extends AutoCloseable { public interface MidiDevice extends AutoCloseable {
/** /**
* Obtains information about the device, including its Java class and * Obtains information about the device, including its Java class and
* <code>Strings</code> containing its name, vendor, and description. * {@code Strings} containing its name, vendor, and description.
* *
* @return device info * @return device info
*/ */
public Info getDeviceInfo(); Info getDeviceInfo();
/** /**
* Opens the device, indicating that it should now acquire any * Opens the device, indicating that it should now acquire any system
* system resources it requires and become operational. * resources it requires and become operational.
*
* <p>An application opening a device explicitly with this call
* has to close the device by calling {@link #close}. This is
* necessary to release system resources and allow applications to
* exit cleanly.
*
* <p> * <p>
* Note that some devices, once closed, cannot be reopened. Attempts * An application opening a device explicitly with this call has to close
* to reopen such a device will always result in a MidiUnavailableException. * the device by calling {@link #close}. This is necessary to release system
* * resources and allow applications to exit cleanly.
* @throws MidiUnavailableException thrown if the device cannot be * <p>
* opened due to resource restrictions. * Note that some devices, once closed, cannot be reopened. Attempts to
* @throws SecurityException thrown if the device cannot be * reopen such a device will always result in a MidiUnavailableException.
* opened due to security restrictions.
* *
* @throws MidiUnavailableException thrown if the device cannot be opened
* due to resource restrictions
* @throws SecurityException thrown if the device cannot be opened due to
* security restrictions
* @see #close * @see #close
* @see #isOpen * @see #isOpen
*/ */
public void open() throws MidiUnavailableException; void open() throws MidiUnavailableException;
/** /**
* Closes the device, indicating that the device should now release * Closes the device, indicating that the device should now release any
* any system resources it is using. * system resources it is using.
* * <p>
* <p>All <code>Receiver</code> and <code>Transmitter</code> instances * All {@code Receiver} and {@code Transmitter} instances open from this
* open from this device are closed. This includes instances retrieved * device are closed. This includes instances retrieved via
* via <code>MidiSystem</code>. * {@code MidiSystem}.
* *
* @see #open * @see #open
* @see #isOpen * @see #isOpen
*/ */
public void close(); void close();
/** /**
* Reports whether the device is open. * Reports whether the device is open.
* *
* @return <code>true</code> if the device is open, otherwise * @return {@code true} if the device is open, otherwise {@code false}
* <code>false</code>
* @see #open * @see #open
* @see #close * @see #close
*/ */
public boolean isOpen(); boolean isOpen();
/** /**
* Obtains the current time-stamp of the device, in microseconds. * Obtains the current time-stamp of the device, in microseconds. If a
* If a device supports time-stamps, it should start counting at * device supports time-stamps, it should start counting at 0 when the
* 0 when the device is opened and continue incrementing its * device is opened and continue incrementing its time-stamp in microseconds
* time-stamp in microseconds until the device is closed. * until the device is closed. If it does not support time-stamps, it should
* If it does not support time-stamps, it should always return * always return -1.
* -1.
* @return the current time-stamp of the device in microseconds,
* or -1 if time-stamping is not supported by the device.
*/
public long getMicrosecondPosition();
/**
* Obtains the maximum number of MIDI IN connections available on this
* MIDI device for receiving MIDI data.
* @return maximum number of MIDI IN connections,
* or -1 if an unlimited number of connections is available.
*/
public int getMaxReceivers();
/**
* Obtains the maximum number of MIDI OUT connections available on this
* MIDI device for transmitting MIDI data.
* @return maximum number of MIDI OUT connections,
* or -1 if an unlimited number of connections is available.
*/
public int getMaxTransmitters();
/**
* Obtains a MIDI IN receiver through which the MIDI device may receive
* MIDI data. The returned receiver must be closed when the application
* has finished using it.
* *
* <p>Usually the returned receiver implements * @return the current time-stamp of the device in microseconds, or -1 if
* the {@code MidiDeviceReceiver} interface. * time-stamping is not supported by the device
*/
long getMicrosecondPosition();
/**
* Obtains the maximum number of MIDI IN connections available on this MIDI
* device for receiving MIDI data.
* *
* <p>Obtaining a <code>Receiver</code> with this method does not * @return maximum number of MIDI IN connections, or -1 if an unlimited
* open the device. To be able to use the device, it has to be * number of connections is available
* opened explicitly by calling {@link #open}. Also, closing the */
* <code>Receiver</code> does not close the device. It has to be int getMaxReceivers();
* closed explicitly by calling {@link #close}.
/**
* Obtains the maximum number of MIDI OUT connections available on this MIDI
* device for transmitting MIDI data.
* *
* @return a receiver for the device. * @return maximum number of MIDI OUT connections, or -1 if an unlimited
* number of connections is available
*/
int getMaxTransmitters();
/**
* Obtains a MIDI IN receiver through which the MIDI device may receive MIDI
* data. The returned receiver must be closed when the application has
* finished using it.
* <p>
* Usually the returned receiver implements the {@code MidiDeviceReceiver}
* interface.
* <p>
* Obtaining a {@code Receiver} with this method does not open the device.
* To be able to use the device, it has to be opened explicitly by calling
* {@link #open}. Also, closing the {@code Receiver} does not close the
* device. It has to be closed explicitly by calling {@link #close}.
*
* @return a receiver for the device
* @throws MidiUnavailableException thrown if a receiver is not available * @throws MidiUnavailableException thrown if a receiver is not available
* due to resource restrictions * due to resource restrictions
* @see Receiver#close() * @see Receiver#close()
*/ */
public Receiver getReceiver() throws MidiUnavailableException; Receiver getReceiver() throws MidiUnavailableException;
/** /**
* Returns all currently active, non-closed receivers * Returns all currently active, non-closed receivers connected with this
* connected with this MidiDevice. * MidiDevice. A receiver can be removed from the device by closing it.
* A receiver can be removed * <p>
* from the device by closing it. * Usually the returned receivers implement the {@code MidiDeviceReceiver}
* * interface.
* <p>Usually the returned receivers implement
* the {@code MidiDeviceReceiver} interface.
* *
* @return an unmodifiable list of the open receivers * @return an unmodifiable list of the open receivers
* @since 1.5 * @since 1.5
*/ */
List<Receiver> getReceivers(); List<Receiver> getReceivers();
/** /**
* Obtains a MIDI OUT connection from which the MIDI device will transmit * Obtains a MIDI OUT connection from which the MIDI device will transmit
* MIDI data The returned transmitter must be closed when the application * MIDI data. The returned transmitter must be closed when the application
* has finished using it. * has finished using it.
* <p>
* Usually the returned transmitter implements the
* {@code MidiDeviceTransmitter} interface.
* <p>
* Obtaining a {@code Transmitter} with this method does not open the
* device. To be able to use the device, it has to be opened explicitly by
* calling {@link #open}. Also, closing the {@code Transmitter} does not
* close the device. It has to be closed explicitly by calling
* {@link #close}.
* *
* <p>Usually the returned transmitter implements * @return a MIDI OUT transmitter for the device
* the {@code MidiDeviceTransmitter} interface.
*
* <p>Obtaining a <code>Transmitter</code> with this method does not
* open the device. To be able to use the device, it has to be
* opened explicitly by calling {@link #open}. Also, closing the
* <code>Transmitter</code> does not close the device. It has to be
* closed explicitly by calling {@link #close}.
*
* @return a MIDI OUT transmitter for the device.
* @throws MidiUnavailableException thrown if a transmitter is not available * @throws MidiUnavailableException thrown if a transmitter is not available
* due to resource restrictions * due to resource restrictions
* @see Transmitter#close() * @see Transmitter#close()
*/ */
public Transmitter getTransmitter() throws MidiUnavailableException; Transmitter getTransmitter() throws MidiUnavailableException;
/** /**
* Returns all currently active, non-closed transmitters * Returns all currently active, non-closed transmitters connected with this
* connected with this MidiDevice. * MidiDevice. A transmitter can be removed from the device by closing it.
* A transmitter can be removed * <p>
* from the device by closing it. * Usually the returned transmitters implement the
* * {@code MidiDeviceTransmitter} interface.
* <p>Usually the returned transmitters implement
* the {@code MidiDeviceTransmitter} interface.
* *
* @return an unmodifiable list of the open transmitters * @return an unmodifiable list of the open transmitters
* @since 1.5 * @since 1.5
*/ */
List<Transmitter> getTransmitters(); List<Transmitter> getTransmitters();
/** /**
* A <code>MidiDevice.Info</code> object contains assorted * A {@code MidiDevice.Info} object contains assorted data about a
* data about a <code>{@link MidiDevice}</code>, including its * {@link MidiDevice}, including its name, the company who created it, and
* name, the company who created it, and descriptive text. * descriptive text.
* *
* @see MidiDevice#getDeviceInfo * @see MidiDevice#getDeviceInfo
*/ */
public static class Info { class Info {
/** /**
* The device's name. * The device's name.
@ -303,7 +269,6 @@ public interface MidiDevice extends AutoCloseable {
*/ */
private String version; private String version;
/** /**
* Constructs a device info object. * Constructs a device info object.
* *
@ -312,7 +277,8 @@ public interface MidiDevice extends AutoCloseable {
* @param description a description of the device * @param description a description of the device
* @param version version information for the device * @param version version information for the device
*/ */
protected Info(String name, String vendor, String description, String version) { protected Info(String name, String vendor, String description,
String version) {
this.name = name; this.name = name;
this.vendor = vendor; this.vendor = vendor;
@ -320,20 +286,18 @@ public interface MidiDevice extends AutoCloseable {
this.version = version; this.version = version;
} }
/** /**
* Reports whether two objects are equal. * Reports whether two objects are equal. Returns {@code true} if the
* Returns <code>true</code> if the objects are identical. * objects are identical.
* @param obj the reference object with which to compare this *
* object * @param obj the reference object with which to compare this object
* @return <code>true</code> if this object is the same as the * @return {@code true} if this object is the same as the {@code obj}
* <code>obj</code> argument; <code>false</code> otherwise * argument; {@code false} otherwise
*/ */
public final boolean equals(Object obj) { public final boolean equals(Object obj) {
return super.equals(obj); return super.equals(obj);
} }
/** /**
* Finalizes the hashcode method. * Finalizes the hashcode method.
*/ */
@ -341,7 +305,6 @@ public interface MidiDevice extends AutoCloseable {
return super.hashCode(); return super.hashCode();
} }
/** /**
* Obtains the name of the device. * Obtains the name of the device.
* *
@ -351,43 +314,40 @@ public interface MidiDevice extends AutoCloseable {
return name; return name;
} }
/** /**
* Obtains the name of the company who supplies the device. * Obtains the name of the company who supplies the device.
*
* @return device the vendor's name * @return device the vendor's name
*/ */
public final String getVendor() { public final String getVendor() {
return vendor; return vendor;
} }
/** /**
* Obtains the description of the device. * Obtains the description of the device.
*
* @return a description of the device * @return a description of the device
*/ */
public final String getDescription() { public final String getDescription() {
return description; return description;
} }
/** /**
* Obtains the version of the device. * Obtains the version of the device.
*
* @return textual version information for the device. * @return textual version information for the device.
*/ */
public final String getVersion() { public final String getVersion() {
return version; return version;
} }
/** /**
* Provides a string representation of the device information. * Provides a string representation of the device information.
*
* @return a description of the info object * @return a description of the info object
*/ */
public final String toString() { public final String toString() {
return name; return name;
} }
} // class Info } // class Info
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,16 +26,18 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* <p>{@code MidiDeviceReceiver} is a {@code Receiver} which represents * {@code MidiDeviceReceiver} is a {@code Receiver} which represents a MIDI
* a MIDI input connector of a {@code MidiDevice} * input connector of a {@code MidiDevice} (see
* (see {@link MidiDevice#getReceiver()}). * {@link MidiDevice#getReceiver()}).
* *
* @since 1.7 * @since 1.7
*/ */
public interface MidiDeviceReceiver extends Receiver { public interface MidiDeviceReceiver extends Receiver {
/** /**
* Obtains a MidiDevice object which is an owner of this Receiver. * Obtains a MidiDevice object which is an owner of this Receiver.
*
* @return a MidiDevice object which is an owner of this Receiver * @return a MidiDevice object which is an owner of this Receiver
*/ */
public MidiDevice getMidiDevice(); MidiDevice getMidiDevice();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,11 +25,10 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* <p>{@code MidiDeviceTransmitter} is a {@code Transmitter} which represents * {@code MidiDeviceTransmitter} is a {@code Transmitter} which represents a
* a MIDI input connector of a {@code MidiDevice} * MIDI input connector of a {@code MidiDevice} (see
* (see {@link MidiDevice#getTransmitter()}). * {@link MidiDevice#getTransmitter()}).
* *
* @since 1.7 * @since 1.7
*/ */
@ -37,7 +36,8 @@ public interface MidiDeviceTransmitter extends Transmitter {
/** /**
* Obtains a MidiDevice object which is an owner of this Transmitter. * Obtains a MidiDevice object which is an owner of this Transmitter.
*
* @return a MidiDevice object which is an owner of this Transmitter * @return a MidiDevice object which is an owner of this Transmitter
*/ */
public MidiDevice getMidiDevice(); MidiDevice getMidiDevice();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,39 +26,33 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* MIDI events contain a MIDI message and a corresponding time-stamp * MIDI events contain a MIDI message and a corresponding time-stamp expressed
* expressed in ticks, and can represent the MIDI event information * in ticks, and can represent the MIDI event information stored in a MIDI file
* stored in a MIDI file or a <code>{@link Sequence}</code> object. The * or a {@link Sequence} object. The duration of a tick is specified by the
* duration of a tick is specified by the timing information contained * timing information contained in the MIDI file or {@code Sequence} object.
* in the MIDI file or <code>Sequence</code> object.
* <p> * <p>
* In Java Sound, <code>MidiEvent</code> objects are typically contained in a * In Java Sound, {@code MidiEvent} objects are typically contained in a
* <code>{@link Track}</code>, and <code>Tracks</code> are likewise * {@link Track}, and {@code Tracks} are likewise contained in a
* contained in a <code>Sequence</code>. * {@code Sequence}.
*
* *
* @author David Rivas * @author David Rivas
* @author Kara Kytle * @author Kara Kytle
*/ */
public class MidiEvent { public class MidiEvent {
// Instance variables
/** /**
* The MIDI message for this event. * The MIDI message for this event.
*/ */
private final MidiMessage message; private final MidiMessage message;
/** /**
* The tick value for this event. * The tick value for this event.
*/ */
private long tick; private long tick;
/** /**
* Constructs a new <code>MidiEvent</code>. * Constructs a new {@code MidiEvent}.
*
* @param message the MIDI message contained in the event * @param message the MIDI message contained in the event
* @param tick the time-stamp for the event, in MIDI ticks * @param tick the time-stamp for the event, in MIDI ticks
*/ */
@ -70,24 +64,25 @@ public class MidiEvent {
/** /**
* Obtains the MIDI message contained in the event. * Obtains the MIDI message contained in the event.
*
* @return the MIDI message * @return the MIDI message
*/ */
public MidiMessage getMessage() { public MidiMessage getMessage() {
return message; return message;
} }
/** /**
* Sets the time-stamp for the event, in MIDI ticks * Sets the time-stamp for the event, in MIDI ticks.
*
* @param tick the new time-stamp, in MIDI ticks * @param tick the new time-stamp, in MIDI ticks
*/ */
public void setTick(long tick) { public void setTick(long tick) {
this.tick = tick; this.tick = tick;
} }
/** /**
* Obtains the time-stamp for the event, in MIDI ticks * Obtains the time-stamp for the event, in MIDI ticks.
*
* @return the time-stamp for the event, in MIDI ticks * @return the time-stamp for the event, in MIDI ticks
*/ */
public long getTick() { public long getTick() {

View file

@ -25,29 +25,23 @@
package javax.sound.midi; package javax.sound.midi;
import java.io.InputStream;
import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* A <code>MidiFileFormat</code> object encapsulates a MIDI file's * A {@code MidiFileFormat} object encapsulates a MIDI file's type, as well as
* type, as well as its length and timing information. * its length and timing information.
* * <p>
* <p>A <code>MidiFileFormat</code> object can * A {@code MidiFileFormat} object can include a set of properties. A property
* include a set of properties. A property is a pair of key and value: * is a pair of key and value: the key is of type {@code String}, the associated
* the key is of type <code>String</code>, the associated property * property value is an arbitrary object. Properties specify additional
* value is an arbitrary object. * informational meta data (like a author, or copyright). Properties are
* Properties specify additional informational * optional information, and file reader and file writer implementations are not
* meta data (like a author, or copyright). * required to provide or recognize properties.
* Properties are optional information, and file reader and file * <p>
* writer implementations are not required to provide or * The following table lists some common properties that should be used in
* recognize properties. * implementations:
*
* <p>The following table lists some common properties that should
* be used in implementations:
* *
* <table border=1> * <table border=1>
<caption>MIDI File Format Properties</caption> <caption>MIDI File Format Properties</caption>
@ -83,24 +77,21 @@ import java.util.Map;
* </tr> * </tr>
* </table> * </table>
* *
* @see MidiSystem#getMidiFileFormat(java.io.File)
* @see Sequencer#setSequence(java.io.InputStream stream)
*
* @author Kara Kytle * @author Kara Kytle
* @author Florian Bomers * @author Florian Bomers
* @see MidiSystem#getMidiFileFormat(java.io.File)
* @see Sequencer#setSequence(java.io.InputStream stream)
*/ */
public class MidiFileFormat { public class MidiFileFormat {
/** /**
* Represents unknown length. * Represents unknown length.
*
* @see #getByteLength * @see #getByteLength
* @see #getMicrosecondLength * @see #getMicrosecondLength
*/ */
public static final int UNKNOWN_LENGTH = -1; public static final int UNKNOWN_LENGTH = -1;
/** /**
* The type of MIDI file. * The type of MIDI file.
*/ */
@ -132,19 +123,22 @@ public class MidiFileFormat {
*/ */
protected long microsecondLength; protected long microsecondLength;
/**
/** The set of properties */ * The set of properties.
*/
private HashMap<String, Object> properties; private HashMap<String, Object> properties;
/** /**
* Constructs a <code>MidiFileFormat</code>. * Constructs a {@code MidiFileFormat}.
* *
* @param type the MIDI file type (0, 1, or 2) * @param type the MIDI file type (0, 1, or 2)
* @param divisionType the timing division type (PPQ or one of the SMPTE types) * @param divisionType the timing division type (PPQ or one of the SMPTE
* types)
* @param resolution the timing resolution * @param resolution the timing resolution
* @param bytes the length of the MIDI file in bytes, or UNKNOWN_LENGTH if not known * @param bytes the length of the MIDI file in bytes, or UNKNOWN_LENGTH if
* @param microseconds the duration of the file in microseconds, or UNKNOWN_LENGTH if not known * not known
* @param microseconds the duration of the file in microseconds, or
* UNKNOWN_LENGTH if not known
* @see #UNKNOWN_LENGTH * @see #UNKNOWN_LENGTH
* @see Sequence#PPQ * @see Sequence#PPQ
* @see Sequence#SMPTE_24 * @see Sequence#SMPTE_24
@ -162,21 +156,18 @@ public class MidiFileFormat {
this.properties = null; this.properties = null;
} }
/** /**
* Construct a <code>MidiFileFormat</code> with a set of properties. * Construct a {@code MidiFileFormat} with a set of properties.
* *
* @param type the MIDI file type (0, 1, or 2) * @param type the MIDI file type (0, 1, or 2)
* @param divisionType the timing division type * @param divisionType the timing division type (PPQ or one of the SMPTE
* (PPQ or one of the SMPTE types) * types)
* @param resolution the timing resolution * @param resolution the timing resolution
* @param bytes the length of the MIDI file in bytes, * @param bytes the length of the MIDI file in bytes, or UNKNOWN_LENGTH if
* or UNKNOWN_LENGTH if not known * not known
* @param microseconds the duration of the file in microseconds, * @param microseconds the duration of the file in microseconds, or
* or UNKNOWN_LENGTH if not known * UNKNOWN_LENGTH if not known
* @param properties a <code>Map&lt;String,Object&gt;</code> object * @param properties a {@code Map<String,Object>} object with properties
* with properties
*
* @see #UNKNOWN_LENGTH * @see #UNKNOWN_LENGTH
* @see Sequence#PPQ * @see Sequence#PPQ
* @see Sequence#SMPTE_24 * @see Sequence#SMPTE_24
@ -192,10 +183,9 @@ public class MidiFileFormat {
this.properties = new HashMap<String, Object>(properties); this.properties = new HashMap<String, Object>(properties);
} }
/** /**
* Obtains the MIDI file type. * Obtains the MIDI file type.
*
* @return the file's type (0, 1, or 2) * @return the file's type (0, 1, or 2)
*/ */
public int getType() { public int getType() {
@ -206,7 +196,6 @@ public class MidiFileFormat {
* Obtains the timing division type for the MIDI file. * Obtains the timing division type for the MIDI file.
* *
* @return the division type (PPQ or one of the SMPTE types) * @return the division type (PPQ or one of the SMPTE types)
*
* @see Sequence#Sequence(float, int) * @see Sequence#Sequence(float, int)
* @see Sequence#PPQ * @see Sequence#PPQ
* @see Sequence#SMPTE_24 * @see Sequence#SMPTE_24
@ -219,11 +208,10 @@ public class MidiFileFormat {
return divisionType; return divisionType;
} }
/** /**
* Obtains the timing resolution for the MIDI file. * Obtains the timing resolution for the MIDI file. If the division type is
* If the division type is PPQ, the resolution is specified in ticks per beat. * PPQ, the resolution is specified in ticks per beat. For SMTPE timing, the
* For SMTPE timing, the resolution is specified in ticks per frame. * resolution is specified in ticks per frame.
* *
* @return the number of ticks per beat (PPQ) or per frame (SMPTE) * @return the number of ticks per beat (PPQ) or per frame (SMPTE)
* @see #getDivisionType * @see #getDivisionType
@ -233,9 +221,9 @@ public class MidiFileFormat {
return resolution; return resolution;
} }
/** /**
* Obtains the length of the MIDI file, expressed in 8-bit bytes. * Obtains the length of the MIDI file, expressed in 8-bit bytes.
*
* @return the number of bytes in the file, or UNKNOWN_LENGTH if not known * @return the number of bytes in the file, or UNKNOWN_LENGTH if not known
* @see #UNKNOWN_LENGTH * @see #UNKNOWN_LENGTH
*/ */
@ -245,7 +233,9 @@ public class MidiFileFormat {
/** /**
* Obtains the length of the MIDI file, expressed in microseconds. * Obtains the length of the MIDI file, expressed in microseconds.
* @return the file's duration in microseconds, or UNKNOWN_LENGTH if not known *
* @return the file's duration in microseconds, or UNKNOWN_LENGTH if not
* known
* @see Sequence#getMicrosecondLength() * @see Sequence#getMicrosecondLength()
* @see #getByteLength * @see #getByteLength
* @see #UNKNOWN_LENGTH * @see #UNKNOWN_LENGTH
@ -255,14 +245,11 @@ public class MidiFileFormat {
} }
/** /**
* Obtain an unmodifiable map of properties. * Obtain an unmodifiable map of properties. The concept of properties is
* The concept of properties is further explained in * further explained in the {@link MidiFileFormat class description}.
* the {@link MidiFileFormat class description}.
*
* @return a <code>Map&lt;String,Object&gt;</code> object containing
* all properties. If no properties are recognized, an empty map is
* returned.
* *
* @return a {@code Map<String,Object>} object containing all properties. If
* no properties are recognized, an empty map is returned.
* @see #getProperty(String) * @see #getProperty(String)
* @since 1.5 * @since 1.5
*/ */
@ -277,20 +264,16 @@ public class MidiFileFormat {
return Collections.unmodifiableMap(ret); return Collections.unmodifiableMap(ret);
} }
/** /**
* Obtain the property value specified by the key. * Obtain the property value specified by the key. The concept of properties
* The concept of properties is further explained in * is further explained in the {@link MidiFileFormat class description}.
* the {@link MidiFileFormat class description}. * <p>
* * If the specified property is not defined for a particular file format,
* <p>If the specified property is not defined for a * this method returns {@code null}.
* particular file format, this method returns
* <code>null</code>.
* *
* @param key the key of the desired property * @param key the key of the desired property
* @return the value of the property with the specified key, * @return the value of the property with the specified key, or {@code null}
* or <code>null</code> if the property does not exist. * if the property does not exist
*
* @see #properties() * @see #properties()
* @since 1.5 * @since 1.5
*/ */
@ -300,6 +283,4 @@ public class MidiFileFormat {
} }
return properties.get(key); return properties.get(key);
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,83 +26,76 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* <code>MidiMessage</code> is the base class for MIDI messages. They include * {@code MidiMessage} is the base class for MIDI messages. They include not
* not only the standard MIDI messages that a synthesizer can respond to, but also * only the standard MIDI messages that a synthesizer can respond to, but also
* "meta-events" that can be used by sequencer programs. There are meta-events * "meta-events" that can be used by sequencer programs. There are meta-events
* for such information as lyrics, copyrights, tempo indications, time and key * for such information as lyrics, copyrights, tempo indications, time and key
* signatures, markers, etc. For more information, see the Standard MIDI Files 1.0 * signatures, markers, etc. For more information, see the Standard MIDI Files
* specification, which is part of the Complete MIDI 1.0 Detailed Specification * 1.0 specification, which is part of the Complete MIDI 1.0 Detailed
* published by the MIDI Manufacturer's Association * Specification published by the MIDI Manufacturer's Association
* (<a href = http://www.midi.org>http://www.midi.org</a>). * (<a href = http://www.midi.org>http://www.midi.org</a>).
* <p> * <p>
* The base <code>MidiMessage</code> class provides access to three types of * The base {@code MidiMessage} class provides access to three types of
* information about a MIDI message: * information about a MIDI message:
* <ul> * <ul>
* <li>The messages's status byte</li> * <li>The messages's status byte</li>
* <li>The total length of the message in bytes (the status byte plus any data bytes)</li> * <li>The total length of the message in bytes (the status byte plus any data
* bytes)</li>
* <li>A byte array containing the complete message</li> * <li>A byte array containing the complete message</li>
* </ul> * </ul>
* *
* <code>MidiMessage</code> includes methods to get, but not set, these values. * {@code MidiMessage} includes methods to get, but not set, these values.
* Setting them is a subclass responsibility. * Setting them is a subclass responsibility.
* <p> * <p>
* <a name="integersVsBytes"></a> * <a name="integersVsBytes"></a> The MIDI standard expresses MIDI data in
* The MIDI standard expresses MIDI data in bytes. However, because * bytes. However, because Java<sup>TM</sup> uses signed bytes, the Java Sound
* Java<sup>TM</sup> uses signed bytes, the Java Sound API uses integers * API uses integers instead of bytes when expressing MIDI data. For example,
* instead of bytes when expressing MIDI data. For example, the * the {@link #getStatus()} method of {@code MidiMessage} returns MIDI status
* {@link #getStatus()} method of * bytes as integers. If you are processing MIDI data that originated outside
* <code>MidiMessage</code> returns MIDI status bytes as integers. If you are * Java Sound and now is encoded as signed bytes, the bytes can can be
* processing MIDI data that originated outside Java Sound and now * converted to integers using this conversion:
* is encoded as signed bytes, the bytes can *
* can be converted to integers using this conversion:
* <center>{@code int i = (int)(byte & 0xFF)}</center> * <center>{@code int i = (int)(byte & 0xFF)}</center>
* <p> * <p>
* If you simply need to pass a known MIDI byte value as a method parameter, * If you simply need to pass a known MIDI byte value as a method parameter, it
* it can be expressed directly as an integer, using (for example) decimal or * can be expressed directly as an integer, using (for example) decimal or
* hexadecimal notation. For instance, to pass the "active sensing" status byte * hexadecimal notation. For instance, to pass the "active sensing" status byte
* as the first argument to ShortMessage's * as the first argument to ShortMessage's
* {@link ShortMessage#setMessage(int) setMessage(int)} * {@link ShortMessage#setMessage(int) setMessage(int)} method, you can express
* method, you can express it as 254 or 0xFE. * it as 254 or 0xFE.
*
* @see Track
* @see Sequence
* @see Receiver
* *
* @author David Rivas * @author David Rivas
* @author Kara Kytle * @author Kara Kytle
* @see Track
* @see Sequence
* @see Receiver
*/ */
public abstract class MidiMessage implements Cloneable { public abstract class MidiMessage implements Cloneable {
// Instance variables
/** /**
* The MIDI message data. The first byte is the status * The MIDI message data. The first byte is the status byte for the message;
* byte for the message; subsequent bytes up to the length * subsequent bytes up to the length of the message are data bytes for this
* of the message are data bytes for this message. * message.
*
* @see #getLength * @see #getLength
*/ */
protected byte[] data; protected byte[] data;
/** /**
* The number of bytes in the MIDI message, including the * The number of bytes in the MIDI message, including the status byte and
* status byte and any data bytes. * any data bytes.
*
* @see #getLength * @see #getLength
*/ */
protected int length = 0; protected int length = 0;
/** /**
* Constructs a new <code>MidiMessage</code>. This protected * Constructs a new {@code MidiMessage}. This protected constructor is
* constructor is called by concrete subclasses, which should * called by concrete subclasses, which should ensure that the data array
* ensure that the data array specifies a complete, valid MIDI * specifies a complete, valid MIDI message.
* message.
*
* @param data an array of bytes containing the complete message.
* The message data may be changed using the <code>setMessage</code>
* method.
* *
* @param data an array of bytes containing the complete message. The
* message data may be changed using the {@code setMessage} method.
* @see #setMessage * @see #setMessage
*/ */
protected MidiMessage(byte[] data) { protected MidiMessage(byte[] data) {
@ -112,20 +105,21 @@ public abstract class MidiMessage implements Cloneable {
} }
} }
/** /**
* Sets the data for the MIDI message. This protected * Sets the data for the MIDI message. This protected method is called by
* method is called by concrete subclasses, which should * concrete subclasses, which should ensure that the data array specifies a
* ensure that the data array specifies a complete, valid MIDI * complete, valid MIDI message.
* message.
* *
* @param data the data bytes in the MIDI message * @param data the data bytes in the MIDI message
* @param length the number of bytes in the data byte array * @param length the number of bytes in the data byte array
* @throws InvalidMidiDataException if the parameter values do not specify a valid MIDI meta message * @throws InvalidMidiDataException if the parameter values do not specify a
* valid MIDI meta message
*/ */
protected void setMessage(byte[] data, int length) throws InvalidMidiDataException { protected void setMessage(byte[] data, int length)
throws InvalidMidiDataException {
if (length < 0 || (length > 0 && length > data.length)) { if (length < 0 || (length > 0 && length > data.length)) {
throw new IndexOutOfBoundsException("length out of bounds: "+length); throw new IndexOutOfBoundsException(
"length out of bounds: " + length);
} }
this.length = length; this.length = length;
@ -135,16 +129,14 @@ public abstract class MidiMessage implements Cloneable {
System.arraycopy(data, 0, this.data, 0, length); System.arraycopy(data, 0, this.data, 0, length);
} }
/** /**
* Obtains the MIDI message data. The first byte of the returned byte * Obtains the MIDI message data. The first byte of the returned byte array
* array is the status byte of the message. Any subsequent bytes up to * is the status byte of the message. Any subsequent bytes up to the length
* the length of the message are data bytes. The byte array may have a * of the message are data bytes. The byte array may have a length which is
* length which is greater than that of the actual message; the total * greater than that of the actual message; the total length of the message
* length of the message in bytes is reported by the <code>{@link #getLength}</code> * in bytes is reported by the {@link #getLength} method.
* method.
* *
* @return the byte array containing the complete <code>MidiMessage</code> data * @return the byte array containing the complete {@code MidiMessage} data
*/ */
public byte[] getMessage() { public byte[] getMessage() {
byte[] returnedArray = new byte[length]; byte[] returnedArray = new byte[length];
@ -152,12 +144,11 @@ public abstract class MidiMessage implements Cloneable {
return returnedArray; return returnedArray;
} }
/** /**
* Obtains the status byte for the MIDI message. The status "byte" is * Obtains the status byte for the MIDI message. The status "byte" is
* represented as an integer; see the * represented as an integer; see the
* <a href="#integersVsBytes">discussion</a> in the * <a href="#integersVsBytes">discussion</a> in the {@code MidiMessage}
* <code>MidiMessage</code> class description. * class description.
* *
* @return the integer representation of this event's status byte * @return the integer representation of this event's status byte
*/ */
@ -168,13 +159,11 @@ public abstract class MidiMessage implements Cloneable {
return 0; return 0;
} }
/** /**
* Obtains the total length of the MIDI message in bytes. A * Obtains the total length of the MIDI message in bytes. A MIDI message
* MIDI message consists of one status byte and zero or more * consists of one status byte and zero or more data bytes. The return value
* data bytes. The return value ranges from 1 for system real-time messages, * ranges from 1 for system real-time messages, to 2 or 3 for channel
* to 2 or 3 for channel messages, to any value for meta and system * messages, to any value for meta and system exclusive messages.
* exclusive messages.
* *
* @return the length of the message in bytes * @return the length of the message in bytes
*/ */
@ -182,11 +171,11 @@ public abstract class MidiMessage implements Cloneable {
return length; return length;
} }
/** /**
* Creates a new object of the same class and with the same contents * Creates a new object of the same class and with the same contents as this
* as this object. * object.
* @return a clone of this instance. *
* @return a clone of this instance
*/ */
public abstract Object clone(); public abstract Object clone();
} }

View file

@ -25,39 +25,37 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* A <code>MidiUnavailableException</code> is thrown when a requested MIDI * A {@code MidiUnavailableException} is thrown when a requested MIDI component
* component cannot be opened or created because it is unavailable. This often * cannot be opened or created because it is unavailable. This often occurs when
* occurs when a device is in use by another application. More generally, it * a device is in use by another application. More generally, it can occur when
* can occur when there is a finite number of a certain kind of resource that can * there is a finite number of a certain kind of resource that can be used for
* be used for some purpose, and all of them are already in use (perhaps all by * some purpose, and all of them are already in use (perhaps all by this
* this application). For an example of the latter case, see the * application). For an example of the latter case, see the
* {@link Transmitter#setReceiver(Receiver) setReceiver} method of * {@link Transmitter#setReceiver(Receiver) setReceiver} method of
* <code>Transmitter</code>. * {@code Transmitter}.
* *
* @author Kara Kytle * @author Kara Kytle
*/ */
public class MidiUnavailableException extends Exception { public class MidiUnavailableException extends Exception {
private static final long serialVersionUID = 6093809578628944323L; private static final long serialVersionUID = 6093809578628944323L;
/** /**
* Constructs a <code>MidiUnavailableException</code> that has * Constructs a {@code MidiUnavailableException} that has {@code null} as
* <code>null</code> as its error detail message. * its error detail message.
*/ */
public MidiUnavailableException() { public MidiUnavailableException() {
super(); super();
} }
/** /**
* Constructs a <code>MidiUnavailableException</code> with the * Constructs a {@code MidiUnavailableException} with the specified detail
* specified detail message. * message.
* *
* @param message the string to display as an error detail message * @param message the string to display as an error detail message
*/ */
public MidiUnavailableException(String message) { public MidiUnavailableException(final String message) {
super(message); super(message);
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,88 +25,77 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* A <code>Patch</code> object represents a location, on a MIDI * A {@code Patch} object represents a location, on a MIDI synthesizer, into
* synthesizer, into which a single instrument is stored (loaded). * which a single instrument is stored (loaded). Every {@code Instrument} object
* Every <code>Instrument</code> object has its own <code>Patch</code> * has its own {@code Patch} object that specifies the memory location into
* object that specifies the memory location * which that instrument should be loaded. The location is specified abstractly
* into which that instrument should be loaded. The * by a bank index and a program number (not by any scheme that directly refers
* location is specified abstractly by a bank index and a program number (not by * to a specific address or offset in RAM). This is a hierarchical indexing
* any scheme that directly refers to a specific address or offset in RAM). * scheme: MIDI provides for up to 16384 banks, each of which contains up to 128
* This is a hierarchical indexing scheme: MIDI provides for up to 16384 banks, * program locations. For example, a minimal sort of synthesizer might have only
* each of which contains up to 128 program locations. For example, a * one bank of instruments, and only 32 instruments (programs) in that bank.
* minimal sort of synthesizer might have only one bank of instruments, and
* only 32 instruments (programs) in that bank.
* <p> * <p>
* To select what instrument should play the notes on a particular MIDI * To select what instrument should play the notes on a particular MIDI channel,
* channel, two kinds of MIDI message are used that specify a patch location: * two kinds of MIDI message are used that specify a patch location: a
* a bank-select command, and a program-change channel command. The Java Sound * bank-select command, and a program-change channel command. The Java Sound
* equivalent is the * equivalent is the
* {@link MidiChannel#programChange(int, int) programChange(int, int)} * {@link MidiChannel#programChange(int, int) programChange(int, int)} method of
* method of <code>MidiChannel</code>. * {@code MidiChannel}.
* *
* @author Kara Kytle
* @see Instrument * @see Instrument
* @see Instrument#getPatch() * @see Instrument#getPatch()
* @see MidiChannel#programChange(int, int) * @see MidiChannel#programChange(int, int)
* @see Synthesizer#loadInstruments(Soundbank, Patch[]) * @see Synthesizer#loadInstruments(Soundbank, Patch[])
* @see Soundbank * @see Soundbank
* @see Sequence#getPatchList() * @see Sequence#getPatchList()
*
* @author Kara Kytle
*/ */
public class Patch { public class Patch {
/** /**
* Bank index * Bank index.
*/ */
private final int bank; private final int bank;
/** /**
* Program change number * Program change number.
*/ */
private final int program; private final int program;
/** /**
* Constructs a new patch object from the specified bank and program * Constructs a new patch object from the specified bank and program
* numbers. * numbers.
*
* @param bank the bank index (in the range from 0 to 16383) * @param bank the bank index (in the range from 0 to 16383)
* @param program the program index (in the range from 0 to 127) * @param program the program index (in the range from 0 to 127)
*/ */
public Patch(int bank, int program) { public Patch(int bank, int program) {
this.bank = bank; this.bank = bank;
this.program = program; this.program = program;
} }
/** /**
* Returns the number of the bank that contains the instrument * Returns the number of the bank that contains the instrument whose
* whose location this <code>Patch</code> specifies. * location this {@code Patch} specifies.
*
* @return the bank number, whose range is from 0 to 16383 * @return the bank number, whose range is from 0 to 16383
* @see MidiChannel#programChange(int, int) * @see MidiChannel#programChange(int, int)
*/ */
public int getBank() { public int getBank() {
return bank; return bank;
} }
/** /**
* Returns the index, within * Returns the index, within a bank, of the instrument whose location this
* a bank, of the instrument whose location this <code>Patch</code> specifies. * {@code Patch} specifies.
* @return the instrument's program number, whose range is from 0 to 127
* *
* @return the instrument's program number, whose range is from 0 to 127
* @see MidiChannel#getProgram * @see MidiChannel#getProgram
* @see MidiChannel#programChange(int) * @see MidiChannel#programChange(int)
* @see MidiChannel#programChange(int, int) * @see MidiChannel#programChange(int, int)
*/ */
public int getProgram() { public int getProgram() {
return program; return program;
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,50 +25,46 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* A <code>Receiver</code> receives <code>{@link MidiEvent}</code> objects and * A {@code Receiver} receives {@link MidiEvent} objects and typically does
* typically does something useful in response, such as interpreting them to * something useful in response, such as interpreting them to generate sound or
* generate sound or raw MIDI output. Common MIDI receivers include * raw MIDI output. Common MIDI receivers include synthesizers and MIDI Out
* synthesizers and MIDI Out ports. * ports.
* *
* @author Kara Kytle
* @see MidiDevice * @see MidiDevice
* @see Synthesizer * @see Synthesizer
* @see Transmitter * @see Transmitter
*
* @author Kara Kytle
*/ */
public interface Receiver extends AutoCloseable { public interface Receiver extends AutoCloseable {
//$$fb 2002-04-12: fix for 4662090: Contradiction in Receiver specification //$$fb 2002-04-12: fix for 4662090: Contradiction in Receiver specification
/** /**
* Sends a MIDI message and time-stamp to this receiver. * Sends a MIDI message and time-stamp to this receiver. If time-stamping is
* If time-stamping is not supported by this receiver, the time-stamp * not supported by this receiver, the time-stamp value should be -1.
* value should be -1. *
* @param message the MIDI message to send * @param message the MIDI message to send
* @param timeStamp the time-stamp for the message, in microseconds. * @param timeStamp the time-stamp for the message, in microseconds
* @throws IllegalStateException if the receiver is closed * @throws IllegalStateException if the receiver is closed
*/ */
public void send(MidiMessage message, long timeStamp); void send(MidiMessage message, long timeStamp);
/** /**
* Indicates that the application has finished using the receiver, and * Indicates that the application has finished using the receiver, and that
* that limited resources it requires may be released or made available. * limited resources it requires may be released or made available.
* * <p>
* <p>If the creation of this <code>Receiver</code> resulted in * If the creation of this {@code Receiver} resulted in implicitly opening
* implicitly opening the underlying device, the device is * the underlying device, the device is implicitly closed by this method.
* implicitly closed by this method. This is true unless the device is * This is true unless the device is kept open by other {@code Receiver} or
* kept open by other <code>Receiver</code> or <code>Transmitter</code> * {@code Transmitter} instances that opened the device implicitly, and
* instances that opened the device implicitly, and unless the device * unless the device has been opened explicitly. If the device this
* has been opened explicitly. If the device this * {@code Receiver} is retrieved from is closed explicitly by calling
* <code>Receiver</code> is retrieved from is closed explicitly by * {@link MidiDevice#close MidiDevice.close}, the {@code Receiver} is
* calling {@link MidiDevice#close MidiDevice.close}, the * closed, too. For a detailed description of open/close behaviour see the
* <code>Receiver</code> is closed, too. For a detailed * class description of {@link MidiDevice MidiDevice}.
* description of open/close behaviour see the class description
* of {@link javax.sound.midi.MidiDevice MidiDevice}.
* *
* @see javax.sound.midi.MidiSystem#getReceiver * @see javax.sound.midi.MidiSystem#getReceiver
*/ */
public void close(); void close();
} }

View file

@ -26,72 +26,77 @@
package javax.sound.midi; package javax.sound.midi;
import java.util.Vector; import java.util.Vector;
import com.sun.media.sound.MidiUtils;
/** /**
* A <code>Sequence</code> is a data structure containing musical * A {@code Sequence} is a data structure containing musical information (often
* information (often an entire song or composition) that can be played * an entire song or composition) that can be played back by a {@link Sequencer}
* back by a <code>{@link Sequencer}</code> object. Specifically, the * object. Specifically, the {@code Sequence} contains timing information and
* <code>Sequence</code> contains timing * one or more tracks. Each {@link Track track} consists of a series of MIDI
* information and one or more tracks. Each <code>{@link Track track}</code> consists of a * events (such as note-ons, note-offs, program changes, and meta-events). The
* series of MIDI events (such as note-ons, note-offs, program changes, and meta-events). * sequence's timing information specifies the type of unit that is used to
* The sequence's timing information specifies the type of unit that is used * time-stamp the events in the sequence.
* to time-stamp the events in the sequence.
* <p> * <p>
* A <code>Sequence</code> can be created from a MIDI file by reading the file * A {@code Sequence} can be created from a MIDI file by reading the file into
* into an input stream and invoking one of the <code>getSequence</code> methods of * an input stream and invoking one of the {@code getSequence} methods of
* {@link MidiSystem}. A sequence can also be built from scratch by adding new * {@link MidiSystem}. A sequence can also be built from scratch by adding new
* <code>Tracks</code> to an empty <code>Sequence</code>, and adding * {@code Tracks} to an empty {@code Sequence}, and adding {@link MidiEvent}
* <code>{@link MidiEvent}</code> objects to these <code>Tracks</code>. * objects to these {@code Tracks}.
* *
* @author Kara Kytle
* @see Sequencer#setSequence(java.io.InputStream stream) * @see Sequencer#setSequence(java.io.InputStream stream)
* @see Sequencer#setSequence(Sequence sequence) * @see Sequencer#setSequence(Sequence sequence)
* @see Track#add(MidiEvent) * @see Track#add(MidiEvent)
* @see MidiFileFormat * @see MidiFileFormat
*
* @author Kara Kytle
*/ */
public class Sequence { public class Sequence {
// Timing types // Timing types
/** /**
* The tempo-based timing type, for which the resolution is expressed in pulses (ticks) per quarter note. * The tempo-based timing type, for which the resolution is expressed in
* pulses (ticks) per quarter note.
*
* @see #Sequence(float, int) * @see #Sequence(float, int)
*/ */
public static final float PPQ = 0.0f; public static final float PPQ = 0.0f;
/** /**
* The SMPTE-based timing type with 24 frames per second (resolution is expressed in ticks per frame). * The SMPTE-based timing type with 24 frames per second (resolution is
* expressed in ticks per frame).
*
* @see #Sequence(float, int) * @see #Sequence(float, int)
*/ */
public static final float SMPTE_24 = 24.0f; public static final float SMPTE_24 = 24.0f;
/** /**
* The SMPTE-based timing type with 25 frames per second (resolution is expressed in ticks per frame). * The SMPTE-based timing type with 25 frames per second (resolution is
* expressed in ticks per frame).
*
* @see #Sequence(float, int) * @see #Sequence(float, int)
*/ */
public static final float SMPTE_25 = 25.0f; public static final float SMPTE_25 = 25.0f;
/** /**
* The SMPTE-based timing type with 29.97 frames per second (resolution is expressed in ticks per frame). * The SMPTE-based timing type with 29.97 frames per second (resolution is
* expressed in ticks per frame).
*
* @see #Sequence(float, int) * @see #Sequence(float, int)
*/ */
public static final float SMPTE_30DROP = 29.97f; public static final float SMPTE_30DROP = 29.97f;
/** /**
* The SMPTE-based timing type with 30 frames per second (resolution is expressed in ticks per frame). * The SMPTE-based timing type with 30 frames per second (resolution is
* expressed in ticks per frame).
*
* @see #Sequence(float, int) * @see #Sequence(float, int)
*/ */
public static final float SMPTE_30 = 30.0f; public static final float SMPTE_30 = 30.0f;
// Variables // Variables
/** /**
* The timing division type of the sequence. * The timing division type of the sequence.
*
* @see #PPQ * @see #PPQ
* @see #SMPTE_24 * @see #SMPTE_24
* @see #SMPTE_25 * @see #SMPTE_25
@ -103,33 +108,33 @@ public class Sequence {
/** /**
* The timing resolution of the sequence. * The timing resolution of the sequence.
*
* @see #getResolution * @see #getResolution
*/ */
protected int resolution; protected int resolution;
/** /**
* The MIDI tracks in this sequence. * The MIDI tracks in this sequence.
*
* @see #getTracks * @see #getTracks
*/ */
protected Vector<Track> tracks = new Vector<Track>(); protected Vector<Track> tracks = new Vector<Track>();
/** /**
* Constructs a new MIDI sequence with the specified timing division * Constructs a new MIDI sequence with the specified timing division type
* type and timing resolution. The division type must be one of the * and timing resolution. The division type must be one of the recognized
* recognized MIDI timing types. For tempo-based timing, * MIDI timing types. For tempo-based timing, {@code divisionType} is PPQ
* <code>divisionType</code> is PPQ (pulses per quarter note) and * (pulses per quarter note) and the resolution is specified in ticks per
* the resolution is specified in ticks per beat. For SMTPE timing, * beat. For SMTPE timing, {@code divisionType} specifies the number of
* <code>divisionType</code> specifies the number of frames per * frames per second and the resolution is specified in ticks per frame. The
* second and the resolution is specified in ticks per frame. * sequence will contain no initial tracks. Tracks may be added to or
* The sequence will contain no initial tracks. Tracks may be * removed from the sequence using {@link #createTrack} and
* added to or removed from the sequence using <code>{@link #createTrack}</code> * {@link #deleteTrack}.
* and <code>{@link #deleteTrack}</code>.
* *
* @param divisionType the timing division type (PPQ or one of the SMPTE types) * @param divisionType the timing division type (PPQ or one of the SMPTE
* types)
* @param resolution the timing resolution * @param resolution the timing resolution
* @throws InvalidMidiDataException if <code>divisionType</code> is not valid * @throws InvalidMidiDataException if {@code divisionType} is not valid
*
* @see #PPQ * @see #PPQ
* @see #SMPTE_24 * @see #SMPTE_24
* @see #SMPTE_25 * @see #SMPTE_25
@ -156,27 +161,25 @@ public class Sequence {
this.resolution = resolution; this.resolution = resolution;
} }
/** /**
* Constructs a new MIDI sequence with the specified timing division * Constructs a new MIDI sequence with the specified timing division type,
* type, timing resolution, and number of tracks. The division type must be one of the * timing resolution, and number of tracks. The division type must be one of
* recognized MIDI timing types. For tempo-based timing, * the recognized MIDI timing types. For tempo-based timing,
* <code>divisionType</code> is PPQ (pulses per quarter note) and * {@code divisionType} is PPQ (pulses per quarter note) and the resolution
* the resolution is specified in ticks per beat. For SMTPE timing, * is specified in ticks per beat. For SMTPE timing, {@code divisionType}
* <code>divisionType</code> specifies the number of frames per * specifies the number of frames per second and the resolution is specified
* second and the resolution is specified in ticks per frame. * in ticks per frame. The sequence will be initialized with the number of
* The sequence will be initialized with the number of tracks specified by * tracks specified by {@code numTracks}. These tracks are initially empty
* <code>numTracks</code>. These tracks are initially empty (i.e. * (i.e. they contain only the meta-event End of Track). The tracks may be
* they contain only the meta-event End of Track). * retrieved for editing using the {@link #getTracks} method. Additional
* The tracks may be retrieved for editing using the <code>{@link #getTracks}</code> * tracks may be added, or existing tracks removed, using
* method. Additional tracks may be added, or existing tracks removed, * {@link #createTrack} and {@link #deleteTrack}.
* using <code>{@link #createTrack}</code> and <code>{@link #deleteTrack}</code>.
* *
* @param divisionType the timing division type (PPQ or one of the SMPTE types) * @param divisionType the timing division type (PPQ or one of the SMPTE
* types)
* @param resolution the timing resolution * @param resolution the timing resolution
* @param numTracks the initial number of tracks in the sequence. * @param numTracks the initial number of tracks in the sequence
* @throws InvalidMidiDataException if <code>divisionType</code> is not valid * @throws InvalidMidiDataException if {@code divisionType} is not valid
*
* @see #PPQ * @see #PPQ
* @see #SMPTE_24 * @see #SMPTE_24
* @see #SMPTE_25 * @see #SMPTE_25
@ -206,11 +209,10 @@ public class Sequence {
} }
} }
/** /**
* Obtains the timing division type for this sequence. * Obtains the timing division type for this sequence.
* @return the division type (PPQ or one of the SMPTE types)
* *
* @return the division type (PPQ or one of the SMPTE types)
* @see #PPQ * @see #PPQ
* @see #SMPTE_24 * @see #SMPTE_24
* @see #SMPTE_25 * @see #SMPTE_25
@ -223,11 +225,10 @@ public class Sequence {
return divisionType; return divisionType;
} }
/** /**
* Obtains the timing resolution for this sequence. * Obtains the timing resolution for this sequence. If the sequence's
* If the sequence's division type is PPQ, the resolution is specified in ticks per beat. * division type is PPQ, the resolution is specified in ticks per beat. For
* For SMTPE timing, the resolution is specified in ticks per frame. * SMTPE timing, the resolution is specified in ticks per frame.
* *
* @return the number of ticks per beat (PPQ) or per frame (SMPTE) * @return the number of ticks per beat (PPQ) or per frame (SMPTE)
* @see #getDivisionType * @see #getDivisionType
@ -238,13 +239,13 @@ public class Sequence {
return resolution; return resolution;
} }
/** /**
* Creates a new, initially empty track as part of this sequence. * Creates a new, initially empty track as part of this sequence. The track
* The track initially contains the meta-event End of Track. * initially contains the meta-event End of Track. The newly created track
* The newly created track is returned. All tracks in the sequence * is returned. All tracks in the sequence may be retrieved using
* may be retrieved using <code>{@link #getTracks}</code>. Tracks may be * {@link #getTracks}. Tracks may be removed from the sequence using
* removed from the sequence using <code>{@link #deleteTrack}</code>. * {@link #deleteTrack}.
*
* @return the newly created track * @return the newly created track
*/ */
public Track createTrack() { public Track createTrack() {
@ -255,13 +256,12 @@ public class Sequence {
return track; return track;
} }
/** /**
* Removes the specified track from the sequence. * Removes the specified track from the sequence.
* @param track the track to remove
* @return <code>true</code> if the track existed in the track and was removed,
* otherwise <code>false</code>.
* *
* @param track the track to remove
* @return {@code true} if the track existed in the track and was removed,
* otherwise {@code false}
* @see #createTrack * @see #createTrack
* @see #getTracks * @see #getTracks
*/ */
@ -273,12 +273,11 @@ public class Sequence {
} }
} }
/** /**
* Obtains an array containing all the tracks in this sequence. * Obtains an array containing all the tracks in this sequence. If the
* If the sequence contains no tracks, an array of length 0 is returned. * sequence contains no tracks, an array of length 0 is returned.
* @return the array of tracks
* *
* @return the array of tracks
* @see #createTrack * @see #createTrack
* @see #deleteTrack * @see #deleteTrack
*/ */
@ -287,22 +286,20 @@ public class Sequence {
return tracks.toArray(new Track[tracks.size()]); return tracks.toArray(new Track[tracks.size()]);
} }
/** /**
* Obtains the duration of this sequence, expressed in microseconds. * Obtains the duration of this sequence, expressed in microseconds.
* @return this sequence's duration in microseconds. *
* @return this sequence's duration in microseconds
*/ */
public long getMicrosecondLength() { public long getMicrosecondLength() {
return com.sun.media.sound.MidiUtils.tick2microsecond(this, getTickLength(), null); return com.sun.media.sound.MidiUtils.tick2microsecond(this, getTickLength(), null);
} }
/** /**
* Obtains the duration of this sequence, expressed in MIDI ticks. * Obtains the duration of this sequence, expressed in MIDI ticks.
* *
* @return this sequence's length in ticks * @return this sequence's length in ticks
*
* @see #getMicrosecondLength * @see #getMicrosecondLength
*/ */
public long getTickLength() { public long getTickLength() {
@ -321,15 +318,12 @@ public class Sequence {
} }
} }
/** /**
* Obtains a list of patches referenced in this sequence. * Obtains a list of patches referenced in this sequence. This patch list
* This patch list may be used to load the required * may be used to load the required {@link Instrument} objects into a
* <code>{@link Instrument}</code> objects * {@link Synthesizer}.
* into a <code>{@link Synthesizer}</code>.
*
* @return an array of <code>{@link Patch}</code> objects used in this sequence
* *
* @return an array of {@link Patch} objects used in this sequence
* @see Synthesizer#loadInstruments(Soundbank, Patch[]) * @see Synthesizer#loadInstruments(Soundbank, Patch[])
*/ */
public Patch[] getPatchList() { public Patch[] getPatchList() {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,156 +26,158 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* A <code>ShortMessage</code> contains a MIDI message that has at most * A {@code ShortMessage} contains a MIDI message that has at most two data
* two data bytes following its status byte. The types of MIDI message * bytes following its status byte. The types of MIDI message that satisfy this
* that satisfy this criterion are channel voice, channel mode, system common, * criterion are channel voice, channel mode, system common, and system
* and system real-time--in other words, everything except system exclusive * real-time--in other words, everything except system exclusive and
* and meta-events. The <code>ShortMessage</code> class provides methods * meta-events. The {@code ShortMessage} class provides methods for getting and
* for getting and setting the contents of the MIDI message. * setting the contents of the MIDI message.
* <p> * <p>
* A number of <code>ShortMessage</code> methods have integer parameters by which * A number of {@code ShortMessage} methods have integer parameters by which you
* you specify a MIDI status or data byte. If you know the numeric value, you * specify a MIDI status or data byte. If you know the numeric value, you can
* can express it directly. For system common and system real-time messages, * express it directly. For system common and system real-time messages, you can
* you can often use the corresponding fields of <code>ShortMessage</code>, such as * often use the corresponding fields of {@code ShortMessage}, such as
* {@link #SYSTEM_RESET SYSTEM_RESET}. For channel messages, * {@link #SYSTEM_RESET SYSTEM_RESET}. For channel messages, the upper four bits
* the upper four bits of the status byte are specified by a command value and * of the status byte are specified by a command value and the lower four bits
* the lower four bits are specified by a MIDI channel number. To * are specified by a MIDI channel number. To convert incoming MIDI data bytes
* convert incoming MIDI data bytes that are in the form of Java's signed bytes, * that are in the form of Java's signed bytes, you can use the
* you can use the <A HREF="MidiMessage.html#integersVsBytes">conversion code</A> * <a href="MidiMessage.html#integersVsBytes">conversion code</a> given in the
* given in the <code>{@link MidiMessage}</code> class description. * {@link MidiMessage} class description.
*
* @see SysexMessage
* @see MetaMessage
* *
* @author David Rivas * @author David Rivas
* @author Kara Kytle * @author Kara Kytle
* @author Florian Bomers * @author Florian Bomers
* @see SysexMessage
* @see MetaMessage
*/ */
public class ShortMessage extends MidiMessage { public class ShortMessage extends MidiMessage {
// Status byte defines // Status byte defines
// System common messages // System common messages
/** /**
* Status byte for MIDI Time Code Quarter Frame message (0xF1, or 241). * Status byte for MIDI Time Code Quarter Frame message (0xF1, or 241).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int MIDI_TIME_CODE = 0xF1; // 241 public static final int MIDI_TIME_CODE = 0xF1; // 241
/** /**
* Status byte for Song Position Pointer message (0xF2, or 242). * Status byte for Song Position Pointer message (0xF2, or 242).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int SONG_POSITION_POINTER = 0xF2; // 242 public static final int SONG_POSITION_POINTER = 0xF2; // 242
/** /**
* Status byte for MIDI Song Select message (0xF3, or 243). * Status byte for MIDI Song Select message (0xF3, or 243).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int SONG_SELECT = 0xF3; // 243 public static final int SONG_SELECT = 0xF3; // 243
/** /**
* Status byte for Tune Request message (0xF6, or 246). * Status byte for Tune Request message (0xF6, or 246).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int TUNE_REQUEST = 0xF6; // 246 public static final int TUNE_REQUEST = 0xF6; // 246
/** /**
* Status byte for End of System Exclusive message (0xF7, or 247). * Status byte for End of System Exclusive message (0xF7, or 247).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int END_OF_EXCLUSIVE = 0xF7; // 247 public static final int END_OF_EXCLUSIVE = 0xF7; // 247
// System real-time messages // System real-time messages
/** /**
* Status byte for Timing Clock message (0xF8, or 248). * Status byte for Timing Clock message (0xF8, or 248).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int TIMING_CLOCK = 0xF8; // 248 public static final int TIMING_CLOCK = 0xF8; // 248
/** /**
* Status byte for Start message (0xFA, or 250). * Status byte for Start message (0xFA, or 250).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int START = 0xFA; // 250 public static final int START = 0xFA; // 250
/** /**
* Status byte for Continue message (0xFB, or 251). * Status byte for Continue message (0xFB, or 251).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int CONTINUE = 0xFB; // 251 public static final int CONTINUE = 0xFB; // 251
/** /**
* Status byte for Stop message (0xFC, or 252). * Status byte for Stop message (0xFC, or 252).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int STOP = 0xFC; //252 public static final int STOP = 0xFC; //252
/** /**
* Status byte for Active Sensing message (0xFE, or 254). * Status byte for Active Sensing message (0xFE, or 254).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int ACTIVE_SENSING = 0xFE; // 254 public static final int ACTIVE_SENSING = 0xFE; // 254
/** /**
* Status byte for System Reset message (0xFF, or 255). * Status byte for System Reset message (0xFF, or 255).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int SYSTEM_RESET = 0xFF; // 255 public static final int SYSTEM_RESET = 0xFF; // 255
// Channel voice message upper nibble defines // Channel voice message upper nibble defines
/** /**
* Command value for Note Off message (0x80, or 128) * Command value for Note Off message (0x80, or 128).
*/ */
public static final int NOTE_OFF = 0x80; // 128 public static final int NOTE_OFF = 0x80; // 128
/** /**
* Command value for Note On message (0x90, or 144) * Command value for Note On message (0x90, or 144).
*/ */
public static final int NOTE_ON = 0x90; // 144 public static final int NOTE_ON = 0x90; // 144
/** /**
* Command value for Polyphonic Key Pressure (Aftertouch) message (0xA0, or 160) * Command value for Polyphonic Key Pressure (Aftertouch) message (0xA0, or
* 160).
*/ */
public static final int POLY_PRESSURE = 0xA0; // 160 public static final int POLY_PRESSURE = 0xA0; // 160
/** /**
* Command value for Control Change message (0xB0, or 176) * Command value for Control Change message (0xB0, or 176).
*/ */
public static final int CONTROL_CHANGE = 0xB0; // 176 public static final int CONTROL_CHANGE = 0xB0; // 176
/** /**
* Command value for Program Change message (0xC0, or 192) * Command value for Program Change message (0xC0, or 192).
*/ */
public static final int PROGRAM_CHANGE = 0xC0; // 192 public static final int PROGRAM_CHANGE = 0xC0; // 192
/** /**
* Command value for Channel Pressure (Aftertouch) message (0xD0, or 208) * Command value for Channel Pressure (Aftertouch) message (0xD0, or 208).
*/ */
public static final int CHANNEL_PRESSURE = 0xD0; // 208 public static final int CHANNEL_PRESSURE = 0xD0; // 208
/** /**
* Command value for Pitch Bend message (0xE0, or 224) * Command value for Pitch Bend message (0xE0, or 224).
*/ */
public static final int PITCH_BEND = 0xE0; // 224 public static final int PITCH_BEND = 0xE0; // 224
// Instance variables
/** /**
* Constructs a new <code>ShortMessage</code>. The * Constructs a new {@code ShortMessage}. The contents of the new message
* contents of the new message are guaranteed to specify * are guaranteed to specify a valid MIDI message. Subsequently, you may set
* a valid MIDI message. Subsequently, you may set the * the contents of the message using one of the {@code setMessage} methods.
* contents of the message using one of the <code>setMessage</code> *
* methods.
* @see #setMessage * @see #setMessage
*/ */
public ShortMessage() { public ShortMessage() {
@ -188,14 +190,13 @@ public class ShortMessage extends MidiMessage {
} }
/** /**
* Constructs a new {@code ShortMessage} which represents a MIDI * Constructs a new {@code ShortMessage} which represents a MIDI message
* message that takes no data bytes. * that takes no data bytes. The contents of the message can be changed by
* The contents of the message can be changed by using one of * using one of the {@code setMessage} methods.
* the {@code setMessage} methods.
* *
* @param status the MIDI status byte * @param status the MIDI status byte
* @throws InvalidMidiDataException if {@code status} does not specify * @throws InvalidMidiDataException if {@code status} does not specify a
* a valid MIDI status byte for a message that requires no data bytes * valid MIDI status byte for a message that requires no data bytes
* @see #setMessage(int) * @see #setMessage(int)
* @see #setMessage(int, int, int) * @see #setMessage(int, int, int)
* @see #setMessage(int, int, int, int) * @see #setMessage(int, int, int, int)
@ -210,10 +211,9 @@ public class ShortMessage extends MidiMessage {
/** /**
* Constructs a new {@code ShortMessage} which represents a MIDI message * Constructs a new {@code ShortMessage} which represents a MIDI message
* that takes up to two data bytes. If the message only takes one data byte, * that takes up to two data bytes. If the message only takes one data byte,
* the second data byte is ignored. If the message does not take * the second data byte is ignored. If the message does not take any data
* any data bytes, both data bytes are ignored. * bytes, both data bytes are ignored. The contents of the message can be
* The contents of the message can be changed by using one of * changed by using one of the {@code setMessage} methods.
* the {@code setMessage} methods.
* *
* @param status the MIDI status byte * @param status the MIDI status byte
* @param data1 the first data byte * @param data1 the first data byte
@ -235,20 +235,19 @@ public class ShortMessage extends MidiMessage {
} }
/** /**
* Constructs a new {@code ShortMessage} which represents a channel * Constructs a new {@code ShortMessage} which represents a channel MIDI
* MIDI message that takes up to two data bytes. If the message only takes * message that takes up to two data bytes. If the message only takes one
* one data byte, the second data byte is ignored. If the message does not * data byte, the second data byte is ignored. If the message does not take
* take any data bytes, both data bytes are ignored. * any data bytes, both data bytes are ignored. The contents of the message
* The contents of the message can be changed by using one of * can be changed by using one of the {@code setMessage} methods.
* the {@code setMessage} methods.
* *
* @param command the MIDI command represented by this message * @param command the MIDI command represented by this message
* @param channel the channel associated with the message * @param channel the channel associated with the message
* @param data1 the first data byte * @param data1 the first data byte
* @param data2 the second data byte * @param data2 the second data byte
* @throws InvalidMidiDataException if the command value, channel value * @throws InvalidMidiDataException if the command value, channel value or
* or all data bytes belonging to the message do not specify * all data bytes belonging to the message do not specify a valid
* a valid MIDI message * MIDI message
* @see #setMessage(int) * @see #setMessage(int)
* @see #setMessage(int, int, int) * @see #setMessage(int, int, int)
* @see #setMessage(int, int, int, int) * @see #setMessage(int, int, int, int)
@ -264,12 +263,11 @@ public class ShortMessage extends MidiMessage {
setMessage(command, channel, data1, data2); setMessage(command, channel, data1, data2);
} }
/** /**
* Constructs a new <code>ShortMessage</code>. * Constructs a new {@code ShortMessage}.
* @param data an array of bytes containing the complete message. *
* The message data may be changed using the <code>setMessage</code> * @param data an array of bytes containing the complete message. The
* method. * message data may be changed using the {@code setMessage} method.
* @see #setMessage * @see #setMessage
*/ */
// $$fb this should throw an Exception in case of an illegal message! // $$fb this should throw an Exception in case of an illegal message!
@ -279,12 +277,12 @@ public class ShortMessage extends MidiMessage {
super(data); super(data);
} }
/** /**
* Sets the parameters for a MIDI message that takes no data bytes. * Sets the parameters for a MIDI message that takes no data bytes.
*
* @param status the MIDI status byte * @param status the MIDI status byte
* @throws InvalidMidiDataException if <code>status</code> does not * @throws InvalidMidiDataException if {@code status} does not specify a
* specify a valid MIDI status byte for a message that requires no data bytes. * valid MIDI status byte for a message that requires no data bytes
* @see #setMessage(int, int, int) * @see #setMessage(int, int, int)
* @see #setMessage(int, int, int, int) * @see #setMessage(int, int, int, int)
*/ */
@ -297,19 +295,17 @@ public class ShortMessage extends MidiMessage {
setMessage(status, 0, 0); setMessage(status, 0, 0);
} }
/** /**
* Sets the parameters for a MIDI message that takes one or two data * Sets the parameters for a MIDI message that takes one or two data bytes.
* bytes. If the message takes only one data byte, the second data * If the message takes only one data byte, the second data byte is ignored;
* byte is ignored; if the message does not take any data bytes, both * if the message does not take any data bytes, both data bytes are ignored.
* data bytes are ignored.
* *
* @param status the MIDI status byte * @param status the MIDI status byte
* @param data1 the first data byte * @param data1 the first data byte
* @param data2 the second data byte * @param data2 the second data byte
* @throws InvalidMidiDataException if the * @throws InvalidMidiDataException if the the status byte, or all data
* the status byte, or all data bytes belonging to the message, do * bytes belonging to the message, do not specify a valid MIDI
* not specify a valid MIDI message. * message
* @see #setMessage(int, int, int, int) * @see #setMessage(int, int, int, int)
* @see #setMessage(int) * @see #setMessage(int)
*/ */
@ -345,22 +341,18 @@ public class ShortMessage extends MidiMessage {
} }
} }
/** /**
* Sets the short message parameters for a channel message * Sets the short message parameters for a channel message which takes up to
* which takes up to two data bytes. If the message only * two data bytes. If the message only takes one data byte, the second data
* takes one data byte, the second data byte is ignored; if * byte is ignored; if the message does not take any data bytes, both data
* the message does not take any data bytes, both data bytes * bytes are ignored.
* are ignored.
* *
* @param command the MIDI command represented by this message * @param command the MIDI command represented by this message
* @param channel the channel associated with the message * @param channel the channel associated with the message
* @param data1 the first data byte * @param data1 the first data byte
* @param data2 the second data byte * @param data2 the second data byte
* @throws InvalidMidiDataException if the * @throws InvalidMidiDataException if the status byte or all data bytes
* status byte or all data bytes belonging to the message, do * belonging to the message, do not specify a valid MIDI message
* not specify a valid MIDI message
*
* @see #setMessage(int, int, int) * @see #setMessage(int, int, int)
* @see #setMessage(int) * @see #setMessage(int)
* @see #getCommand * @see #getCommand
@ -379,12 +371,12 @@ public class ShortMessage extends MidiMessage {
setMessage((command & 0xF0) | (channel & 0x0F), data1, data2); setMessage((command & 0xF0) | (channel & 0x0F), data1, data2);
} }
/** /**
* Obtains the MIDI channel associated with this event. This method * Obtains the MIDI channel associated with this event. This method assumes
* assumes that the event is a MIDI channel message; if not, the return * that the event is a MIDI channel message; if not, the return value will
* value will not be meaningful. * not be meaningful.
* @return MIDI channel associated with the message. *
* @return MIDI channel associated with the message
* @see #setMessage(int, int, int, int) * @see #setMessage(int, int, int, int)
*/ */
public int getChannel() { public int getChannel() {
@ -392,11 +384,11 @@ public class ShortMessage extends MidiMessage {
return (getStatus() & 0x0F); return (getStatus() & 0x0F);
} }
/** /**
* Obtains the MIDI command associated with this event. This method * Obtains the MIDI command associated with this event. This method assumes
* assumes that the event is a MIDI channel message; if not, the return * that the event is a MIDI channel message; if not, the return value will
* value will not be meaningful. * not be meaningful.
*
* @return the MIDI command associated with this event * @return the MIDI command associated with this event
* @see #setMessage(int, int, int, int) * @see #setMessage(int, int, int, int)
*/ */
@ -405,10 +397,10 @@ public class ShortMessage extends MidiMessage {
return (getStatus() & 0xF0); return (getStatus() & 0xF0);
} }
/** /**
* Obtains the first data byte in the message. * Obtains the first data byte in the message.
* @return the value of the <code>data1</code> field *
* @return the value of the {@code data1} field
* @see #setMessage(int, int, int) * @see #setMessage(int, int, int)
*/ */
public int getData1() { public int getData1() {
@ -418,10 +410,10 @@ public class ShortMessage extends MidiMessage {
return 0; return 0;
} }
/** /**
* Obtains the second data byte in the message. * Obtains the second data byte in the message.
* @return the value of the <code>data2</code> field *
* @return the value of the {@code data2} field
* @see #setMessage(int, int, int) * @see #setMessage(int, int, int)
*/ */
public int getData2() { public int getData2() {
@ -431,11 +423,11 @@ public class ShortMessage extends MidiMessage {
return 0; return 0;
} }
/** /**
* Creates a new object of the same class and with the same contents * Creates a new object of the same class and with the same contents as this
* as this object. * object.
* @return a clone of this instance. *
* @return a clone of this instance
*/ */
public Object clone() { public Object clone() {
byte[] newData = new byte[length]; byte[] newData = new byte[length];
@ -445,15 +437,15 @@ public class ShortMessage extends MidiMessage {
return msg; return msg;
} }
/** /**
* Retrieves the number of data bytes associated with a particular * Retrieves the number of data bytes associated with a particular status
* status byte value. * byte value.
* @param status status byte value, which must represent a short MIDI message *
* @param status status byte value, which must represent a short MIDI
* message
* @return data length in bytes (0, 1, or 2) * @return data length in bytes (0, 1, or 2)
* @throws InvalidMidiDataException if the * @throws InvalidMidiDataException if the {@code status} argument does not
* <code>status</code> argument does not represent the status byte for any * represent the status byte for any short message
* short message
*/ */
protected final int getDataLength(int status) throws InvalidMidiDataException { protected final int getDataLength(int status) throws InvalidMidiDataException {
// system common and system real-time messages // system common and system real-time messages

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,109 +25,101 @@
package javax.sound.midi; package javax.sound.midi;
import java.net.URL;
/** /**
* A <code>Soundbank</code> contains a set of <code>Instruments</code> * A {@code Soundbank} contains a set of {@code Instruments} that can be loaded
* that can be loaded into a <code>Synthesizer</code>. * into a {@code Synthesizer}. Note that a Java Sound {@code Soundbank} is
* Note that a Java Sound <code>Soundbank</code> is different from a MIDI bank. * different from a MIDI bank. MIDI permits up to 16383 banks, each containing
* MIDI permits up to 16383 banks, each containing up to 128 instruments * up to 128 instruments (also sometimes called programs, patches, or timbres).
* (also sometimes called programs, patches, or timbres). * However, a {@code Soundbank} can contain 16383 times 128 instruments, because
* However, a <code>Soundbank</code> can contain 16383 times 128 instruments, * the instruments within a {@code Soundbank} are indexed by both a MIDI program
* because the instruments within a <code>Soundbank</code> are indexed by both * number and a MIDI bank number (via a {@code Patch} object). Thus, a
* a MIDI program number and a MIDI bank number (via a <code>Patch</code> * {@code Soundbank} can be thought of as a collection of MIDI banks.
* object). Thus, a <code>Soundbank</code> can be thought of as a collection
* of MIDI banks.
* <p> * <p>
* <code>Soundbank</code> includes methods that return <code>String</code> * {@code Soundbank} includes methods that return {@code String} objects
* objects containing the sound bank's name, manufacturer, version number, and * containing the sound bank's name, manufacturer, version number, and
* description. The precise content and format of these strings is left * description. The precise content and format of these strings is left to the
* to the implementor. * implementor.
* <p> * <p>
* Different synthesizers use a variety of synthesis techniques. A common * Different synthesizers use a variety of synthesis techniques. A common one is
* one is wavetable synthesis, in which a segment of recorded sound is * wavetable synthesis, in which a segment of recorded sound is played back,
* played back, often with looping and pitch change. The Downloadable Sound * often with looping and pitch change. The Downloadable Sound (DLS) format uses
* (DLS) format uses segments of recorded sound, as does the Headspace Engine. * segments of recorded sound, as does the Headspace Engine. {@code Soundbanks}
* <code>Soundbanks</code> and <code>Instruments</code> that are based on * and {@code Instruments} that are based on wavetable synthesis (or other uses
* wavetable synthesis (or other uses of stored sound recordings) should * of stored sound recordings) should typically implement the
* typically implement the <code>getResources()</code> * {@code getResources()} method to provide access to these recorded segments.
* method to provide access to these recorded segments. This is optional, * This is optional, however; the method can return an zero-length array if the
* however; the method can return an zero-length array if the synthesis technique * synthesis technique doesn't use sampled sound (FM synthesis and physical
* doesn't use sampled sound (FM synthesis and physical modeling are examples * modeling are examples of such techniques), or if it does but the implementor
* of such techniques), or if it does but the implementor chooses not to make the * chooses not to make the samples accessible.
* samples accessible.
* *
* @author David Rivas
* @author Kara Kytle
* @see Synthesizer#getDefaultSoundbank * @see Synthesizer#getDefaultSoundbank
* @see Synthesizer#isSoundbankSupported * @see Synthesizer#isSoundbankSupported
* @see Synthesizer#loadInstruments(Soundbank, Patch[]) * @see Synthesizer#loadInstruments(Soundbank, Patch[])
* @see Patch * @see Patch
* @see Instrument * @see Instrument
* @see SoundbankResource * @see SoundbankResource
*
* @author David Rivas
* @author Kara Kytle
*/ */
public interface Soundbank { public interface Soundbank {
/** /**
* Obtains the name of the sound bank. * Obtains the name of the sound bank.
* @return a <code>String</code> naming the sound bank *
* @return a {@code String} naming the sound bank
*/ */
public String getName(); String getName();
/** /**
* Obtains the version string for the sound bank. * Obtains the version string for the sound bank.
* @return a <code>String</code> that indicates the sound bank's version *
* @return a {@code String} that indicates the sound bank's version
*/ */
public String getVersion(); String getVersion();
/** /**
* Obtains a <code>string</code> naming the company that provides the * Obtains a {@code string} naming the company that provides the sound bank.
* sound bank *
* @return the vendor string * @return the vendor string
*/ */
public String getVendor(); String getVendor();
/** /**
* Obtains a textual description of the sound bank, suitable for display. * Obtains a textual description of the sound bank, suitable for display.
* @return a <code>String</code> that describes the sound bank *
* @return a {@code String} that describes the sound bank
*/ */
public String getDescription(); String getDescription();
/** /**
* Extracts a list of non-Instrument resources contained in the sound bank. * Extracts a list of non-Instrument resources contained in the sound bank.
* @return an array of resources, excluding instruments. If the sound bank contains *
* no resources (other than instruments), returns an array of length 0. * @return an array of resources, excluding instruments. If the sound bank
* contains no resources (other than instruments), returns an array
* of length 0.
*/ */
public SoundbankResource[] getResources(); SoundbankResource[] getResources();
/** /**
* Obtains a list of instruments contained in this sound bank. * Obtains a list of instruments contained in this sound bank.
* @return an array of the <code>Instruments</code> in this
* <code>SoundBank</code>
* If the sound bank contains no instruments, returns an array of length 0.
* *
* @return an array of the {@code Instruments} in this {@code SoundBank}. If
* the sound bank contains no instruments, returns an array of
* length 0.
* @see Synthesizer#getLoadedInstruments * @see Synthesizer#getLoadedInstruments
* @see #getInstrument(Patch) * @see #getInstrument(Patch)
*/ */
public Instrument[] getInstruments(); Instrument[] getInstruments();
/** /**
* Obtains an <code>Instrument</code> from the given <code>Patch</code>. * Obtains an {@code Instrument} from the given {@code Patch}.
* @param patch a <code>Patch</code> object specifying the bank index
* and program change number
* @return the requested instrument, or <code>null</code> if the
* sound bank doesn't contain that instrument
* *
* @param patch a {@code Patch} object specifying the bank index and
* program change number
* @return the requested instrument, or {@code null} if the sound bank
* doesn't contain that instrument
* @see #getInstruments * @see #getInstruments
* @see Synthesizer#loadInstruments(Soundbank, Patch[]) * @see Synthesizer#loadInstruments(Soundbank, Patch[])
*/ */
public Instrument getInstrument(Patch patch); Instrument getInstrument(Patch patch);
} }

View file

@ -25,81 +25,72 @@
package javax.sound.midi; package javax.sound.midi;
import javax.sound.sampled.AudioInputStream;
/** /**
* A <code>SoundbankResource</code> represents any audio resource stored * A {@code SoundbankResource} represents any audio resource stored in a
* in a <code>{@link Soundbank}</code>. Common soundbank resources include: * {@link Soundbank}. Common soundbank resources include:
* <ul> * <ul>
* <li>Instruments. An instrument may be specified in a variety of * <li>Instruments. An instrument may be specified in a variety of ways.
* ways. However, all soundbanks have some mechanism for defining * However, all soundbanks have some mechanism for defining instruments. In
* instruments. In doing so, they may reference other resources * doing so, they may reference other resources stored in the soundbank. Each
* stored in the soundbank. Each instrument has a <code>Patch</code> * instrument has a {@code Patch} which specifies the MIDI program and bank by
* which specifies the MIDI program and bank by which it may be * which it may be referenced in MIDI messages. Instrument information may be
* referenced in MIDI messages. Instrument information may be * stored in {@link Instrument} objects.</li>
* stored in <code>{@link Instrument}</code> objects. * <li>Audio samples. A sample typically is a sampled audio waveform which
* <li>Audio samples. A sample typically is a sampled audio waveform * contains a short sound recording whose duration is a fraction of a second, or
* which contains a short sound recording whose duration is a fraction of * at most a few seconds. These audio samples may be used by a
* a second, or at most a few seconds. These audio samples may be * {@link Synthesizer} to synthesize sound in response to MIDI commands, or
* used by a <code>{@link Synthesizer}</code> to synthesize sound in response to MIDI * extracted for use by an application. (The terminology reflects musicians' use
* commands, or extracted for use by an application. * of the word "sample" to refer collectively to a series of contiguous audio
* (The terminology reflects musicians' use of the word "sample" to refer * samples or frames, rather than to a single, instantaneous sample.) The data
* collectively to a series of contiguous audio samples or frames, rather than * class for an audio sample will be an object that encapsulates the audio
* to a single, instantaneous sample.) * sample data itself and information about how to interpret it (the format of
* The data class for an audio sample will be an object * the audio data), such as an {@link AudioInputStream}.</li>
* that encapsulates the audio sample data itself and information * <li>Embedded sequences. A sound bank may contain built-in song data stored in
* about how to interpret it (the format of the audio data), such * a data object such as a {@link Sequence}.</li>
* as an <code>{@link javax.sound.sampled.AudioInputStream}</code>. </li>
* <li>Embedded sequences. A sound bank may contain built-in
* song data stored in a data object such as a <code>{@link Sequence}</code>.
* </ul> * </ul>
* <p> * Synthesizers that use wavetable synthesis or related techniques play back the
* Synthesizers that use wavetable synthesis or related * audio in a sample when synthesizing notes, often when emulating the
* techniques play back the audio in a sample when * real-world instrument that was originally recorded. However, there is not
* synthesizing notes, often when emulating the real-world instrument that * necessarily a one-to-one correspondence between the {@code Instruments} and
* was originally recorded. However, there is not necessarily a one-to-one * samples in a {@code Soundbank}. A single {@code Instrument} can use multiple
* correspondence between the <code>Instruments</code> and samples * SoundbankResources (typically for notes of dissimilar pitch or brightness).
* in a <code>Soundbank</code>. A single <code>Instrument</code> can use * Also, more than one {@code Instrument} can use the same sample.
* multiple SoundbankResources (typically for notes of dissimilar pitch or
* brightness). Also, more than one <code>Instrument</code> can use the same
* sample.
* *
* @author Kara Kytle * @author Kara Kytle
*/ */
public abstract class SoundbankResource { public abstract class SoundbankResource {
/** /**
* The sound bank that contains the <code>SoundbankResources</code> * The sound bank that contains the {@code SoundbankResources}.
*/ */
private final Soundbank soundBank; private final Soundbank soundBank;
/** /**
* The name of the <code>SoundbankResource</code> * The name of the {@code SoundbankResource}.
*/ */
private final String name; private final String name;
/** /**
* The class used to represent the sample's data. * The class used to represent the sample's data.
*/ */
private final Class<?> dataClass; private final Class<?> dataClass;
/** /**
* The wavetable index. * The wavetable index.
*/ */
//private final int index; //private final int index;
/** /**
* Constructs a new <code>SoundbankResource</code> from the given sound bank * Constructs a new {@code SoundbankResource} from the given sound bank and
* and wavetable index. (Setting the <code>SoundbankResource's</code> name, * wavetable index. (Setting the {@code SoundbankResource's} name, sampled
* sampled audio data, and instruments is a subclass responsibility.) * audio data, and instruments is a subclass responsibility.)
* @param soundBank the sound bank containing this <code>SoundbankResource</code> *
* @param soundBank the sound bank containing this
* {@code SoundbankResource}
* @param name the name of the sample * @param name the name of the sample
* @param dataClass the class used to represent the sample's data * @param dataClass the class used to represent the sample's data
*
* @see #getSoundbank * @see #getSoundbank
* @see #getName * @see #getName
* @see #getDataClass * @see #getDataClass
@ -112,65 +103,65 @@ public abstract class SoundbankResource {
this.dataClass = dataClass; this.dataClass = dataClass;
} }
/** /**
* Obtains the sound bank that contains this <code>SoundbankResource</code>. * Obtains the sound bank that contains this {@code SoundbankResource}.
* @return the sound bank in which this <code>SoundbankResource</code> is stored *
* @return the sound bank in which this {@code SoundbankResource} is stored
*/ */
public Soundbank getSoundbank() { public Soundbank getSoundbank() {
return soundBank; return soundBank;
} }
/** /**
* Obtains the name of the resource. This should generally be a string * Obtains the name of the resource. This should generally be a string
* descriptive of the resource. * descriptive of the resource.
*
* @return the instrument's name * @return the instrument's name
*/ */
public String getName() { public String getName() {
return name; return name;
} }
/** /**
* Obtains the class used by this sample to represent its data. * Obtains the class used by this sample to represent its data. The object
* The object returned by <code>getData</code> will be of this * returned by {@code getData} will be of this class. If this
* class. If this <code>SoundbankResource</code> object does not support * {@code SoundbankResource} object does not support direct access to its
* direct access to its data, returns <code>null</code>. * data, returns {@code null}.
* @return the class used to represent the sample's data, or *
* null if the data is not accessible * @return the class used to represent the sample's data, or null if the
* data is not accessible
*/ */
public Class<?> getDataClass() { public Class<?> getDataClass() {
return dataClass; return dataClass;
} }
/** /**
* Obtains the sampled audio that is stored in this <code>SoundbankResource</code>. * Obtains the sampled audio that is stored in this
* The type of object returned depends on the implementation of the * {@code SoundbankResource}. The type of object returned depends on the
* concrete class, and may be queried using <code>getDataClass</code>. * implementation of the concrete class, and may be queried using
* {@code getDataClass}.
*
* @return an object containing the sampled audio data * @return an object containing the sampled audio data
* @see #getDataClass * @see #getDataClass
*/ */
public abstract Object getData(); public abstract Object getData();
/** /**
* Obtains the index of this <code>SoundbankResource</code> into the * Obtains the index of this {@code SoundbankResource} into the
* <code>Soundbank's</code> set of <code>SoundbankResources</code>. * {@code Soundbank's} set of {@code SoundbankResources}.
*
* @return the wavetable index * @return the wavetable index
*/ */
//public int getIndex() { //public int getIndex() {
// return index; // return index;
//} //}
/** /**
* Obtains a list of the instruments in the sound bank that use the * Obtains a list of the instruments in the sound bank that use the
* <code>SoundbankResource</code> for sound synthesis. * {@code SoundbankResource} for sound synthesis.
* @return an array of <code>Instruments</code> that reference this
* <code>SoundbankResource</code>
* *
* @return an array of {@code Instruments} that reference this
* {@code SoundbankResource}
* @see Instrument#getSamples * @see Instrument#getSamples
*/ */
//public abstract Instrument[] getInstruments(); //public abstract Instrument[] getInstruments();

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,46 +25,43 @@
package javax.sound.midi; package javax.sound.midi;
import javax.sound.sampled.Control;
/** /**
* A <code>Synthesizer</code> generates sound. This usually happens when one of * A {@code Synthesizer} generates sound. This usually happens when one of the
* the <code>Synthesizer</code>'s {@link MidiChannel} objects receives a * {@code Synthesizer}'s {@link MidiChannel} objects receives a
* {@link MidiChannel#noteOn(int, int) noteOn} message, either * {@link MidiChannel#noteOn(int, int) noteOn} message, either directly or via
* directly or via the <code>Synthesizer</code> object. * the {@code Synthesizer} object. Many {@code Synthesizer}s support
* Many <code>Synthesizer</code>s support <code>Receivers</code>, through which * {@code Receivers}, through which MIDI events can be delivered to the
* MIDI events can be delivered to the <code>Synthesizer</code>. * {@code Synthesizer}. In such cases, the {@code Synthesizer} typically
* In such cases, the <code>Synthesizer</code> typically responds by sending * responds by sending a corresponding message to the appropriate
* a corresponding message to the appropriate <code>MidiChannel</code>, or by * {@code MidiChannel}, or by processing the event itself if the event isn't one
* processing the event itself if the event isn't one of the MIDI channel * of the MIDI channel messages.
* messages.
* <p> * <p>
* The <code>Synthesizer</code> interface includes methods for loading and * The {@code Synthesizer} interface includes methods for loading and unloading
* unloading instruments from soundbanks. An instrument is a specification for synthesizing a * instruments from soundbanks. An instrument is a specification for
* certain type of sound, whether that sound emulates a traditional instrument or is * synthesizing a certain type of sound, whether that sound emulates a
* some kind of sound effect or other imaginary sound. A soundbank is a collection of instruments, organized * traditional instrument or is some kind of sound effect or other imaginary
* by bank and program number (via the instrument's <code>Patch</code> object). * sound. A soundbank is a collection of instruments, organized by bank and
* Different <code>Synthesizer</code> classes might implement different sound-synthesis * program number (via the instrument's {@code Patch} object). Different
* techniques, meaning that some instruments and not others might be compatible with a * {@code Synthesizer} classes might implement different sound-synthesis
* given synthesizer. * techniques, meaning that some instruments and not others might be compatible
* Also, synthesizers may have a limited amount of memory for instruments, meaning * with a given synthesizer. Also, synthesizers may have a limited amount of
* that not every soundbank and instrument can be used by every synthesizer, even if * memory for instruments, meaning that not every soundbank and instrument can
* the synthesis technique is compatible. * be used by every synthesizer, even if the synthesis technique is compatible.
* To see whether the instruments from * To see whether the instruments from a certain soundbank can be played by a
* a certain soundbank can be played by a given synthesizer, invoke the * given synthesizer, invoke the
* {@link #isSoundbankSupported(Soundbank) isSoundbankSupported} method of * {@link #isSoundbankSupported(Soundbank) isSoundbankSupported}
* <code>Synthesizer</code>. * method of {@code Synthesizer}.
* <p> * <p>
* "Loading" an instrument means that that instrument becomes available for * "Loading" an instrument means that that instrument becomes available for
* synthesizing notes. The instrument is loaded into the bank and * synthesizing notes. The instrument is loaded into the bank and program
* program location specified by its <code>Patch</code> object. Loading does * location specified by its {@code Patch} object. Loading does not necessarily
* not necessarily mean that subsequently played notes will immediately have * mean that subsequently played notes will immediately have the sound of this
* the sound of this newly loaded instrument. For the instrument to play notes, * newly loaded instrument. For the instrument to play notes, one of the
* one of the synthesizer's <code>MidiChannel</code> objects must receive (or have received) * synthesizer's {@code MidiChannel} objects must receive (or have received) a
* a program-change message that causes that particular instrument's * program-change message that causes that particular instrument's bank and
* bank and program number to be selected. * program number to be selected.
* *
* @author Kara Kytle
* @see MidiSystem#getSynthesizer * @see MidiSystem#getSynthesizer
* @see Soundbank * @see Soundbank
* @see Instrument * @see Instrument
@ -72,107 +69,103 @@ import javax.sound.sampled.Control;
* @see Receiver * @see Receiver
* @see Transmitter * @see Transmitter
* @see MidiDevice * @see MidiDevice
*
* @author Kara Kytle
*/ */
public interface Synthesizer extends MidiDevice { public interface Synthesizer extends MidiDevice {
// SYNTHESIZER METHODS // SYNTHESIZER METHODS
/** /**
* Obtains the maximum number of notes that this synthesizer can sound simultaneously. * Obtains the maximum number of notes that this synthesizer can sound
* simultaneously.
*
* @return the maximum number of simultaneous notes * @return the maximum number of simultaneous notes
* @see #getVoiceStatus * @see #getVoiceStatus
*/ */
public int getMaxPolyphony(); int getMaxPolyphony();
/** /**
* Obtains the processing latency incurred by this synthesizer, expressed in * Obtains the processing latency incurred by this synthesizer, expressed in
* microseconds. This latency measures the worst-case delay between the * microseconds. This latency measures the worst-case delay between the time
* time a MIDI message is delivered to the synthesizer and the time that the * a MIDI message is delivered to the synthesizer and the time that the
* synthesizer actually produces the corresponding result. * synthesizer actually produces the corresponding result.
* <p> * <p>
* Although the latency is expressed in microseconds, a synthesizer's actual measured * Although the latency is expressed in microseconds, a synthesizer's actual
* delay may vary over a wider range than this resolution suggests. For example, * measured delay may vary over a wider range than this resolution suggests.
* a synthesizer might have a worst-case delay of a few milliseconds or more. * For example, a synthesizer might have a worst-case delay of a few
* milliseconds or more.
* *
* @return the worst-case delay, in microseconds * @return the worst-case delay, in microseconds
*/ */
public long getLatency(); long getLatency();
/** /**
* Obtains the set of MIDI channels controlled by this synthesizer. Each * Obtains the set of MIDI channels controlled by this synthesizer. Each
* non-null element in the returned array is a <code>MidiChannel</code> that * non-null element in the returned array is a {@code MidiChannel} that
* receives the MIDI messages sent on that channel number. * receives the MIDI messages sent on that channel number.
* <p> * <p>
* The MIDI 1.0 specification provides for 16 channels, so this * The MIDI 1.0 specification provides for 16 channels, so this method
* method returns an array of at least 16 elements. However, if this synthesizer * returns an array of at least 16 elements. However, if this synthesizer
* doesn't make use of all 16 channels, some of the elements of the array * doesn't make use of all 16 channels, some of the elements of the array
* might be <code>null</code>, so you should check each element * might be {@code null}, so you should check each element before using it.
* before using it. *
* @return an array of the <code>MidiChannel</code> objects managed by this * @return an array of the {@code MidiChannel} objects managed by this
* <code>Synthesizer</code>. Some of the array elements may be <code>null</code>. * {@code Synthesizer}. Some of the array elements may be
* {@code null}.
*/ */
public MidiChannel[] getChannels(); MidiChannel[] getChannels();
/** /**
* Obtains the current status of the voices produced by this synthesizer. * Obtains the current status of the voices produced by this synthesizer. If
* If this class of <code>Synthesizer</code> does not provide voice * this class of {@code Synthesizer} does not provide voice information, the
* information, the returned array will always be of length 0. Otherwise, * returned array will always be of length 0. Otherwise, its length is
* its length is always equal to the total number of voices, as returned by * always equal to the total number of voices, as returned by
* <code>getMaxPolyphony()</code>. (See the <code>VoiceStatus</code> class * {@code getMaxPolyphony()}. (See the {@code VoiceStatus} class description
* description for an explanation of synthesizer voices.) * for an explanation of synthesizer voices.)
* *
* @return an array of <code>VoiceStatus</code> objects that supply * @return an array of {@code VoiceStatus} objects that supply information
* information about the corresponding synthesizer voices * about the corresponding synthesizer voices
* @see #getMaxPolyphony * @see #getMaxPolyphony
* @see VoiceStatus * @see VoiceStatus
*/ */
public VoiceStatus[] getVoiceStatus(); VoiceStatus[] getVoiceStatus();
/** /**
* Informs the caller whether this synthesizer is capable of loading * Informs the caller whether this synthesizer is capable of loading
* instruments from the specified soundbank. * instruments from the specified soundbank. If the soundbank is
* If the soundbank is unsupported, any attempts to load instruments from * unsupported, any attempts to load instruments from it will result in an
* it will result in an <code>IllegalArgumentException</code>. * {@code IllegalArgumentException}.
*
* @param soundbank soundbank for which support is queried * @param soundbank soundbank for which support is queried
* @return <code>true</code> if the soundbank is supported, otherwise <code>false</code> * @return {@code true} if the soundbank is supported, otherwise
* {@code false}
* @see #loadInstruments * @see #loadInstruments
* @see #loadAllInstruments * @see #loadAllInstruments
* @see #unloadInstruments * @see #unloadInstruments
* @see #unloadAllInstruments * @see #unloadAllInstruments
* @see #getDefaultSoundbank * @see #getDefaultSoundbank
*/ */
public boolean isSoundbankSupported(Soundbank soundbank); boolean isSoundbankSupported(Soundbank soundbank);
/** /**
* Makes a particular instrument available for synthesis. This instrument * Makes a particular instrument available for synthesis. This instrument is
* is loaded into the patch location specified by its <code>Patch</code> * loaded into the patch location specified by its {@code Patch} object, so
* object, so that if a program-change message is * that if a program-change message is received (or has been received) that
* received (or has been received) that causes that patch to be selected, * causes that patch to be selected, subsequent notes will be played using
* subsequent notes will be played using the sound of * the sound of {@code instrument}. If the specified instrument is already
* <code>instrument</code>. If the specified instrument is already loaded, * loaded, this method does nothing and returns {@code true}.
* this method does nothing and returns <code>true</code>.
* <p> * <p>
* The instrument must be part of a soundbank * The instrument must be part of a soundbank that this {@code Synthesizer}
* that this <code>Synthesizer</code> supports. (To make sure, you can use * supports. (To make sure, you can use the {@code getSoundbank} method of
* the <code>getSoundbank</code> method of <code>Instrument</code> and the * {@code Instrument} and the {@code isSoundbankSupported} method of
* <code>isSoundbankSupported</code> method of <code>Synthesizer</code>.) * {@code Synthesizer}.)
*
* @param instrument instrument to load * @param instrument instrument to load
* @return <code>true</code> if the instrument is successfully loaded (or * @return {@code true} if the instrument is successfully loaded (or already
* already had been), <code>false</code> if the instrument could not be * had been), {@code false} if the instrument could not be loaded
* loaded (for example, if the synthesizer has insufficient * (for example, if the synthesizer has insufficient memory to load
* memory to load it) * it)
* @throws IllegalArgumentException if this * @throws IllegalArgumentException if this {@code Synthesizer} doesn't
* <code>Synthesizer</code> doesn't support the specified instrument's * support the specified instrument's soundbank
* soundbank
* @see #unloadInstrument * @see #unloadInstrument
* @see #loadInstruments * @see #loadInstruments
* @see #loadAllInstruments * @see #loadAllInstruments
@ -180,138 +173,139 @@ public interface Synthesizer extends MidiDevice {
* @see SoundbankResource#getSoundbank * @see SoundbankResource#getSoundbank
* @see MidiChannel#programChange(int, int) * @see MidiChannel#programChange(int, int)
*/ */
public boolean loadInstrument(Instrument instrument); boolean loadInstrument(Instrument instrument);
/** /**
* Unloads a particular instrument. * Unloads a particular instrument.
*
* @param instrument instrument to unload * @param instrument instrument to unload
* @throws IllegalArgumentException if this * @throws IllegalArgumentException if this {@code Synthesizer} doesn't
* <code>Synthesizer</code> doesn't support the specified instrument's * support the specified instrument's soundbank
* soundbank
* @see #loadInstrument * @see #loadInstrument
* @see #unloadInstruments * @see #unloadInstruments
* @see #unloadAllInstruments * @see #unloadAllInstruments
* @see #getLoadedInstruments * @see #getLoadedInstruments
* @see #remapInstrument * @see #remapInstrument
*/ */
public void unloadInstrument(Instrument instrument); void unloadInstrument(Instrument instrument);
/** /**
* Remaps an instrument. Instrument <code>to</code> takes the * Remaps an instrument. Instrument {@code to} takes the place of instrument
* place of instrument <code>from</code>.<br> * {@code from}.
* For example, if <code>from</code> was located at bank number 2, * <br>
* program number 11, remapping causes that bank and program location * For example, if {@code from} was located at bank number 2, program number
* to be occupied instead by <code>to</code>.<br> * 11, remapping causes that bank and program location to be occupied
* If the function succeeds, instrument <code>from</code> is unloaded. * instead by {@code to}.
* <p>To cancel the remapping reload instrument <code>from</code> by * <br>
* invoking one of {@link #loadInstrument}, {@link #loadInstruments} * If the function succeeds, instrument {@code from} is unloaded.
* or {@link #loadAllInstruments}. * <p>
* To cancel the remapping reload instrument {@code from} by invoking one of
* {@link #loadInstrument}, {@link #loadInstruments} or
* {@link #loadAllInstruments}.
* *
* @param from the <code>Instrument</code> object to be replaced * @param from the {@code Instrument} object to be replaced
* @param to the <code>Instrument</code> object to be used in place * @param to the {@code Instrument} object to be used in place of the old
* of the old instrument, it should be loaded into the synthesizer * instrument, it should be loaded into the synthesizer
* @return <code>true</code> if the instrument successfully remapped, * @return {@code true} if the instrument successfully remapped,
* <code>false</code> if feature is not implemented by synthesizer * {@code false} if feature is not implemented by synthesizer
* @throws IllegalArgumentException if instrument * @throws IllegalArgumentException if instrument {@code from} or instrument
* <code>from</code> or instrument <code>to</code> aren't supported by * {@code to} aren't supported by synthesizer or if instrument
* synthesizer or if instrument <code>to</code> is not loaded * {@code to} is not loaded
* @throws NullPointerException if <code>from</code> or * @throws NullPointerException if {@code from} or {@code to} parameters
* <code>to</code> parameters have null value * have null value
* @see #loadInstrument * @see #loadInstrument
* @see #loadInstruments * @see #loadInstruments
* @see #loadAllInstruments * @see #loadAllInstruments
*/ */
public boolean remapInstrument(Instrument from, Instrument to); boolean remapInstrument(Instrument from, Instrument to);
/** /**
* Obtains the default soundbank for the synthesizer, if one exists. * Obtains the default soundbank for the synthesizer, if one exists. (Some
* (Some synthesizers provide a default or built-in soundbank.) * synthesizers provide a default or built-in soundbank.) If a synthesizer
* If a synthesizer doesn't have a default soundbank, instruments must * doesn't have a default soundbank, instruments must be loaded explicitly
* be loaded explicitly from an external soundbank. * from an external soundbank.
* @return default soundbank, or <code>null</code> if one does not exist. *
* @return default soundbank, or {@code null} if one does not exist
* @see #isSoundbankSupported * @see #isSoundbankSupported
*/ */
public Soundbank getDefaultSoundbank(); Soundbank getDefaultSoundbank();
/** /**
* Obtains a list of instruments that come with the synthesizer. These * Obtains a list of instruments that come with the synthesizer. These
* instruments might be built into the synthesizer, or they might be * instruments might be built into the synthesizer, or they might be part of
* part of a default soundbank provided with the synthesizer, etc. * a default soundbank provided with the synthesizer, etc.
* <p> * <p>
* Note that you don't use this method to find out which instruments are * Note that you don't use this method to find out which instruments are
* currently loaded onto the synthesizer; for that purpose, you use * currently loaded onto the synthesizer; for that purpose, you use
* <code>getLoadedInstruments()</code>. * {@code getLoadedInstruments()}. Nor does the method indicate all the
* Nor does the method indicate all the instruments that can be loaded onto * instruments that can be loaded onto the synthesizer; it only indicates
* the synthesizer; it only indicates the subset that come with the synthesizer. * the subset that come with the synthesizer. To learn whether another
* To learn whether another instrument can be loaded, you can invoke * instrument can be loaded, you can invoke {@code isSoundbankSupported()},
* <code>isSoundbankSupported()</code>, and if the instrument's * and if the instrument's {@code Soundbank} is supported, you can try
* <code>Soundbank</code> is supported, you can try loading the instrument. * loading the instrument.
* *
* @return list of available instruments. If the synthesizer * @return list of available instruments. If the synthesizer has no
* has no instruments coming with it, an array of length 0 is returned. * instruments coming with it, an array of length 0 is returned.
* @see #getLoadedInstruments * @see #getLoadedInstruments
* @see #isSoundbankSupported(Soundbank) * @see #isSoundbankSupported(Soundbank)
* @see #loadInstrument * @see #loadInstrument
*/ */
public Instrument[] getAvailableInstruments(); Instrument[] getAvailableInstruments();
/** /**
* Obtains a list of the instruments that are currently loaded onto this * Obtains a list of the instruments that are currently loaded onto this
* <code>Synthesizer</code>. * {@code Synthesizer}.
*
* @return a list of currently loaded instruments * @return a list of currently loaded instruments
* @see #loadInstrument * @see #loadInstrument
* @see #getAvailableInstruments * @see #getAvailableInstruments
* @see Soundbank#getInstruments * @see Soundbank#getInstruments
*/ */
public Instrument[] getLoadedInstruments(); Instrument[] getLoadedInstruments();
/** /**
* Loads onto the <code>Synthesizer</code> all instruments contained * Loads onto the {@code Synthesizer} all instruments contained in the
* in the specified <code>Soundbank</code>. * specified {@code Soundbank}.
* @param soundbank the <code>Soundbank</code> whose are instruments are *
* to be loaded * @param soundbank the {@code Soundbank} whose are instruments are to be
* @return <code>true</code> if the instruments are all successfully loaded (or * loaded
* already had been), <code>false</code> if any instrument could not be * @return {@code true} if the instruments are all successfully loaded (or
* loaded (for example, if the <code>Synthesizer</code> had insufficient memory) * already had been), {@code false} if any instrument could not be
* loaded (for example, if the {@code Synthesizer} had insufficient
* memory)
* @throws IllegalArgumentException if the requested soundbank is * @throws IllegalArgumentException if the requested soundbank is
* incompatible with this synthesizer. * incompatible with this synthesizer
* @see #isSoundbankSupported * @see #isSoundbankSupported
* @see #loadInstrument * @see #loadInstrument
* @see #loadInstruments * @see #loadInstruments
*/ */
public boolean loadAllInstruments(Soundbank soundbank); boolean loadAllInstruments(Soundbank soundbank);
/** /**
* Unloads all instruments contained in the specified <code>Soundbank</code>. * Unloads all instruments contained in the specified {@code Soundbank}.
*
* @param soundbank soundbank containing instruments to unload * @param soundbank soundbank containing instruments to unload
* @throws IllegalArgumentException thrown if the soundbank is not supported. * @throws IllegalArgumentException thrown if the soundbank is not supported
* @see #isSoundbankSupported * @see #isSoundbankSupported
* @see #unloadInstrument * @see #unloadInstrument
* @see #unloadInstruments * @see #unloadInstruments
*/ */
public void unloadAllInstruments(Soundbank soundbank); void unloadAllInstruments(Soundbank soundbank);
/** /**
* Loads the instruments referenced by the specified patches, from the * Loads the instruments referenced by the specified patches, from the
* specified <code>Soundbank</code>. Each of the <code>Patch</code> objects * specified {@code Soundbank}. Each of the {@code Patch} objects indicates
* indicates a bank and program number; the <code>Instrument</code> that * a bank and program number; the {@code Instrument} that has the matching
* has the matching <code>Patch</code> is loaded into that bank and program * {@code Patch} is loaded into that bank and program location.
* location. *
* @param soundbank the <code>Soundbank</code> containing the instruments to load * @param soundbank the {@code Soundbank} containing the instruments to
* load
* @param patchList list of patches for which instruments should be loaded * @param patchList list of patches for which instruments should be loaded
* @return <code>true</code> if the instruments are all successfully loaded (or * @return {@code true} if the instruments are all successfully loaded (or
* already had been), <code>false</code> if any instrument could not be * already had been), {@code false} if any instrument could not be
* loaded (for example, if the <code>Synthesizer</code> had insufficient memory) * loaded (for example, if the {@code Synthesizer} had insufficient
* @throws IllegalArgumentException thrown if the soundbank is not supported. * memory)
* @throws IllegalArgumentException thrown if the soundbank is not supported
* @see #isSoundbankSupported * @see #isSoundbankSupported
* @see Instrument#getPatch * @see Instrument#getPatch
* @see #loadAllInstruments * @see #loadAllInstruments
@ -319,62 +313,62 @@ public interface Synthesizer extends MidiDevice {
* @see Soundbank#getInstrument(Patch) * @see Soundbank#getInstrument(Patch)
* @see Sequence#getPatchList() * @see Sequence#getPatchList()
*/ */
public boolean loadInstruments(Soundbank soundbank, Patch[] patchList); boolean loadInstruments(Soundbank soundbank, Patch[] patchList);
/** /**
* Unloads the instruments referenced by the specified patches, from the MIDI sound bank specified. * Unloads the instruments referenced by the specified patches, from the
* @param soundbank soundbank containing instruments to unload * MIDI sound bank specified.
* @param patchList list of patches for which instruments should be unloaded
* @throws IllegalArgumentException thrown if the soundbank is not supported.
* *
* @param soundbank soundbank containing instruments to unload
* @param patchList list of patches for which instruments should be
* unloaded
* @throws IllegalArgumentException thrown if the soundbank is not supported
* @see #unloadInstrument * @see #unloadInstrument
* @see #unloadAllInstruments * @see #unloadAllInstruments
* @see #isSoundbankSupported * @see #isSoundbankSupported
* @see Instrument#getPatch * @see Instrument#getPatch
* @see #loadInstruments * @see #loadInstruments
*/ */
public void unloadInstruments(Soundbank soundbank, Patch[] patchList); void unloadInstruments(Soundbank soundbank, Patch[] patchList);
// RECEIVER METHODS // RECEIVER METHODS
/** /**
* Obtains the name of the receiver. * Obtains the name of the receiver.
*
* @return receiver name * @return receiver name
*/ */
// public abstract String getName(); // abstract String getName();
/** /**
* Opens the receiver. * Opens the receiver.
*
* @throws MidiUnavailableException if the receiver is cannot be opened, * @throws MidiUnavailableException if the receiver is cannot be opened,
* usually because the MIDI device is in use by another application. * usually because the MIDI device is in use by another application.
* @throws SecurityException if the receiver cannot be opened due to security * @throws SecurityException if the receiver cannot be opened due to
* restrictions. * security restrictions
*/ */
// public abstract void open() throws MidiUnavailableException, SecurityException; // abstract void open() throws MidiUnavailableException, SecurityException;
/** /**
* Closes the receiver. * Closes the receiver.
*/ */
// public abstract void close(); // abstract void close();
/** /**
* Sends a MIDI event to the receiver. * Sends a MIDI event to the receiver.
* @param event event to send. *
* @throws IllegalStateException if the receiver is not open. * @param event event to send
* @throws IllegalStateException if the receiver is not open
*/ */
// public void send(MidiEvent event) throws IllegalStateException { // void send(MidiEvent event) throws IllegalStateException {
// //
// } // }
/** /**
* Obtains the set of controls supported by the * Obtains the set of controls supported by the element. If no controls are
* element. If no controls are supported, returns an * supported, returns an array of length 0.
* array of length 0. *
* @return set of controls * @return set of controls
*/ */
// $$kk: 03.04.99: josh bloch recommends getting rid of this: // $$kk: 03.04.99: josh bloch recommends getting rid of this:
@ -382,13 +376,13 @@ public interface Synthesizer extends MidiDevice {
// $$kk: 03.05.99: i am putting this back in. for one thing, // $$kk: 03.05.99: i am putting this back in. for one thing,
// you can check the length and know whether you should keep // you can check the length and know whether you should keep
// looking.... // looking....
// public Control[] getControls(); // Control[] getControls();
/** /**
* Obtains the specified control. * Obtains the specified control.
*
* @param controlClass class of the requested control * @param controlClass class of the requested control
* @return requested control object, or null if the * @return requested control object, or null if the control is not supported
* control is not supported.
*/ */
// public Control getControl(Class controlClass); // Control getControl(Class controlClass);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,47 +26,47 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* A <code>SysexMessage</code> object represents a MIDI system exclusive message. * A {@code SysexMessage} object represents a MIDI system exclusive message.
* <p> * <p>
* When a system exclusive message is read from a MIDI file, it always has * When a system exclusive message is read from a MIDI file, it always has a
* a defined length. Data from a system exclusive message from a MIDI file * defined length. Data from a system exclusive message from a MIDI file should
* should be stored in the data array of a <code>SysexMessage</code> as * be stored in the data array of a {@code SysexMessage} as follows: the system
* follows: the system exclusive message status byte (0xF0 or 0xF7), all * exclusive message status byte (0xF0 or 0xF7), all message data bytes, and
* message data bytes, and finally the end-of-exclusive flag (0xF7). * finally the end-of-exclusive flag (0xF7). The length reported by the
* The length reported by the <code>SysexMessage</code> object is therefore * {@code SysexMessage} object is therefore the length of the system exclusive
* the length of the system exclusive data plus two: one byte for the status * data plus two: one byte for the status byte and one for the end-of-exclusive
* byte and one for the end-of-exclusive flag. * flag.
* <p> * <p>
* As dictated by the Standard MIDI Files specification, two status byte values are legal * As dictated by the Standard MIDI Files specification, two status byte values
* for a <code>SysexMessage</code> read from a MIDI file: * are legal for a {@code SysexMessage} read from a MIDI file:
* <ul> * <ul>
* <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li> * <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li>
* <li>0xF7: Special System Exclusive message</li> * <li>0xF7: Special System Exclusive message</li>
* </ul> * </ul>
* <p> * When Java Sound is used to handle system exclusive data that is being
* When Java Sound is used to handle system exclusive data that is being received * received using MIDI wire protocol, it should place the data in one or more
* using MIDI wire protocol, it should place the data in one or more * {@code SysexMessages}. In this case, the length of the system exclusive data
* <code>SysexMessages</code>. In this case, the length of the system exclusive data
* is not known in advance; the end of the system exclusive data is marked by an * is not known in advance; the end of the system exclusive data is marked by an
* end-of-exclusive flag (0xF7) in the MIDI wire byte stream. * end-of-exclusive flag (0xF7) in the MIDI wire byte stream.
* <ul> * <ul>
* <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li> * <li>0xF0: System Exclusive message (same as in MIDI wire protocol)</li>
* <li>0xF7: End of Exclusive (EOX)</li> * <li>0xF7: End of Exclusive (EOX)</li>
* </ul> * </ul>
* The first <code>SysexMessage</code> object containing data for a particular system * The first {@code SysexMessage} object containing data for a particular system
* exclusive message should have the status value 0xF0. If this message contains all * exclusive message should have the status value 0xF0. If this message contains
* the system exclusive data * all the system exclusive data for the message, it should end with the status
* for the message, it should end with the status byte 0xF7 (EOX). * byte 0xF7 (EOX). Otherwise, additional system exclusive data should be sent
* Otherwise, additional system exclusive data should be sent in one or more * in one or more {@code SysexMessages} with a status value of 0xF7. The
* <code>SysexMessages</code> with a status value of 0xF7. The <code>SysexMessage</code> * {@code SysexMessage} containing the last of the data for the system exclusive
* containing the last of the data for the system exclusive message should end with the * message should end with the value 0xF7 (EOX) to mark the end of the system
* value 0xF7 (EOX) to mark the end of the system exclusive message. * exclusive message.
* <p> * <p>
* If system exclusive data from <code>SysexMessages</code> objects is being transmitted * If system exclusive data from {@code SysexMessages} objects is being
* using MIDI wire protocol, only the initial 0xF0 status byte, the system exclusive * transmitted using MIDI wire protocol, only the initial 0xF0 status byte, the
* data itself, and the final 0xF7 (EOX) byte should be propagated; any 0xF7 status * system exclusive data itself, and the final 0xF7 (EOX) byte should be
* bytes used to indicate that a <code>SysexMessage</code> contains continuing system * propagated; any 0xF7 status bytes used to indicate that a
* exclusive data should not be propagated via MIDI wire protocol. * {@code SysexMessage} contains continuing system exclusive data should not be
* propagated via MIDI wire protocol.
* *
* @author David Rivas * @author David Rivas
* @author Kara Kytle * @author Kara Kytle
@ -74,43 +74,36 @@ package javax.sound.midi;
*/ */
public class SysexMessage extends MidiMessage { public class SysexMessage extends MidiMessage {
// Status byte defines // Status byte defines
/** /**
* Status byte for System Exclusive message (0xF0, or 240). * Status byte for System Exclusive message (0xF0, or 240).
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int SYSTEM_EXCLUSIVE = 0xF0; // 240 public static final int SYSTEM_EXCLUSIVE = 0xF0; // 240
/** /**
* Status byte for Special System Exclusive message (0xF7, or 247), which is used * Status byte for Special System Exclusive message (0xF7, or 247), which is
* in MIDI files. It has the same value as END_OF_EXCLUSIVE, which * used in MIDI files. It has the same value as END_OF_EXCLUSIVE, which is
* is used in the real-time "MIDI wire" protocol. * used in the real-time "MIDI wire" protocol.
*
* @see MidiMessage#getStatus * @see MidiMessage#getStatus
*/ */
public static final int SPECIAL_SYSTEM_EXCLUSIVE = 0xF7; // 247 public static final int SPECIAL_SYSTEM_EXCLUSIVE = 0xF7; // 247
/**
// Instance variables * The data bytes for this system exclusive message. These are initialized
* to {@code null} and are set explicitly by
* {@link #setMessage(int, byte[], int, long) setMessage}.
/*
* The data bytes for this system exclusive message. These are
* initialized to <code>null</code> and are set explicitly
* by {@link #setMessage(int, byte[], int, long) setMessage}.
*/ */
//protected byte[] data = null; //protected byte[] data = null;
/** /**
* Constructs a new <code>SysexMessage</code>. The * Constructs a new {@code SysexMessage}. The contents of the new message
* contents of the new message are guaranteed to specify * are guaranteed to specify a valid MIDI message. Subsequently, you may set
* a valid MIDI message. Subsequently, you may set the * the contents of the message using one of the {@code setMessage} methods.
* contents of the message using one of the <code>setMessage</code> *
* methods.
* @see #setMessage * @see #setMessage
*/ */
public SysexMessage() { public SysexMessage() {
@ -121,18 +114,17 @@ public class SysexMessage extends MidiMessage {
} }
/** /**
* Constructs a new {@code SysexMessage} and sets the data for * Constructs a new {@code SysexMessage} and sets the data for the message.
* the message. The first byte of the data array must be a valid system * The first byte of the data array must be a valid system exclusive status
* exclusive status byte (0xF0 or 0xF7). * byte (0xF0 or 0xF7). The contents of the message can be changed by using
* The contents of the message can be changed by using one of * one of the {@code setMessage} methods.
* the {@code setMessage} methods.
* *
* @param data the system exclusive message data including the status byte * @param data the system exclusive message data including the status byte
* @param length the length of the valid message data in the array, * @param length the length of the valid message data in the array,
* including the status byte; it should be non-negative and less than * including the status byte; it should be non-negative and less
* or equal to {@code data.length} * than or equal to {@code data.length}
* @throws InvalidMidiDataException if the parameter values * @throws InvalidMidiDataException if the parameter values do not specify a
* do not specify a valid MIDI meta message. * valid MIDI meta message.
* @see #setMessage(byte[], int) * @see #setMessage(byte[], int)
* @see #setMessage(int, byte[], int) * @see #setMessage(int, byte[], int)
* @see #getData() * @see #getData()
@ -146,17 +138,17 @@ public class SysexMessage extends MidiMessage {
/** /**
* Constructs a new {@code SysexMessage} and sets the data for the message. * Constructs a new {@code SysexMessage} and sets the data for the message.
* The contents of the message can be changed by using one of * The contents of the message can be changed by using one of the
* the {@code setMessage} methods. * {@code setMessage} methods.
* *
* @param status the status byte for the message; it must be a valid system * @param status the status byte for the message; it must be a valid system
* exclusive status byte (0xF0 or 0xF7) * exclusive status byte (0xF0 or 0xF7)
* @param data the system exclusive message data (without the status byte) * @param data the system exclusive message data (without the status byte)
* @param length the length of the valid message data in the array; * @param length the length of the valid message data in the array; it
* it should be non-negative and less than or equal to * should be non-negative and less than or equal to
* {@code data.length} * {@code data.length}
* @throws InvalidMidiDataException if the parameter values * @throws InvalidMidiDataException if the parameter values do not specify a
* do not specify a valid MIDI meta message. * valid MIDI meta message
* @see #setMessage(byte[], int) * @see #setMessage(byte[], int)
* @see #setMessage(int, byte[], int) * @see #setMessage(int, byte[], int)
* @see #getData() * @see #getData()
@ -168,26 +160,24 @@ public class SysexMessage extends MidiMessage {
setMessage(status, data, length); setMessage(status, data, length);
} }
/** /**
* Constructs a new <code>SysexMessage</code>. * Constructs a new {@code SysexMessage}.
* @param data an array of bytes containing the complete message. *
* The message data may be changed using the <code>setMessage</code> * @param data an array of bytes containing the complete message. The
* method. * message data may be changed using the {@code setMessage} method.
* @see #setMessage * @see #setMessage
*/ */
protected SysexMessage(byte[] data) { protected SysexMessage(byte[] data) {
super(data); super(data);
} }
/** /**
* Sets the data for the system exclusive message. The * Sets the data for the system exclusive message. The first byte of the
* first byte of the data array must be a valid system * data array must be a valid system exclusive status byte (0xF0 or 0xF7).
* exclusive status byte (0xF0 or 0xF7). *
* @param data the system exclusive message data * @param data the system exclusive message data
* @param length the length of the valid message data in * @param length the length of the valid message data in the array,
* the array, including the status byte. * including the status byte
*/ */
public void setMessage(byte[] data, int length) throws InvalidMidiDataException { public void setMessage(byte[] data, int length) throws InvalidMidiDataException {
int status = (data[0] & 0xFF); int status = (data[0] & 0xFF);
@ -197,14 +187,14 @@ public class SysexMessage extends MidiMessage {
super.setMessage(data, length); super.setMessage(data, length);
} }
/** /**
* Sets the data for the system exclusive message. * Sets the data for the system exclusive message.
*
* @param status the status byte for the message (0xF0 or 0xF7) * @param status the status byte for the message (0xF0 or 0xF7)
* @param data the system exclusive message data * @param data the system exclusive message data
* @param length the length of the valid message data in * @param length the length of the valid message data in the array
* the array * @throws InvalidMidiDataException if the status byte is invalid for a
* @throws InvalidMidiDataException if the status byte is invalid for a sysex message * sysex message
*/ */
public void setMessage(int status, byte[] data, int length) throws InvalidMidiDataException { public void setMessage(int status, byte[] data, int length) throws InvalidMidiDataException {
if ( (status != 0xF0) && (status != 0xF7) ) { if ( (status != 0xF0) && (status != 0xF7) ) {
@ -225,11 +215,11 @@ public class SysexMessage extends MidiMessage {
} }
} }
/** /**
* Obtains a copy of the data for the system exclusive message. * Obtains a copy of the data for the system exclusive message. The returned
* The returned array of bytes does not include the status byte. * array of bytes does not include the status byte.
* @return array containing the system exclusive message data. *
* @return array containing the system exclusive message data
*/ */
public byte[] getData() { public byte[] getData() {
byte[] returnedArray = new byte[length - 1]; byte[] returnedArray = new byte[length - 1];
@ -237,10 +227,10 @@ public class SysexMessage extends MidiMessage {
return returnedArray; return returnedArray;
} }
/** /**
* Creates a new object of the same class and with the same contents * Creates a new object of the same class and with the same contents as this
* as this object. * object.
*
* @return a clone of this instance * @return a clone of this instance
*/ */
public Object clone() { public Object clone() {

View file

@ -25,41 +25,40 @@
package javax.sound.midi; package javax.sound.midi;
import java.util.Vector;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import com.sun.media.sound.MidiUtils; import com.sun.media.sound.MidiUtils;
/** /**
* A MIDI track is an independent stream of MIDI events (time-stamped MIDI * A MIDI track is an independent stream of MIDI events (time-stamped MIDI data)
* data) that can be stored along with other tracks in a standard MIDI file. * that can be stored along with other tracks in a standard MIDI file. The MIDI
* The MIDI specification allows only 16 channels of MIDI data, but tracks * specification allows only 16 channels of MIDI data, but tracks are a way to
* are a way to get around this limitation. A MIDI file can contain any number * get around this limitation. A MIDI file can contain any number of tracks,
* of tracks, each containing its own stream of up to 16 channels of MIDI data. * each containing its own stream of up to 16 channels of MIDI data.
* <p> * <p>
* A <code>Track</code> occupies a middle level in the hierarchy of data played * A {@code Track} occupies a middle level in the hierarchy of data played by a
* by a <code>{@link Sequencer}</code>: sequencers play sequences, which contain tracks, * {@link Sequencer}: sequencers play sequences, which contain tracks, which
* which contain MIDI events. A sequencer may provide controls that mute * contain MIDI events. A sequencer may provide controls that mute or solo
* or solo individual tracks. * individual tracks.
* <p> * <p>
* The timing information and resolution for a track is controlled by and stored * The timing information and resolution for a track is controlled by and stored
* in the sequence containing the track. A given <code>Track</code> * in the sequence containing the track. A given {@code Track} is considered to
* is considered to belong to the particular <code>{@link Sequence}</code> that * belong to the particular {@link Sequence} that maintains its timing. For this
* maintains its timing. For this reason, a new (empty) track is created by calling the * reason, a new (empty) track is created by calling the
* <code>{@link Sequence#createTrack}</code> method, rather than by directly invoking a * {@link Sequence#createTrack} method, rather than by directly invoking a
* <code>Track</code> constructor. * {@code Track} constructor.
* <p> * <p>
* The <code>Track</code> class provides methods to edit the track by adding * The {@code Track} class provides methods to edit the track by adding or
* or removing <code>MidiEvent</code> objects from it. These operations keep * removing {@code MidiEvent} objects from it. These operations keep the event
* the event list in the correct time order. Methods are also * list in the correct time order. Methods are also included to obtain the
* included to obtain the track's size, in terms of either the number of events * track's size, in terms of either the number of events it contains or its
* it contains or its duration in ticks. * duration in ticks.
*
* @see Sequencer#setTrackMute
* @see Sequencer#setTrackSolo
* *
* @author Kara Kytle * @author Kara Kytle
* @author Florian Bomers * @author Florian Bomers
* @see Sequencer#setTrackMute
* @see Sequencer#setTrackSolo
*/ */
public class Track { public class Track {
@ -73,10 +72,9 @@ public class Track {
private MidiEvent eotEvent; private MidiEvent eotEvent;
/** /**
* Package-private constructor. Constructs a new, empty Track object, * Package-private constructor. Constructs a new, empty Track object, which
* which initially contains one event, the meta-event End of Track. * initially contains one event, the meta-event End of Track.
*/ */
Track() { Track() {
// start with the end of track event // start with the end of track event
@ -87,14 +85,14 @@ public class Track {
} }
/** /**
* Adds a new event to the track. However, if the event is already * Adds a new event to the track. However, if the event is already contained
* contained in the track, it is not added again. The list of events * in the track, it is not added again. The list of events is kept in time
* is kept in time order, meaning that this event inserted at the * order, meaning that this event inserted at the appropriate place in the
* appropriate place in the list, not necessarily at the end. * list, not necessarily at the end.
* *
* @param event the event to add * @param event the event to add
* @return <code>true</code> if the event did not already exist in the * @return {@code true} if the event did not already exist in the track and
* track and was added, otherwise <code>false</code> * was added, otherwise {@code false}
*/ */
public boolean add(MidiEvent event) { public boolean add(MidiEvent event) {
if (event == null) { if (event == null) {
@ -176,12 +174,12 @@ public class Track {
return false; return false;
} }
/** /**
* Removes the specified event from the track. * Removes the specified event from the track.
*
* @param event the event to remove * @param event the event to remove
* @return <code>true</code> if the event existed in the track and was removed, * @return {@code true} if the event existed in the track and was removed,
* otherwise <code>false</code> * otherwise {@code false}
*/ */
public boolean remove(MidiEvent event) { public boolean remove(MidiEvent event) {
@ -207,15 +205,14 @@ public class Track {
return false; return false;
} }
/** /**
* Obtains the event at the specified index. * Obtains the event at the specified index.
*
* @param index the location of the desired event in the event vector * @param index the location of the desired event in the event vector
* @throws ArrayIndexOutOfBoundsException if the
* specified index is negative or not less than the current size of
* this track.
* @see #size
* @return the event at the specified index * @return the event at the specified index
* @throws ArrayIndexOutOfBoundsException if the specified index is negative
* or not less than the current size of this track
* @see #size
*/ */
public MidiEvent get(int index) throws ArrayIndexOutOfBoundsException { public MidiEvent get(int index) throws ArrayIndexOutOfBoundsException {
try { try {
@ -227,9 +224,9 @@ public class Track {
} }
} }
/** /**
* Obtains the number of events in this track. * Obtains the number of events in this track.
*
* @return the size of the track's event vector * @return the size of the track's event vector
*/ */
public int size() { public int size() {
@ -238,12 +235,12 @@ public class Track {
} }
} }
/** /**
* Obtains the length of the track, expressed in MIDI ticks. (The * Obtains the length of the track, expressed in MIDI ticks. (The duration
* duration of a tick in seconds is determined by the timing resolution * of a tick in seconds is determined by the timing resolution of the
* of the <code>Sequence</code> containing this track, and also by * {@code Sequence} containing this track, and also by the tempo of the
* the tempo of the music as set by the sequencer.) * music as set by the sequencer.)
*
* @return the duration, in ticks * @return the duration, in ticks
* @see Sequence#Sequence(float, int) * @see Sequence#Sequence(float, int)
* @see Sequencer#setTempoInBPM(float) * @see Sequencer#setTempoInBPM(float)
@ -271,5 +268,4 @@ public class Track {
throw new InvalidMidiDataException("cannot modify end of track message"); throw new InvalidMidiDataException("cannot modify end of track message");
} }
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,52 +25,49 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* A <code>Transmitter</code> sends <code>{@link MidiEvent}</code> objects to one or more * A {@code Transmitter} sends {@link MidiEvent} objects to one or more
* <code>{@link Receiver Receivers}</code>. Common MIDI transmitters include sequencers * {@link Receiver Receivers}. Common MIDI transmitters include sequencers and
* and MIDI input ports. * MIDI input ports.
*
* @see Receiver
* *
* @author Kara Kytle * @author Kara Kytle
* @see Receiver
*/ */
public interface Transmitter extends AutoCloseable { public interface Transmitter extends AutoCloseable {
/** /**
* Sets the receiver to which this transmitter will deliver MIDI messages. * Sets the receiver to which this transmitter will deliver MIDI messages.
* If a receiver is currently set, it is replaced with this one. * If a receiver is currently set, it is replaced with this one.
* @param receiver the desired receiver. *
* @param receiver the desired receiver
*/ */
public void setReceiver(Receiver receiver); void setReceiver(Receiver receiver);
/** /**
* Obtains the current receiver to which this transmitter will deliver MIDI messages. * Obtains the current receiver to which this transmitter will deliver MIDI
* @return the current receiver. If no receiver is currently set, * messages.
* returns <code>null</code> *
* @return the current receiver. If no receiver is currently set, returns
* {@code null}.
*/ */
public Receiver getReceiver(); Receiver getReceiver();
/** /**
* Indicates that the application has finished using the transmitter, and * Indicates that the application has finished using the transmitter, and
* that limited resources it requires may be released or made available. * that limited resources it requires may be released or made available.
* * <p>
* <p>If the creation of this <code>Transmitter</code> resulted in * If the creation of this {@code Transmitter} resulted in implicitly
* implicitly opening the underlying device, the device is * opening the underlying device, the device is implicitly closed by this
* implicitly closed by this method. This is true unless the device is * method. This is true unless the device is kept open by other
* kept open by other <code>Receiver</code> or <code>Transmitter</code> * {@code Receiver} or {@code Transmitter} instances that opened the device
* instances that opened the device implicitly, and unless the device * implicitly, and unless the device has been opened explicitly. If the
* has been opened explicitly. If the device this * device this {@code Transmitter} is retrieved from is closed explicitly by
* <code>Transmitter</code> is retrieved from is closed explicitly * calling {@link MidiDevice#close MidiDevice.close}, the
* by calling {@link MidiDevice#close MidiDevice.close}, the * {@code Transmitter} is closed, too. For a detailed description of
* <code>Transmitter</code> is closed, too. For a detailed * open/close behaviour see the class description of
* description of open/close behaviour see the class description * {@link MidiDevice MidiDevice}.
* of {@link javax.sound.midi.MidiDevice MidiDevice}.
* *
* @see javax.sound.midi.MidiSystem#getTransmitter * @see javax.sound.midi.MidiSystem#getTransmitter
*/ */
public void close(); void close();
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,93 +25,83 @@
package javax.sound.midi; package javax.sound.midi;
/** /**
* A <code>VoiceStatus</code> object contains information about the current * A {@code VoiceStatus} object contains information about the current status of
* status of one of the voices produced by a {@link Synthesizer}. * one of the voices produced by a {@link Synthesizer}.
* <p> * <p>
* MIDI synthesizers are generally capable of producing some maximum number of * MIDI synthesizers are generally capable of producing some maximum number of
* simultaneous notes, also referred to as voices. A voice is a stream * simultaneous notes, also referred to as voices. A voice is a stream of
* of successive single notes, and the process of assigning incoming MIDI notes to * successive single notes, and the process of assigning incoming MIDI notes to
* specific voices is known as voice allocation. * specific voices is known as voice allocation. However, the voice-allocation
* However, the voice-allocation algorithm and the contents of each voice are * algorithm and the contents of each voice are normally internal to a MIDI
* normally internal to a MIDI synthesizer and hidden from outside view. One can, of * synthesizer and hidden from outside view. One can, of course, learn from MIDI
* course, learn from MIDI messages which notes the synthesizer is playing, and * messages which notes the synthesizer is playing, and one might be able deduce
* one might be able deduce something about the assignment of notes to voices. * something about the assignment of notes to voices. But MIDI itself does not
* But MIDI itself does not provide a means to report which notes a * provide a means to report which notes a synthesizer has assigned to which
* synthesizer has assigned to which voice, nor even to report how many voices * voice, nor even to report how many voices the synthesizer is capable of
* the synthesizer is capable of synthesizing. * synthesizing.
* <p> * <p>
* In Java Sound, however, a * In Java Sound, however, a {@code Synthesizer} class can expose the contents
* <code>Synthesizer</code> class can expose the contents of its voices through its * of its voices through its
* {@link Synthesizer#getVoiceStatus() getVoiceStatus()} method. * {@link Synthesizer#getVoiceStatus() getVoiceStatus()} method. This behavior
* This behavior is recommended but optional; * is recommended but optional; synthesizers that don't expose their voice
* synthesizers that don't expose their voice allocation simply return a * allocation simply return a zero-length array. A {@code Synthesizer} that does
* zero-length array. A <code>Synthesizer</code> that does report its voice status * report its voice status should maintain this information at all times for all
* should maintain this information at * of its voices, whether they are currently sounding or not. In other words, a
* all times for all of its voices, whether they are currently sounding or * given type of {@code Synthesizer} always has a fixed number of voices, equal
* not. In other words, a given type of <code>Synthesizer</code> always has a fixed * to the maximum number of simultaneous notes it is capable of sounding.
* number of voices, equal to the maximum number of simultaneous notes it is
* capable of sounding.
* <p> * <p>
* <A NAME="description_of_active"></A> * <a NAME="description_of_active"></a> If the voice is not currently processing
* If the voice is not currently processing a MIDI note, it * a MIDI note, it is considered inactive. A voice is inactive when it has been
* is considered inactive. A voice is inactive when it has * given no note-on commands, or when every note-on command received has been
* been given no note-on commands, or when every note-on command received has * terminated by a corresponding note-off (or by an "all notes off" message).
* been terminated by a corresponding note-off (or by an "all notes off" * For example, this happens when a synthesizer capable of playing 16
* message). For example, this happens when a synthesizer capable of playing 16 * simultaneous notes is told to play a four-note chord; only four voices are
* simultaneous notes is told to play a four-note chord; only * active in this case (assuming no earlier notes are still playing). Usually, a
* four voices are active in this case (assuming no earlier notes are still playing). * voice whose status is reported as active is producing audible sound, but this
* Usually, a voice whose status is reported as active is producing audible sound, but this * is not always true; it depends on the details of the instrument (that is, the
* is not always true; it depends on the details of the instrument (that * synthesis algorithm) and how long the note has been going on. For example, a
* is, the synthesis algorithm) and how long the note has been going on. * voice may be synthesizing the sound of a single hand-clap. Because this sound
* For example, a voice may be synthesizing the sound of a single hand-clap. Because * dies away so quickly, it may become inaudible before a note-off message is
* this sound dies away so quickly, it may become inaudible before a note-off * received. In such a situation, the voice is still considered active even
* message is received. In such a situation, the voice is still considered active * though no sound is currently being produced.
* even though no sound is currently being produced.
* <p> * <p>
* Besides its active or inactive status, the <code>VoiceStatus</code> class * Besides its active or inactive status, the {@code VoiceStatus} class provides
* provides fields that reveal the voice's current MIDI channel, bank and * fields that reveal the voice's current MIDI channel, bank and program number,
* program number, MIDI note number, and MIDI volume. All of these can * MIDI note number, and MIDI volume. All of these can change during the course
* change during the course of a voice. While the voice is inactive, each * of a voice. While the voice is inactive, each of these fields has an
* of these fields has an unspecified value, so you should check the active * unspecified value, so you should check the active field first.
* field first.
*
* @see Synthesizer#getMaxPolyphony
* @see Synthesizer#getVoiceStatus
* *
* @author David Rivas * @author David Rivas
* @author Kara Kytle * @author Kara Kytle
* @see Synthesizer#getMaxPolyphony
* @see Synthesizer#getVoiceStatus
*/ */
public class VoiceStatus { public class VoiceStatus {
/** /**
* Indicates whether the voice is currently processing a MIDI note. * Indicates whether the voice is currently processing a MIDI note. See the
* See the explanation of * explanation of
* <A HREF="#description_of_active">active and inactive voices</A>. * <a HREF="#description_of_active">active and inactive voices</a>.
*/ */
public boolean active = false; public boolean active = false;
/** /**
* The MIDI channel on which this voice is playing. The value is a * The MIDI channel on which this voice is playing. The value is a
* zero-based channel number if the voice is active, or * zero-based channel number if the voice is active, or unspecified if the
* unspecified if the voice is inactive. * voice is inactive.
* *
* @see MidiChannel * @see MidiChannel
* @see #active * @see #active
*/ */
public int channel = 0; public int channel = 0;
/** /**
* The bank number of the instrument that this voice is currently using. * The bank number of the instrument that this voice is currently using.
* This is a number dictated by the MIDI bank-select message; it does not * This is a number dictated by the MIDI bank-select message; it does not
* refer to a <code>SoundBank</code> object. * refer to a {@code SoundBank} object. The value ranges from 0 to 16383 if
* The value ranges from 0 to 16383 if the voice is active, and is * the voice is active, and is unspecified if the voice is inactive.
* unspecified if the voice is inactive. *
* @see Patch * @see Patch
* @see Soundbank * @see Soundbank
* @see #active * @see #active
@ -119,11 +109,10 @@ public class VoiceStatus {
*/ */
public int bank = 0; public int bank = 0;
/** /**
* The program number of the instrument that this voice is currently using. * The program number of the instrument that this voice is currently using.
* The value ranges from 0 to 127 if the voice is active, and is * The value ranges from 0 to 127 if the voice is active, and is unspecified
* unspecified if the voice is inactive. * if the voice is inactive.
* *
* @see MidiChannel#getProgram * @see MidiChannel#getProgram
* @see Patch * @see Patch
@ -131,28 +120,24 @@ public class VoiceStatus {
*/ */
public int program = 0; public int program = 0;
/** /**
* The MIDI note that this voice is playing. The range for an active voice * The MIDI note that this voice is playing. The range for an active voice
* is from 0 to 127 in semitones, with 60 referring to Middle C. * is from 0 to 127 in semitones, with 60 referring to Middle C. The value
* The value is unspecified if the voice is inactive. * is unspecified if the voice is inactive.
* *
* @see MidiChannel#noteOn * @see MidiChannel#noteOn
* @see #active * @see #active
*/ */
public int note = 0; public int note = 0;
/** /**
* The current MIDI volume level for the voice. * The current MIDI volume level for the voice. The value ranges from 0 to
* The value ranges from 0 to 127 if the voice is active, and is * 127 if the voice is active, and is unspecified if the voice is inactive.
* unspecified if the voice is inactive.
* <p> * <p>
* Note that this value does not necessarily reflect * Note that this value does not necessarily reflect the instantaneous level
* the instantaneous level of the sound produced by this * of the sound produced by this voice; that level is the result of many
* voice; that level is the result of many contributing * contributing factors, including the current instrument and the shape of
* factors, including the current instrument and the * the amplitude envelope it produces.
* shape of the amplitude envelope it produces.
* *
* @see #active * @see #active
*/ */

View file

@ -26,13 +26,13 @@
package javax.sound.midi.spi; package javax.sound.midi.spi;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.URL; import java.net.URL;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiFileFormat; import javax.sound.midi.MidiFileFormat;
import javax.sound.midi.Sequence; import javax.sound.midi.Sequence;
import javax.sound.midi.InvalidMidiDataException;
/** /**
* A {@code MidiFileReader} supplies MIDI file-reading services. Classes * A {@code MidiFileReader} supplies MIDI file-reading services. Classes
@ -106,7 +106,7 @@ public abstract class MidiFileReader {
* @param stream the input stream from which the {@code Sequence} should * @param stream the input stream from which the {@code Sequence} should
* be constructed * be constructed
* @return a {@code Sequence} object based on the MIDI file data contained * @return a {@code Sequence} object based on the MIDI file data contained
* in the input stream. * in the input stream
* @throws InvalidMidiDataException if the stream does not point to valid * @throws InvalidMidiDataException if the stream does not point to valid
* MIDI file data recognized by the system * MIDI file data recognized by the system
* @throws IOException if an I/O exception occurs * @throws IOException if an I/O exception occurs

View file

@ -32,12 +32,12 @@ import java.net.URL;
import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.Soundbank; import javax.sound.midi.Soundbank;
import javax.sound.midi.Synthesizer;
/** /**
* A {@code SoundbankReader} supplies soundbank file-reading services. Concrete * A {@code SoundbankReader} supplies soundbank file-reading services. Concrete
* subclasses of {@code SoundbankReader} parse a given soundbank file, producing * subclasses of {@code SoundbankReader} parse a given soundbank file, producing
* a {@link javax.sound.midi.Soundbank} object that can be loaded into a * a {@link Soundbank} object that can be loaded into a {@link Synthesizer}.
* {@link javax.sound.midi.Synthesizer}.
* *
* @since 1.3 * @since 1.3
* @author Kara Kytle * @author Kara Kytle
@ -47,7 +47,7 @@ public abstract class SoundbankReader {
/** /**
* Obtains a soundbank object from the URL provided. * Obtains a soundbank object from the URL provided.
* *
* @param url URL representing the soundbank. * @param url URL representing the soundbank
* @return soundbank object * @return soundbank object
* @throws InvalidMidiDataException if the URL does not point to valid MIDI * @throws InvalidMidiDataException if the URL does not point to valid MIDI
* soundbank data recognized by this soundbank reader * soundbank data recognized by this soundbank reader

View file

@ -26,19 +26,19 @@
package javax.sound.sampled; package javax.sound.sampled;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URL; import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.Vector; import java.util.Vector;
import java.util.ArrayList;
import javax.sound.sampled.spi.AudioFileWriter;
import javax.sound.sampled.spi.AudioFileReader; import javax.sound.sampled.spi.AudioFileReader;
import javax.sound.sampled.spi.AudioFileWriter;
import javax.sound.sampled.spi.FormatConversionProvider; import javax.sound.sampled.spi.FormatConversionProvider;
import javax.sound.sampled.spi.MixerProvider; import javax.sound.sampled.spi.MixerProvider;
@ -60,14 +60,14 @@ import com.sun.media.sound.JDK13Services;
* <p> * <p>
* Properties can be used to specify the default mixer for specific line types. * Properties can be used to specify the default mixer for specific line types.
* Both system properties and a properties file are considered. The * Both system properties and a properties file are considered. The
* {@code sound.properties} properties file is read from an * "sound.properties" properties file is read from an implementation-specific
* implementation-specific location (typically it is the {@code lib} directory * location (typically it is the {@code lib} directory in the Java installation
* in the Java installation directory). If a property exists both as a system * directory). If a property exists both as a system property and in the
* property and in the properties file, the system property takes precedence. * properties file, the system property takes precedence. If none is specified,
* If none is specified, a suitable default is chosen among the available * a suitable default is chosen among the available devices. The syntax of the
* devices. The syntax of the properties file is specified in * properties file is specified in
* {@link java.util.Properties#load(InputStream) Properties.load}. The following * {@link Properties#load(InputStream) Properties.load}. The following table
* table lists the available property keys and which methods consider them: * lists the available property keys and which methods consider them:
* *
* <table border=0> * <table border=0>
* <caption>Audio System Property Keys</caption> * <caption>Audio System Property Keys</caption>
@ -100,12 +100,11 @@ import com.sun.media.sound.JDK13Services;
* *
* The property value consists of the provider class name and the mixer name, * The property value consists of the provider class name and the mixer name,
* separated by the hash mark (&quot;#&quot;). The provider class name is the * separated by the hash mark (&quot;#&quot;). The provider class name is the
* fully-qualified name of a concrete * fully-qualified name of a concrete {@link MixerProvider mixer provider}
* {@link javax.sound.sampled.spi.MixerProvider mixer provider} class. The mixer * class. The mixer name is matched against the {@code String} returned by the
* name is matched against the {@code String} returned by the {@code getName} * {@code getName} method of {@code Mixer.Info}. Either the class name, or the
* method of {@code Mixer.Info}. Either the class name, or the mixer name may be * mixer name may be omitted. If only the class name is specified, the trailing
* omitted. If only the class name is specified, the trailing hash mark is * hash mark is optional.
* optional.
* <p> * <p>
* If the provider class is specified, and it can be successfully retrieved from * If the provider class is specified, and it can be successfully retrieved from
* the installed providers, the list of {@code Mixer.Info} objects is retrieved * the installed providers, the list of {@code Mixer.Info} objects is retrieved
@ -1324,10 +1323,9 @@ public class AudioSystem {
* Obtains the set of format converters (codecs, transcoders, etc.) that are * Obtains the set of format converters (codecs, transcoders, etc.) that are
* currently installed on the system. * currently installed on the system.
* *
* @return an array of {@link javax.sound.sampled.spi.FormatConversionProvider * @return an array of {@link FormatConversionProvider} objects representing
* FormatConversionProvider} objects representing the available * the available format converters. If no format converters readers
* format converters. If no format converters readers are available * are available on the system, an array of length 0 is returned.
* on the system, an array of length 0 is returned.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static List<FormatConversionProvider> getFormatConversionProviders() { private static List<FormatConversionProvider> getFormatConversionProviders() {
@ -1338,10 +1336,9 @@ public class AudioSystem {
* Obtains the set of audio file readers that are currently installed on the * Obtains the set of audio file readers that are currently installed on the
* system. * system.
* *
* @return a List of {@link javax.sound.sampled.spi.AudioFileReader * @return a List of {@link AudioFileReader} objects representing the
* AudioFileReader} objects representing the installed audio file * installed audio file readers. If no audio file readers are
* readers. If no audio file readers are available on the system, an * available on the system, an empty List is returned.
* empty List is returned.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static List<AudioFileReader> getAudioFileReaders() { private static List<AudioFileReader> getAudioFileReaders() {
@ -1352,10 +1349,9 @@ public class AudioSystem {
* Obtains the set of audio file writers that are currently installed on the * Obtains the set of audio file writers that are currently installed on the
* system. * system.
* *
* @return a List of {@link javax.sound.sampled.spi.AudioFileWriter * @return a List of {@link AudioFileWriter} objects representing the
* AudioFileWriter} objects representing the available audio file * available audio file writers. If no audio file writers are
* writers. If no audio file writers are available on the system, an * available on the system, an empty List is returned.
* empty List is returned.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static List<AudioFileWriter> getAudioFileWriters() { private static List<AudioFileWriter> getAudioFileWriters() {

View file

@ -355,11 +355,11 @@ public interface DataLine extends Line {
* {@code true} for all formats returned by {@code getFormats()}. * {@code true} for all formats returned by {@code getFormats()}.
* <p> * <p>
* Some fields in the AudioFormat instances can be set to * Some fields in the AudioFormat instances can be set to
* {@link javax.sound.sampled.AudioSystem#NOT_SPECIFIED NOT_SPECIFIED} * {@link AudioSystem#NOT_SPECIFIED NOT_SPECIFIED} if that field does
* if that field does not apply to the format, or if the format supports * not apply to the format, or if the format supports a wide range of
* a wide range of values for that field. For example, a multi-channel * values for that field. For example, a multi-channel device supporting
* device supporting up to 64 channels, could set the channel field in * up to 64 channels, could set the channel field in the
* the {@code AudioFormat} instances returned by this method to * {@code AudioFormat} instances returned by this method to
* {@code NOT_SPECIFIED}. * {@code NOT_SPECIFIED}.
* *
* @return a set of supported audio formats * @return a set of supported audio formats

View file

@ -26,8 +26,8 @@
package javax.sound.sampled.spi; package javax.sound.sampled.spi;
import java.io.File; import java.io.File;
import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.URL; import java.net.URL;
import javax.sound.sampled.AudioFileFormat; import javax.sound.sampled.AudioFileFormat;

View file

@ -30,6 +30,7 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import static javax.sound.sampled.AudioFileFormat.Type; import static javax.sound.sampled.AudioFileFormat.Type;
@ -110,8 +111,7 @@ public abstract class AudioFileWriter {
* the length be written into the file header, and cannot be written from * the length be written into the file header, and cannot be written from
* start to finish unless the length is known in advance. An attempt to * start to finish unless the length is known in advance. An attempt to
* write such a file type will fail with an IOException if the length in the * write such a file type will fail with an IOException if the length in the
* audio file format is {@link javax.sound.sampled.AudioSystem#NOT_SPECIFIED * audio file format is {@link AudioSystem#NOT_SPECIFIED}.
* AudioSystem.NOT_SPECIFIED}.
* *
* @param stream the audio input stream containing audio data to be written * @param stream the audio input stream containing audio data to be written
* to the output stream * to the output stream

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -47,7 +47,7 @@ import javax.swing.event.*;
* new component implement the interface. Or the developer can * new component implement the interface. Or the developer can
* choose a wrapper based approach and provide a companion object which * choose a wrapper based approach and provide a companion object which
* implements the <code>CellEditor</code> interface (See * implements the <code>CellEditor</code> interface (See
* <code>JCellEditor</code> for example). The wrapper approach * <code>DefaultCellEditor</code> for example). The wrapper approach
* is particularly useful if the user want to use a 3rd party ISV * is particularly useful if the user want to use a 3rd party ISV
* editor with <code>JTable</code>, but the ISV didn't implement the * editor with <code>JTable</code>, but the ISV didn't implement the
* <code>CellEditor</code> interface. The user can simply create an object * <code>CellEditor</code> interface. The user can simply create an object

View file

@ -490,12 +490,33 @@ public class ImageIcon implements Icon, Serializable, Accessible {
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException throws ClassNotFoundException, IOException
{ {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
imageObserver = (ImageObserver) f.get("imageObserver", null);
description = (String) f.get("description", null);
width = f.get("width", -1);
height = f.get("height", -1);
accessibleContext = (AccessibleImageIcon) f.get("accessibleContext", null);
int w = s.readInt(); int w = s.readInt();
int h = s.readInt(); int h = s.readInt();
int[] pixels = (int[])(s.readObject()); int[] pixels = (int[])(s.readObject());
if (pixels == null && (w != -1 || h != -1)) {
throw new IllegalStateException("Inconsistent width and height"
+ " for null image [" + w + ", " + h + "]");
}
if (pixels != null && (w < 0 || h < 0)) {
throw new IllegalStateException("Inconsistent width and height"
+ " for image [" + w + ", " + h + "]");
}
if (w != getIconWidth() || h != getIconHeight()) {
throw new IllegalStateException("Inconsistent width and height"
+ " for image [" + w + ", " + h + "]");
}
if (pixels != null) { if (pixels != null) {
Toolkit tk = Toolkit.getDefaultToolkit(); Toolkit tk = Toolkit.getDefaultToolkit();
ColorModel cm = ColorModel.getRGBdefault(); ColorModel cm = ColorModel.getRGBdefault();

View file

@ -1888,7 +1888,7 @@ public abstract class JComponent extends Container implements Serializable,
* description: The preferred vertical alignment of the component. * description: The preferred vertical alignment of the component.
*/ */
public void setAlignmentY(float alignmentY) { public void setAlignmentY(float alignmentY) {
this.alignmentY = alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY; this.alignmentY = validateAlignment(alignmentY);
isAlignmentYSet = true; isAlignmentYSet = true;
} }
@ -1917,10 +1917,14 @@ public abstract class JComponent extends Container implements Serializable,
* description: The preferred horizontal alignment of the component. * description: The preferred horizontal alignment of the component.
*/ */
public void setAlignmentX(float alignmentX) { public void setAlignmentX(float alignmentX) {
this.alignmentX = alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX; this.alignmentX = validateAlignment(alignmentX);
isAlignmentXSet = true; isAlignmentXSet = true;
} }
private float validateAlignment(float alignment) {
return alignment > 1.0f ? 1.0f : alignment < 0.0f ? 0.0f : alignment;
}
/** /**
* Sets the input verifier for this component. * Sets the input verifier for this component.
* *
@ -5514,7 +5518,24 @@ public abstract class JComponent extends Container implements Serializable,
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException throws IOException, ClassNotFoundException
{ {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
isAlignmentXSet = f.get("isAlignmentXSet", false);
alignmentX = validateAlignment(f.get("alignmentX", 0f));
isAlignmentYSet = f.get("isAlignmentYSet", false);
alignmentY = validateAlignment(f.get("alignmentY", 0f));
listenerList = (EventListenerList) f.get("listenerList", null);
vetoableChangeSupport = (VetoableChangeSupport) f.get("vetoableChangeSupport", null);
autoscrolls = f.get("autoscrolls", false);
border = (Border) f.get("border", null);
flags = f.get("flags", 0);
inputVerifier = (InputVerifier) f.get("inputVerifier", null);
verifyInputWhenFocusTarget = f.get("verifyInputWhenFocusTarget", false);
popupMenu = (JPopupMenu) f.get("popupMenu", null);
focusInputMap = (InputMap) f.get("focusInputMap", null);
ancestorInputMap = (InputMap) f.get("ancestorInputMap", null);
windowInputMap = (ComponentInputMap) f.get("windowInputMap", null);
actionMap = (ActionMap) f.get("actionMap", null);
/* If there's no ReadObjectCallback for this stream yet, that is, if /* If there's no ReadObjectCallback for this stream yet, that is, if
* this is the first call to JComponent.readObject() for this * this is the first call to JComponent.readObject() for this

View file

@ -50,6 +50,8 @@ import java.awt.Toolkit;
import java.awt.event.*; import java.awt.event.*;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
/** /**
@ -460,10 +462,14 @@ public class JFileChooser extends JComponent implements Accessible {
* bound: false * bound: false
*/ */
public void setDragEnabled(boolean b) { public void setDragEnabled(boolean b) {
checkDragEnabled(b);
dragEnabled = b;
}
private static void checkDragEnabled(boolean b) {
if (b && GraphicsEnvironment.isHeadless()) { if (b && GraphicsEnvironment.isHeadless()) {
throw new HeadlessException(); throw new HeadlessException();
} }
dragEnabled = b;
} }
/** /**
@ -949,9 +955,7 @@ public class JFileChooser extends JComponent implements Accessible {
if(this.dialogType == dialogType) { if(this.dialogType == dialogType) {
return; return;
} }
if(!(dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG || dialogType == CUSTOM_DIALOG)) { checkDialogType(dialogType);
throw new IllegalArgumentException("Incorrect Dialog Type: " + dialogType);
}
int oldValue = this.dialogType; int oldValue = this.dialogType;
this.dialogType = dialogType; this.dialogType = dialogType;
if(dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG) { if(dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG) {
@ -960,6 +964,14 @@ public class JFileChooser extends JComponent implements Accessible {
firePropertyChange(DIALOG_TYPE_CHANGED_PROPERTY, oldValue, dialogType); firePropertyChange(DIALOG_TYPE_CHANGED_PROPERTY, oldValue, dialogType);
} }
private static void checkDialogType(int dialogType) {
if (!(dialogType == OPEN_DIALOG || dialogType == SAVE_DIALOG
|| dialogType == CUSTOM_DIALOG)) {
throw new IllegalArgumentException(
"Incorrect Dialog Type: " + dialogType);
}
}
/** /**
* Sets the string that goes in the <code>JFileChooser</code> window's * Sets the string that goes in the <code>JFileChooser</code> window's
* title bar. * title bar.
@ -1349,12 +1361,17 @@ public class JFileChooser extends JComponent implements Accessible {
return; return;
} }
if ((mode == FILES_ONLY) || (mode == DIRECTORIES_ONLY) || (mode == FILES_AND_DIRECTORIES)) { checkFileSelectionMode(mode);
int oldValue = fileSelectionMode; int oldValue = fileSelectionMode;
fileSelectionMode = mode; fileSelectionMode = mode;
firePropertyChange(FILE_SELECTION_MODE_CHANGED_PROPERTY, oldValue, fileSelectionMode); firePropertyChange(FILE_SELECTION_MODE_CHANGED_PROPERTY, oldValue, fileSelectionMode);
} else { }
throw new IllegalArgumentException("Incorrect Mode for file selection: " + mode);
private static void checkFileSelectionMode(int mode) {
if ((mode != FILES_ONLY) && (mode != DIRECTORIES_ONLY)
&& (mode != FILES_AND_DIRECTORIES)) {
throw new IllegalArgumentException(
"Incorrect Mode for file selection: " + mode);
} }
} }
@ -1901,7 +1918,43 @@ public class JFileChooser extends JComponent implements Accessible {
*/ */
private void readObject(java.io.ObjectInputStream in) private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
in.defaultReadObject(); ObjectInputStream.GetField f = in.readFields();
dialogTitle = (String) f.get("dialogTitle", null);
approveButtonText = (String) f.get("approveButtonText", null);
approveButtonToolTipText =
(String) f.get("approveButtonToolTipText", null);
approveButtonMnemonic = f.get("approveButtonMnemonic", 0);
@SuppressWarnings("unchecked")
Vector<FileFilter> newFilters = (Vector<FileFilter>) f.get("filters", null);
if (newFilters == null) {
throw new InvalidObjectException("Null filters");
}
filters = newFilters;
dialog = (JDialog) f.get("dialog", null);
int newDialogType = f.get("dialogType", OPEN_DIALOG);
checkDialogType(newDialogType);
dialogType = newDialogType;
returnValue = f.get("returnValue", 0);
accessory = (JComponent) f.get("accessory", null);
fileView = (FileView) f.get("fileView", null);
controlsShown = f.get("controlsShown", false);
useFileHiding = f.get("useFileHiding", false);
int newFileSelectionMode = f.get("fileSelectionMode", FILES_ONLY);
checkFileSelectionMode(newFileSelectionMode);
fileSelectionMode = newFileSelectionMode;
multiSelectionEnabled = f.get("multiSelectionEnabled", false);
useAcceptAllFileFilter = f.get("useAcceptAllFileFilter", false);
boolean newDragEnabled = f.get("dragEnabled", false);
checkDragEnabled(newDragEnabled);
dragEnabled = newDragEnabled;
fileFilter = (FileFilter) f.get("fileFilter", null);
fileSystemView = (FileSystemView) f.get("fileSystemView", null);
currentDirectory = (File) f.get("currentDirectory", null);
selectedFile = (File) f.get("selectedFile", null);
selectedFiles = (File[]) f.get("selectedFiles", null);
accessibleContext = (AccessibleContext) f.get("accessibleContext", null);
installShowFilesListener(); installShowFilesListener();
} }

View file

@ -24,14 +24,22 @@
*/ */
package javax.swing; package javax.swing;
import java.awt.*; import java.awt.AWTEvent;
import java.awt.event.*; import java.awt.BorderLayout;
import java.beans.PropertyChangeListener; import java.awt.Component;
import java.util.Locale; import java.awt.Container;
import java.util.Vector; import java.awt.Frame;
import java.io.Serializable; import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.event.WindowEvent;
import javax.accessibility.*; import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
/** /**
@ -297,7 +305,7 @@ public class JFrame extends Frame implements WindowConstants,
* @see #setDefaultCloseOperation * @see #setDefaultCloseOperation
* @see java.awt.Window#processWindowEvent * @see java.awt.Window#processWindowEvent
*/ */
protected void processWindowEvent(WindowEvent e) { protected void processWindowEvent(final WindowEvent e) {
super.processWindowEvent(e); super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) { if (e.getID() == WindowEvent.WINDOW_CLOSING) {
@ -308,22 +316,17 @@ public class JFrame extends Frame implements WindowConstants,
case DISPOSE_ON_CLOSE: case DISPOSE_ON_CLOSE:
dispose(); dispose();
break; break;
case DO_NOTHING_ON_CLOSE:
default:
break;
case EXIT_ON_CLOSE: case EXIT_ON_CLOSE:
// This needs to match the checkExit call in // This needs to match the checkExit call in
// setDefaultCloseOperation // setDefaultCloseOperation
System.exit(0); System.exit(0);
break; break;
case DO_NOTHING_ON_CLOSE:
default:
} }
} }
} }
// public void setMenuBar(MenuBar menu) {
// throw new IllegalComponentStateException("Please use setJMenuBar() with JFrame.");
// }
/** /**
* Sets the operation that will happen by default when * Sets the operation that will happen by default when
* the user initiates a "close" on this frame. * the user initiates a "close" on this frame.

View file

@ -158,8 +158,9 @@ public final class JLayer<V extends Component>
private LayerUI<? super V> layerUI; private LayerUI<? super V> layerUI;
private JPanel glassPane; private JPanel glassPane;
private long eventMask; private long eventMask;
private transient boolean isPainting; private transient boolean isPaintCalling;
private transient boolean isPaintingImmediately; private transient boolean isPaintImmediatelyCalling;
private transient boolean isImageUpdateCalling;
private static final LayerEventController eventController = private static final LayerEventController eventController =
new LayerEventController(); new LayerEventController();
@ -405,30 +406,57 @@ public final class JLayer<V extends Component>
* @param h the height of the region to be painted * @param h the height of the region to be painted
*/ */
public void paintImmediately(int x, int y, int w, int h) { public void paintImmediately(int x, int y, int w, int h) {
if (!isPaintingImmediately && getUI() != null) { if (!isPaintImmediatelyCalling && getUI() != null) {
isPaintingImmediately = true; isPaintImmediatelyCalling = true;
try { try {
getUI().paintImmediately(x, y, w, h, this); getUI().paintImmediately(x, y, w, h, this);
} finally { } finally {
isPaintingImmediately = false; isPaintImmediatelyCalling = false;
} }
} else { } else {
super.paintImmediately(x, y, w, h); super.paintImmediately(x, y, w, h);
} }
} }
/**
* Delegates its functionality to the
* {@link javax.swing.plaf.LayerUI#imageUpdate(java.awt.Image, int, int, int, int, int, JLayer)} method,
* if the {@code LayerUI} is set.
*
* @param img the image being observed
* @param infoflags see {@code imageUpdate} for more information
* @param x the <i>x</i> coordinate
* @param y the <i>y</i> coordinate
* @param w the width
* @param h the height
* @return {@code false} if the infoflags indicate that the
* image is completely loaded; {@code true} otherwise.
*/
public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
if (!isImageUpdateCalling && getUI() != null) {
isImageUpdateCalling = true;
try {
return getUI().imageUpdate(img, infoflags, x, y, w, h, this);
} finally {
isImageUpdateCalling = false;
}
} else {
return super.imageUpdate(img, infoflags, x, y, w, h);
}
}
/** /**
* Delegates all painting to the {@link javax.swing.plaf.LayerUI} object. * Delegates all painting to the {@link javax.swing.plaf.LayerUI} object.
* *
* @param g the {@code Graphics} to render to * @param g the {@code Graphics} to render to
*/ */
public void paint(Graphics g) { public void paint(Graphics g) {
if (!isPainting) { if (!isPaintCalling) {
isPainting = true; isPaintCalling = true;
try { try {
super.paintComponent(g); super.paintComponent(g);
} finally { } finally {
isPainting = false; isPaintCalling = false;
} }
} else { } else {
super.paint(g); super.paint(g);
@ -646,15 +674,21 @@ public final class JLayer<V extends Component>
return 1; return 1;
} }
@SuppressWarnings("unchecked")
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
if (layerUI != null) {
setUI(layerUI); view = (V) f.get("view", null);
} glassPane = (JPanel) f.get("glassPane", null);
eventMask = f.get("eventMask", 0l);
if (eventMask != 0) { if (eventMask != 0) {
eventController.updateAWTEventListener(0, eventMask); eventController.updateAWTEventListener(0, eventMask);
} }
LayerUI<V> newLayerUI = (LayerUI<V>) f.get("layerUI", null);
if (newLayerUI != null) {
setUI(newLayerUI);
}
} }
/** /**

View file

@ -43,13 +43,10 @@ import java.awt.event.WindowEvent;
import java.awt.event.ComponentAdapter; import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.io.IOException; import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Vector; import java.util.Vector;
import javax.swing.plaf.OptionPaneUI; import javax.swing.plaf.OptionPaneUI;
import javax.swing.event.InternalFrameEvent; import javax.swing.event.InternalFrameEvent;
@ -2055,15 +2052,22 @@ public class JOptionPane extends JComponent implements Accessible
* description: The option pane's message type. * description: The option pane's message type.
*/ */
public void setMessageType(int newType) { public void setMessageType(int newType) {
checkMessageType(newType);
int oldType = messageType;
messageType = newType;
firePropertyChange(MESSAGE_TYPE_PROPERTY, oldType, messageType);
}
private static void checkMessageType(int newType){
if(newType != ERROR_MESSAGE && newType != INFORMATION_MESSAGE && if(newType != ERROR_MESSAGE && newType != INFORMATION_MESSAGE &&
newType != WARNING_MESSAGE && newType != QUESTION_MESSAGE && newType != WARNING_MESSAGE && newType != QUESTION_MESSAGE &&
newType != PLAIN_MESSAGE) newType != PLAIN_MESSAGE)
throw new RuntimeException("JOptionPane: type must be one of JOptionPane.ERROR_MESSAGE, JOptionPane.INFORMATION_MESSAGE, JOptionPane.WARNING_MESSAGE, JOptionPane.QUESTION_MESSAGE or JOptionPane.PLAIN_MESSAGE"); throw new RuntimeException("JOptionPane: type must be one of"
+ " JOptionPane.ERROR_MESSAGE,"
int oldType = messageType; + " JOptionPane.INFORMATION_MESSAGE,"
+ " JOptionPane.WARNING_MESSAGE,"
messageType = newType; + " JOptionPane.QUESTION_MESSAGE"
firePropertyChange(MESSAGE_TYPE_PROPERTY, oldType, messageType); + " or JOptionPane.PLAIN_MESSAGE");
} }
/** /**
@ -2097,16 +2101,23 @@ public class JOptionPane extends JComponent implements Accessible
* description: The option pane's option type. * description: The option pane's option type.
*/ */
public void setOptionType(int newType) { public void setOptionType(int newType) {
if(newType != DEFAULT_OPTION && newType != YES_NO_OPTION && checkOptionType(newType);
newType != YES_NO_CANCEL_OPTION && newType != OK_CANCEL_OPTION)
throw new RuntimeException("JOptionPane: option type must be one of JOptionPane.DEFAULT_OPTION, JOptionPane.YES_NO_OPTION, JOptionPane.YES_NO_CANCEL_OPTION or JOptionPane.OK_CANCEL_OPTION");
int oldType = optionType; int oldType = optionType;
optionType = newType; optionType = newType;
firePropertyChange(OPTION_TYPE_PROPERTY, oldType, optionType); firePropertyChange(OPTION_TYPE_PROPERTY, oldType, optionType);
} }
private static void checkOptionType(int newType) {
if (newType != DEFAULT_OPTION && newType != YES_NO_OPTION
&& newType != YES_NO_CANCEL_OPTION
&& newType != OK_CANCEL_OPTION) {
throw new RuntimeException("JOptionPane: option type must be one of"
+ " JOptionPane.DEFAULT_OPTION, JOptionPane.YES_NO_OPTION,"
+ " JOptionPane.YES_NO_CANCEL_OPTION"
+ " or JOptionPane.OK_CANCEL_OPTION");
}
}
/** /**
* Returns the type of options that are displayed. * Returns the type of options that are displayed.
* *
@ -2385,7 +2396,15 @@ public class JOptionPane extends JComponent implements Accessible
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
int newMessageType = f.get("messageType", 0);
checkMessageType(newMessageType);
messageType = newMessageType;
int newOptionType = f.get("optionType", 0);
checkOptionType(newOptionType);
optionType = newOptionType;
wantsInput = f.get("wantsInput", false);
Vector<?> values = (Vector)s.readObject(); Vector<?> values = (Vector)s.readObject();
int indexCounter = 0; int indexCounter = 0;

View file

@ -1345,7 +1345,20 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement {
// implements javax.swing.MenuElement // implements javax.swing.MenuElement
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
int newDesiredLocationX = f.get("desiredLocationX", 0);
int newDesiredLocationY = f.get("desiredLocationY", 0);
Point p = adjustPopupLocationToFitScreen(
newDesiredLocationX, newDesiredLocationY);
desiredLocationX = p.x;
desiredLocationY = p.y;
label = (String) f.get("label", null);
paintBorder = f.get("paintBorder", false);
margin = (Insets) f.get("margin", null);
lightWeightPopup = f.get("lightWeightPopup", false);
selectionModel = (SingleSelectionModel) f.get("selectionModel", null);
Vector<?> values = (Vector)s.readObject(); Vector<?> values = (Vector)s.readObject();
int indexCounter = 0; int indexCounter = 0;

View file

@ -495,10 +495,7 @@ public class JTabbedPane extends JComponent
* *
*/ */
public void setTabPlacement(int tabPlacement) { public void setTabPlacement(int tabPlacement) {
if (tabPlacement != TOP && tabPlacement != LEFT && checkTabPlacement(tabPlacement);
tabPlacement != BOTTOM && tabPlacement != RIGHT) {
throw new IllegalArgumentException("illegal tab placement: must be TOP, BOTTOM, LEFT, or RIGHT");
}
if (this.tabPlacement != tabPlacement) { if (this.tabPlacement != tabPlacement) {
int oldValue = this.tabPlacement; int oldValue = this.tabPlacement;
this.tabPlacement = tabPlacement; this.tabPlacement = tabPlacement;
@ -508,6 +505,14 @@ public class JTabbedPane extends JComponent
} }
} }
private static void checkTabPlacement(int tabPlacement) {
if (tabPlacement != TOP && tabPlacement != LEFT &&
tabPlacement != BOTTOM && tabPlacement != RIGHT) {
throw new IllegalArgumentException("illegal tab placement:"
+ " must be TOP, BOTTOM, LEFT, or RIGHT");
}
}
/** /**
* Returns the policy used by the tabbedpane to layout the tabs when all the * Returns the policy used by the tabbedpane to layout the tabs when all the
* tabs will not fit within a single run. * tabs will not fit within a single run.
@ -551,9 +556,7 @@ public class JTabbedPane extends JComponent
* *
*/ */
public void setTabLayoutPolicy(int tabLayoutPolicy) { public void setTabLayoutPolicy(int tabLayoutPolicy) {
if (tabLayoutPolicy != WRAP_TAB_LAYOUT && tabLayoutPolicy != SCROLL_TAB_LAYOUT) { checkTabLayoutPolicy(tabLayoutPolicy);
throw new IllegalArgumentException("illegal tab layout policy: must be WRAP_TAB_LAYOUT or SCROLL_TAB_LAYOUT");
}
if (this.tabLayoutPolicy != tabLayoutPolicy) { if (this.tabLayoutPolicy != tabLayoutPolicy) {
int oldValue = this.tabLayoutPolicy; int oldValue = this.tabLayoutPolicy;
this.tabLayoutPolicy = tabLayoutPolicy; this.tabLayoutPolicy = tabLayoutPolicy;
@ -563,6 +566,14 @@ public class JTabbedPane extends JComponent
} }
} }
private static void checkTabLayoutPolicy(int tabLayoutPolicy) {
if (tabLayoutPolicy != WRAP_TAB_LAYOUT
&& tabLayoutPolicy != SCROLL_TAB_LAYOUT) {
throw new IllegalArgumentException("illegal tab layout policy:"
+ " must be WRAP_TAB_LAYOUT or SCROLL_TAB_LAYOUT");
}
}
/** /**
* Returns the currently selected index for this tabbedpane. * Returns the currently selected index for this tabbedpane.
* Returns -1 if there is no currently selected tab. * Returns -1 if there is no currently selected tab.
@ -1816,7 +1827,19 @@ public class JTabbedPane extends JComponent
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException throws IOException, ClassNotFoundException
{ {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
int newTabPlacement = f.get("tabPlacement", TOP);
checkTabPlacement(newTabPlacement);
tabPlacement = newTabPlacement;
int newTabLayoutPolicy = f.get("tabLayoutPolicy", 0);
checkTabLayoutPolicy(newTabLayoutPolicy);
tabLayoutPolicy = newTabLayoutPolicy;
model = (SingleSelectionModel) f.get("model", null);
haveRegistered = f.get("haveRegistered", false);
changeListener = (ChangeListener) f.get("changeListener", null);
visComp = (Component) f.get("visComp", null);
if ((ui != null) && (getUIClassID().equals(uiClassID))) { if ((ui != null) && (getUIClassID().equals(uiClassID))) {
ui.installUI(this); ui.installUI(this);
} }

View file

@ -37,6 +37,7 @@ import java.beans.*;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InvalidObjectException;
import javax.accessibility.*; import javax.accessibility.*;
@ -1203,11 +1204,7 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* AUTO_RESIZE_ALL_COLUMNS JTable.AUTO_RESIZE_ALL_COLUMNS * AUTO_RESIZE_ALL_COLUMNS JTable.AUTO_RESIZE_ALL_COLUMNS
*/ */
public void setAutoResizeMode(int mode) { public void setAutoResizeMode(int mode) {
if ((mode == AUTO_RESIZE_OFF) || if (isValidAutoResizeMode(mode)) {
(mode == AUTO_RESIZE_NEXT_COLUMN) ||
(mode == AUTO_RESIZE_SUBSEQUENT_COLUMNS) ||
(mode == AUTO_RESIZE_LAST_COLUMN) ||
(mode == AUTO_RESIZE_ALL_COLUMNS)) {
int old = autoResizeMode; int old = autoResizeMode;
autoResizeMode = mode; autoResizeMode = mode;
resizeAndRepaint(); resizeAndRepaint();
@ -1218,6 +1215,14 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
} }
} }
private static boolean isValidAutoResizeMode(int mode) {
return (mode == AUTO_RESIZE_OFF)
|| (mode == AUTO_RESIZE_NEXT_COLUMN)
|| (mode == AUTO_RESIZE_SUBSEQUENT_COLUMNS)
|| (mode == AUTO_RESIZE_LAST_COLUMN)
|| (mode == AUTO_RESIZE_ALL_COLUMNS);
}
/** /**
* Returns the auto resize mode of the table. The default mode * Returns the auto resize mode of the table. The default mode
* is AUTO_RESIZE_SUBSEQUENT_COLUMNS. * is AUTO_RESIZE_SUBSEQUENT_COLUMNS.
@ -1439,10 +1444,14 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* bound: false * bound: false
*/ */
public void setDragEnabled(boolean b) { public void setDragEnabled(boolean b) {
checkDragEnabled(b);
dragEnabled = b;
}
private void checkDragEnabled(boolean b) {
if (b && GraphicsEnvironment.isHeadless()) { if (b && GraphicsEnvironment.isHeadless()) {
throw new HeadlessException(); throw new HeadlessException();
} }
dragEnabled = b;
} }
/** /**
@ -1489,6 +1498,11 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
* @since 1.6 * @since 1.6
*/ */
public final void setDropMode(DropMode dropMode) { public final void setDropMode(DropMode dropMode) {
checkDropMode(dropMode);
this.dropMode = dropMode;
}
private static void checkDropMode(DropMode dropMode) {
if (dropMode != null) { if (dropMode != null) {
switch (dropMode) { switch (dropMode) {
case USE_SELECTION: case USE_SELECTION:
@ -1499,14 +1513,12 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
case ON_OR_INSERT: case ON_OR_INSERT:
case ON_OR_INSERT_ROWS: case ON_OR_INSERT_ROWS:
case ON_OR_INSERT_COLS: case ON_OR_INSERT_COLS:
this.dropMode = dropMode;
return; return;
} }
} }
throw new IllegalArgumentException(dropMode
throw new IllegalArgumentException(dropMode + ": Unsupported drop mode for table"); + ": Unsupported drop mode for table");
} }
/** /**
* Returns the drop mode for this component. * Returns the drop mode for this component.
* *
@ -5865,7 +5877,75 @@ public class JTable extends JComponent implements TableModelListener, Scrollable
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException throws IOException, ClassNotFoundException
{ {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
TableModel newDataModel = (TableModel) f.get("dataModel", null);
if (newDataModel == null) {
throw new InvalidObjectException("Null dataModel");
}
dataModel = newDataModel;
TableColumnModel newColumnModel = (TableColumnModel) f.get("columnModel", null);
if (newColumnModel == null) {
throw new InvalidObjectException("Null columnModel");
}
columnModel = newColumnModel;
ListSelectionModel newSelectionModel = (ListSelectionModel) f.get("selectionModel", null);
if (newSelectionModel == null) {
throw new InvalidObjectException("Null selectionModel");
}
selectionModel = newSelectionModel;
tableHeader = (JTableHeader) f.get("tableHeader", null);
int newRowHeight = f.get("rowHeight", 0);
if (newRowHeight <= 0) {
throw new InvalidObjectException("Row height less than 1");
}
rowHeight = newRowHeight;
rowMargin = f.get("rowMargin", 0);
Color newGridColor = (Color) f.get("gridColor", null);
if (newGridColor == null) {
throw new InvalidObjectException("Null gridColor");
}
gridColor = newGridColor;
showHorizontalLines = f.get("showHorizontalLines", false);
showVerticalLines = f.get("showVerticalLines", false);
int newAutoResizeMode = f.get("autoResizeMode", 0);
if (!isValidAutoResizeMode(newAutoResizeMode)) {
throw new InvalidObjectException("autoResizeMode is not valid");
}
autoResizeMode = newAutoResizeMode;
autoCreateColumnsFromModel = f.get("autoCreateColumnsFromModel", false);
preferredViewportSize = (Dimension) f.get("preferredViewportSize", null);
rowSelectionAllowed = f.get("rowSelectionAllowed", false);
cellSelectionEnabled = f.get("cellSelectionEnabled", false);
selectionForeground = (Color) f.get("selectionForeground", null);
selectionBackground = (Color) f.get("selectionBackground", null);
rowModel = (SizeSequence) f.get("rowModel", null);
boolean newDragEnabled = f.get("dragEnabled", false);
checkDragEnabled(newDragEnabled);
dragEnabled = newDragEnabled;
surrendersFocusOnKeystroke = f.get("surrendersFocusOnKeystroke", false);
editorRemover = (PropertyChangeListener) f.get("editorRemover", null);
columnSelectionAdjusting = f.get("columnSelectionAdjusting", false);
rowSelectionAdjusting = f.get("rowSelectionAdjusting", false);
printError = (Throwable) f.get("printError", null);
isRowHeightSet = f.get("isRowHeightSet", false);
updateSelectionOnSort = f.get("updateSelectionOnSort", false);
ignoreSortChange = f.get("ignoreSortChange", false);
sorterChanged = f.get("sorterChanged", false);
autoCreateRowSorter = f.get("autoCreateRowSorter", false);
fillsViewportHeight = f.get("fillsViewportHeight", false);
DropMode newDropMode = (DropMode) f.get("dropMode",
DropMode.USE_SELECTION);
checkDropMode(newDropMode);
dropMode = newDropMode;
if ((ui != null) && (getUIClassID().equals(uiClassID))) { if ((ui != null) && (getUIClassID().equals(uiClassID))) {
ui.installUI(this); ui.installUI(this);
} }

View file

@ -1216,10 +1216,14 @@ public class JTree extends JComponent implements Scrollable, Accessible
* bound: false * bound: false
*/ */
public void setDragEnabled(boolean b) { public void setDragEnabled(boolean b) {
checkDragEnabled(b);
dragEnabled = b;
}
private static void checkDragEnabled(boolean b) {
if (b && GraphicsEnvironment.isHeadless()) { if (b && GraphicsEnvironment.isHeadless()) {
throw new HeadlessException(); throw new HeadlessException();
} }
dragEnabled = b;
} }
/** /**
@ -1262,18 +1266,23 @@ public class JTree extends JComponent implements Scrollable, Accessible
* @since 1.6 * @since 1.6
*/ */
public final void setDropMode(DropMode dropMode) { public final void setDropMode(DropMode dropMode) {
checkDropMode(dropMode);
this.dropMode = dropMode;
}
private static void checkDropMode(DropMode dropMode) {
if (dropMode != null) { if (dropMode != null) {
switch (dropMode) { switch (dropMode) {
case USE_SELECTION: case USE_SELECTION:
case ON: case ON:
case INSERT: case INSERT:
case ON_OR_INSERT: case ON_OR_INSERT:
this.dropMode = dropMode;
return; return;
} }
} }
throw new IllegalArgumentException(dropMode + ": Unsupported drop mode for tree"); throw new IllegalArgumentException(dropMode +
": Unsupported drop mode for tree");
} }
/** /**
@ -3089,7 +3098,34 @@ public class JTree extends JComponent implements Scrollable, Accessible
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
rootVisible = f.get("rootVisible", false);
rowHeight = f.get("rowHeight", 0);
rowHeightSet = f.get("rowHeightSet", false);
showsRootHandles = f.get("showsRootHandles", false);
showsRootHandlesSet = f.get("showsRootHandlesSet", false);
editable = f.get("editable", false);
largeModel = f.get("largeModel", false);
visibleRowCount = f.get("visibleRowCount", 0);
invokesStopCellEditing = f.get("invokesStopCellEditing", false);
scrollsOnExpand = f.get("scrollsOnExpand", false);
scrollsOnExpandSet = f.get("scrollsOnExpandSet", false);
toggleClickCount = f.get("toggleClickCount", 0);
leadPath = (TreePath) f.get("leadPath", null);
anchorPath = (TreePath) f.get("anchorPath", null);
expandsSelectedPaths = f.get("expandsSelectedPaths", false);
settingUI = f.get("settingUI", false);
boolean newDragEnabled = f.get("dragEnabled", false);
checkDragEnabled(newDragEnabled);
dragEnabled = newDragEnabled;
DropMode newDropMode = (DropMode) f.get("dropMode",
DropMode.USE_SELECTION);
checkDropMode(newDropMode);
dropMode = newDropMode;
expandRow = f.get("expandRow", -1);
dropTimer = (TreeTimer) f.get("dropTimer", null);
// Create an instance of expanded state. // Create an instance of expanded state.

View file

@ -194,7 +194,23 @@ final class LegacyGlueFocusTraversalPolicy extends FocusTraversalPolicy
private void readObject(ObjectInputStream in) private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException throws IOException, ClassNotFoundException
{ {
in.defaultReadObject(); ObjectInputStream.GetField f = in.readFields();
@SuppressWarnings("unchecked")
HashMap<Component, Component> newForwardMap =
(HashMap<Component, Component> ) f.get("forwardMap", null);
if (newForwardMap == null) {
throw new InvalidObjectException("Null forwardMap");
}
forwardMap = newForwardMap;
@SuppressWarnings("unchecked")
HashMap<Component, Component> newBackwardMap =
(HashMap<Component, Component>) f.get("backwardMap", null);
if (newBackwardMap == null) {
throw new InvalidObjectException("Null backwardMap");
}
backwardMap = newBackwardMap;
delegatePolicy = (FocusTraversalPolicy)in.readObject(); delegatePolicy = (FocusTraversalPolicy)in.readObject();
delegateManager = (DefaultFocusManager)in.readObject(); delegateManager = (DefaultFocusManager)in.readObject();
} }

View file

@ -374,7 +374,8 @@ public class SwingUtilities implements SwingConstants
sourceWheelEvent.isPopupTrigger(), sourceWheelEvent.isPopupTrigger(),
sourceWheelEvent.getScrollType(), sourceWheelEvent.getScrollType(),
sourceWheelEvent.getScrollAmount(), sourceWheelEvent.getScrollAmount(),
sourceWheelEvent.getWheelRotation()); sourceWheelEvent.getWheelRotation(),
sourceWheelEvent.getPreciseWheelRotation());
} }
else if (sourceEvent instanceof MenuDragMouseEvent) { else if (sourceEvent instanceof MenuDragMouseEvent) {
MenuDragMouseEvent sourceMenuDragEvent = (MenuDragMouseEvent)sourceEvent; MenuDragMouseEvent sourceMenuDragEvent = (MenuDragMouseEvent)sourceEvent;

View file

@ -401,14 +401,15 @@ public class Timer implements Serializable
* @see #setInitialDelay * @see #setInitialDelay
*/ */
public void setDelay(int delay) { public void setDelay(int delay) {
if (delay < 0) { checkDelay(delay, "Invalid delay: ");
throw new IllegalArgumentException("Invalid delay: " + delay);
}
else {
this.delay = delay; this.delay = delay;
} }
}
private static void checkDelay(int delay, String message) {
if (delay < 0) {
throw new IllegalArgumentException(message + delay);
}
}
/** /**
* Returns the delay, in milliseconds, * Returns the delay, in milliseconds,
@ -435,14 +436,9 @@ public class Timer implements Serializable
* @see #setDelay * @see #setDelay
*/ */
public void setInitialDelay(int initialDelay) { public void setInitialDelay(int initialDelay) {
if (initialDelay < 0) { checkDelay(initialDelay, "Invalid initial delay: ");
throw new IllegalArgumentException("Invalid initial delay: " +
initialDelay);
}
else {
this.initialDelay = initialDelay; this.initialDelay = initialDelay;
} }
}
/** /**
@ -638,7 +634,26 @@ public class Timer implements Serializable
throws ClassNotFoundException, IOException throws ClassNotFoundException, IOException
{ {
this.acc = AccessController.getContext(); this.acc = AccessController.getContext();
in.defaultReadObject(); ObjectInputStream.GetField f = in.readFields();
EventListenerList newListenerList = (EventListenerList)
f.get("listenerList", null);
if (newListenerList == null) {
throw new InvalidObjectException("Null listenerList");
}
listenerList = newListenerList;
int newInitialDelay = f.get("initialDelay", 0);
checkDelay(newInitialDelay, "Invalid initial delay: ");
initialDelay = newInitialDelay;
int newDelay = f.get("delay", 0);
checkDelay(newDelay, "Invalid delay: ");
delay = newDelay;
repeats = f.get("repeats", false);
coalesce = f.get("coalesce", false);
actionCommand = (String) f.get("actionCommand", null);
} }
/* /*

View file

@ -107,7 +107,7 @@ public final class SwingPropertyChangeSupport extends PropertyChangeSupport {
* @see #SwingPropertyChangeSupport(Object sourceBean, boolean notifyOnEDT) * @see #SwingPropertyChangeSupport(Object sourceBean, boolean notifyOnEDT)
* @since 1.6 * @since 1.6
*/ */
public final boolean isNotifyOnEDT() { public boolean isNotifyOnEDT() {
return notifyOnEDT; return notifyOnEDT;
} }

View file

@ -37,16 +37,25 @@ public abstract class ComboBoxUI extends ComponentUI {
/** /**
* Set the visibility of the popup * Set the visibility of the popup
*
* @param c a {@code JComboBox}
* @param v a {@code boolean} determining the visibilty of the popup
*/ */
public abstract void setPopupVisible( JComboBox<?> c, boolean v ); public abstract void setPopupVisible( JComboBox<?> c, boolean v );
/** /**
* Determine the visibility of the popup * Determine the visibility of the popup
*
* @param c a {@code JComboBox}
* @return true if popup of the {@code JComboBox} is visible
*/ */
public abstract boolean isPopupVisible( JComboBox<?> c ); public abstract boolean isPopupVisible( JComboBox<?> c );
/** /**
* Determine whether or not the combo box itself is traversable * Determine whether or not the combo box itself is traversable
*
* @param c a {@code JComboBox}
* @return true if the given {@code JComboBox} is traversable
*/ */
public abstract boolean isFocusTraversable( JComboBox<?> c ); public abstract boolean isFocusTraversable( JComboBox<?> c );
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -173,7 +173,8 @@ public abstract class ComponentUI {
* this argument is often ignored, * this argument is often ignored,
* but might be used if the UI object is stateless * but might be used if the UI object is stateless
* and shared by multiple components * and shared by multiple components
* * @return a {@code Dimension} object containing given component's preferred
* size appropriate for the look and feel
* @see javax.swing.JComponent#getPreferredSize * @see javax.swing.JComponent#getPreferredSize
* @see java.awt.LayoutManager#preferredLayoutSize * @see java.awt.LayoutManager#preferredLayoutSize
*/ */
@ -240,7 +241,8 @@ public abstract class ComponentUI {
* and shared by multiple components * and shared by multiple components
* @param x the <i>x</i> coordinate of the point * @param x the <i>x</i> coordinate of the point
* @param y the <i>y</i> coordinate of the point * @param y the <i>y</i> coordinate of the point
* * @return {@code true} if the specified {@code x,y} location is contained
* within the look and feel's defined shape for the given component
* @see javax.swing.JComponent#contains * @see javax.swing.JComponent#contains
* @see java.awt.Component#contains * @see java.awt.Component#contains
*/ */
@ -258,6 +260,9 @@ public abstract class ComponentUI {
* stateful, then it should return a new instance per component. * stateful, then it should return a new instance per component.
* The default implementation of this method throws an error, as it * The default implementation of this method throws an error, as it
* should never be invoked. * should never be invoked.
*
* @param c a {@code JComponent} for which to create a UI delegate
* @return a {@code ComponentUI} object for {@code c}
*/ */
public static ComponentUI createUI(JComponent c) { public static ComponentUI createUI(JComponent c) {
throw new Error("ComponentUI.createUI not implemented."); throw new Error("ComponentUI.createUI not implemented.");
@ -332,8 +337,9 @@ public abstract class ComponentUI {
* <code>Component.AccessibleAWTComponent.getAccessibleChildrenCount()</code> instead * <code>Component.AccessibleAWTComponent.getAccessibleChildrenCount()</code> instead
* of this method. * of this method.
* *
* @see #getAccessibleChild * @param c {@code JComponent} for which to get count of accessible children
* @return the number of accessible children in the object * @return the number of accessible children in the object
* @see #getAccessibleChild
*/ */
public int getAccessibleChildrenCount(JComponent c) { public int getAccessibleChildrenCount(JComponent c) {
return SwingUtilities.getAccessibleChildrenCount(c); return SwingUtilities.getAccessibleChildrenCount(c);
@ -351,9 +357,10 @@ public abstract class ComponentUI {
* <code>Component.AccessibleAWTComponent.getAccessibleChild()</code> instead of * <code>Component.AccessibleAWTComponent.getAccessibleChild()</code> instead of
* this method. * this method.
* *
* @see #getAccessibleChildrenCount * @param c a {@code JComponent} for which to get a child object
* @param i zero-based index of child * @param i zero-based index of child
* @return the <code>i</code>th <code>Accessible</code> child of the object * @return the <code>i</code>th <code>Accessible</code> child of the object
* @see #getAccessibleChildrenCount
*/ */
public Accessible getAccessibleChild(JComponent c, int i) { public Accessible getAccessibleChild(JComponent c, int i) {
return SwingUtilities.getAccessibleChild(c, i); return SwingUtilities.getAccessibleChild(c, i);

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -52,6 +52,8 @@ public abstract class FileChooserUI extends ComponentUI
* <code>JFileChooser</code> will use this button as default button * <code>JFileChooser</code> will use this button as default button
* for dialog windows. * for dialog windows.
* *
* @param fc the {@code JFileChooser} whose default button is requested
* @return the default JButton for current look and feel
* @since 1.7 * @since 1.7
*/ */
public JButton getDefaultButton(JFileChooser fc) { public JButton getDefaultButton(JFileChooser fc) {

View file

@ -716,10 +716,22 @@ public class LayerUI<V extends Component>
* @param y the y value of the region to be painted * @param y the y value of the region to be painted
* @param width the width of the region to be painted * @param width the width of the region to be painted
* @param height the height of the region to be painted * @param height the height of the region to be painted
* * @param l a {@code JLayer} component
* @see JComponent#paintImmediately(int, int, int, int) * @see JComponent#paintImmediately(int, int, int, int)
*/ */
public void paintImmediately(int x, int y, int width, int height, JLayer<? extends V> l) { public void paintImmediately(int x, int y, int width, int height, JLayer<? extends V> l) {
l.paintImmediately(x, y, width, height); l.paintImmediately(x, y, width, height);
} }
/**
* Delegates its functionality to the default implementation of the {@code JLayer.imageUpdate} method
* which is inherited from {@code JLayer}'s base classes.
* <p>
* This method is to be overridden instead of {@code JLayer.imageUpdate}.
* <p>
* <b>Note:</b> This method is usually called <b>not</b> on the Event Dispatching Thread.
*/
public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h, JLayer<? extends V> l) {
return l.imageUpdate(img, infoflags, x, y, w, h);
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -38,12 +38,18 @@ public abstract class OptionPaneUI extends ComponentUI
/** /**
* Requests the component representing the default value to have * Requests the component representing the default value to have
* focus. * focus.
*
* @param op a {@code JOptionPane}
*/ */
public abstract void selectInitialValue(JOptionPane op); public abstract void selectInitialValue(JOptionPane op);
/** /**
* Returns true if the user has supplied instances of Component for * Returns true if the user has supplied instances of Component for
* either the options or message. * either the options or message.
*
* @param op a {@code JOptionPane}
* @return {@code true} if the given {@code JOptionPane} contains user
* created {@code Component}s
*/ */
public abstract boolean containsCustomComponents(JOptionPane op); public abstract boolean containsCustomComponents(JOptionPane op);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,6 +39,11 @@ import javax.swing.JPopupMenu;
public abstract class PopupMenuUI extends ComponentUI { public abstract class PopupMenuUI extends ComponentUI {
/** /**
* Returns whether or not the given {@code MouseEvent} is the popup menu
* trigger event for the platform
*
* @param e a {@code MouseEvent}
* @return true if the {@code MouseEvent e} is the popup menu trigger
* @since 1.3 * @since 1.3
*/ */
public boolean isPopupTrigger(MouseEvent e) { public boolean isPopupTrigger(MouseEvent e) {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -38,32 +38,49 @@ public abstract class SplitPaneUI extends ComponentUI
/** /**
* Messaged to relayout the JSplitPane based on the preferred size * Messaged to relayout the JSplitPane based on the preferred size
* of the children components. * of the children components.
*
* @param jc a {@code JSplitPane}
*/ */
public abstract void resetToPreferredSizes(JSplitPane jc); public abstract void resetToPreferredSizes(JSplitPane jc);
/** /**
* Sets the location of the divider to location. * Sets the location of the divider to location.
*
* @param jc a {@code JSplitPane}
* @param location an integer specifying the location of the divider
*/ */
public abstract void setDividerLocation(JSplitPane jc, int location); public abstract void setDividerLocation(JSplitPane jc, int location);
/** /**
* Returns the location of the divider. * Returns the location of the divider.
*
* @param jc a {@code JSplitPane}
* @return an integer specifying the location of the divider
*/ */
public abstract int getDividerLocation(JSplitPane jc); public abstract int getDividerLocation(JSplitPane jc);
/** /**
* Returns the minimum possible location of the divider. * Returns the minimum possible location of the divider.
*
* @param jc a {@code JSplitPane}
* @return and integer specifying the minimum location of the divider
*/ */
public abstract int getMinimumDividerLocation(JSplitPane jc); public abstract int getMinimumDividerLocation(JSplitPane jc);
/** /**
* Returns the maximum possible location of the divider. * Returns the maximum possible location of the divider.
*
* @param jc a {@code JSplitPane}
* @return an integer specifying the maximum location of the divider
*/ */
public abstract int getMaximumDividerLocation(JSplitPane jc); public abstract int getMaximumDividerLocation(JSplitPane jc);
/** /**
* Messaged after the JSplitPane the receiver is providing the look * Messaged after the JSplitPane the receiver is providing the look
* and feel for paints its children. * and feel for paints its children.
*
* @param jc a {@code JSplitPane}
* @param g the {@code Graphics} context
*/ */
public abstract void finishedPaintingChildren(JSplitPane jc, Graphics g); public abstract void finishedPaintingChildren(JSplitPane jc, Graphics g);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,8 +42,9 @@ public abstract class TextUI extends ComponentUI
* Converts the given location in the model to a place in * Converts the given location in the model to a place in
* the view coordinate system. * the view coordinate system.
* *
* @param t the text component for which this UI is installed
* @param pos the local location in the model to translate &gt;= 0 * @param pos the local location in the model to translate &gt;= 0
* @return the coordinates as a rectangle * @return the coordinates as a {@code Rectangle}
* @exception BadLocationException if the given position does not * @exception BadLocationException if the given position does not
* represent a valid location in the associated document * represent a valid location in the associated document
*/ */
@ -53,8 +54,10 @@ public abstract class TextUI extends ComponentUI
* Converts the given location in the model to a place in * Converts the given location in the model to a place in
* the view coordinate system. * the view coordinate system.
* *
* @param t the text component for which this UI is installed
* @param pos the local location in the model to translate &gt;= 0 * @param pos the local location in the model to translate &gt;= 0
* @return the coordinates as a rectangle * @param bias the bias for the position
* @return the coordinates as a {@code Rectangle}
* @exception BadLocationException if the given position does not * @exception BadLocationException if the given position does not
* represent a valid location in the associated document * represent a valid location in the associated document
*/ */
@ -64,6 +67,7 @@ public abstract class TextUI extends ComponentUI
* Converts the given place in the view coordinate system * Converts the given place in the view coordinate system
* to the nearest representative location in the model. * to the nearest representative location in the model.
* *
* @param t the text component for which this UI is installed
* @param pt the location in the view to translate. This * @param pt the location in the view to translate. This
* should be in the same coordinate system as the mouse * should be in the same coordinate system as the mouse
* events. * events.
@ -75,6 +79,7 @@ public abstract class TextUI extends ComponentUI
* Provides a mapping from the view coordinate space to the logical * Provides a mapping from the view coordinate space to the logical
* coordinate space of the model. * coordinate space of the model.
* *
* @param t the text component for which this UI is installed
* @param pt the location in the view to translate. * @param pt the location in the view to translate.
* This should be in the same coordinate system * This should be in the same coordinate system
* as the mouse events. * as the mouse events.
@ -117,6 +122,7 @@ public abstract class TextUI extends ComponentUI
* Causes the portion of the view responsible for the * Causes the portion of the view responsible for the
* given part of the model to be repainted. * given part of the model to be repainted.
* *
* @param t the text component for which this UI is installed
* @param p0 the beginning of the range &gt;= 0 * @param p0 the beginning of the range &gt;= 0
* @param p1 the end of the range &gt;= p0 * @param p1 the end of the range &gt;= p0
*/ */
@ -126,8 +132,13 @@ public abstract class TextUI extends ComponentUI
* Causes the portion of the view responsible for the * Causes the portion of the view responsible for the
* given part of the model to be repainted. * given part of the model to be repainted.
* *
* @param t the text component for which this UI is installed
* @param p0 the beginning of the range &gt;= 0 * @param p0 the beginning of the range &gt;= 0
* @param p1 the end of the range &gt;= p0 * @param p1 the end of the range &gt;= p0
* @param firstBias the bias of the first character position, toward the
* previous character or the next character
* @param secondBias the bias of the second character position, toward the
* previous character or the next character
*/ */
public abstract void damageRange(JTextComponent t, int p0, int p1, public abstract void damageRange(JTextComponent t, int p0, int p1,
Position.Bias firstBias, Position.Bias firstBias,
@ -139,6 +150,7 @@ public abstract class TextUI extends ComponentUI
* things like the commands available, stream readers and * things like the commands available, stream readers and
* writers, etc. * writers, etc.
* *
* @param t the text component for which this UI is installed
* @return the editor kit binding * @return the editor kit binding
*/ */
public abstract EditorKit getEditorKit(JTextComponent t); public abstract EditorKit getEditorKit(JTextComponent t);
@ -149,13 +161,18 @@ public abstract class TextUI extends ComponentUI
* can be traversed to determine how the model is being * can be traversed to determine how the model is being
* represented spatially. * represented spatially.
* *
* @return the view * @param t the text component for which this UI is installed
* @return a {@code View} with the allocation of the associated
* text component
*/ */
public abstract View getRootView(JTextComponent t); public abstract View getRootView(JTextComponent t);
/** /**
* Returns the string to be used as the tooltip at the passed in location. * Returns the string to be used as the tooltip at the passed in location.
* *
* @param t the text component for which this UI is installed
* @param pt a {@code Point} specifying location for which to get a tooltip
* @return a {@code String} containing the tooltip
* @see javax.swing.text.JTextComponent#getToolTipText * @see javax.swing.text.JTextComponent#getToolTipText
* @since 1.4 * @since 1.4
*/ */

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -41,12 +41,23 @@ public abstract class TreeUI extends ComponentUI
* Returns the Rectangle enclosing the label portion that the * Returns the Rectangle enclosing the label portion that the
* last item in path will be drawn into. Will return null if * last item in path will be drawn into. Will return null if
* any component in path is currently valid. * any component in path is currently valid.
*
* @param tree the {@code JTree} for {@code path}
* @param path the {@code TreePath} identifying the node
* @return the {@code Rectangle} enclosing the label portion that the
* last item in path will be drawn into, {@code null} if any
* component in path is currently valid.
*/ */
public abstract Rectangle getPathBounds(JTree tree, TreePath path); public abstract Rectangle getPathBounds(JTree tree, TreePath path);
/** /**
* Returns the path for passed in row. If row is not visible * Returns the path for passed in row. If row is not visible
* null is returned. * null is returned.
*
* @param tree a {@code JTree} object
* @param row an integer specifying a row
* @return the {@code path} for {@code row} or {@code null} if {@code row}
* is not visible
*/ */
public abstract TreePath getPathForRow(JTree tree, int row); public abstract TreePath getPathForRow(JTree tree, int row);
@ -54,11 +65,20 @@ public abstract class TreeUI extends ComponentUI
* Returns the row that the last item identified in path is visible * Returns the row that the last item identified in path is visible
* at. Will return -1 if any of the elements in path are not * at. Will return -1 if any of the elements in path are not
* currently visible. * currently visible.
*
* @param tree the {@code JTree} for {@code path}
* @param path the {@code TreePath} object to look in
* @return an integer specifying the row at which the last item
* identified is visible, -1 if any of the elements in
* {@code path} are not currently visible
*/ */
public abstract int getRowForPath(JTree tree, TreePath path); public abstract int getRowForPath(JTree tree, TreePath path);
/** /**
* Returns the number of rows that are being displayed. * Returns the number of rows that are being displayed.
*
* @param tree the {@code JTree} for which to count rows
* @return an integer specifying the number of row being displayed
*/ */
public abstract int getRowCount(JTree tree); public abstract int getRowCount(JTree tree);
@ -68,6 +88,14 @@ public abstract class TreeUI extends ComponentUI
* it'll always return a valid path. If you need to test if the * it'll always return a valid path. If you need to test if the
* returned object is exactly at x, y you should get the bounds for * returned object is exactly at x, y you should get the bounds for
* the returned path and test x, y against that. * the returned path and test x, y against that.
*
* @param tree a {@code JTree} object
* @param x an integer giving the number of pixels horizontally from the
* left edge of the display area
* @param y an integer giving the number of pixels vertically from the top
* of the display area, minus any top margin
* @return the {@code TreePath} node closest to {@code x,y} or {@code null}
* if there is nothing currently visible
*/ */
public abstract TreePath getClosestPathForLocation(JTree tree, int x, public abstract TreePath getClosestPathForLocation(JTree tree, int x,
int y); int y);
@ -75,6 +103,9 @@ public abstract class TreeUI extends ComponentUI
/** /**
* Returns true if the tree is being edited. The item that is being * Returns true if the tree is being edited. The item that is being
* edited can be returned by getEditingPath(). * edited can be returned by getEditingPath().
*
* @param tree a {@code JTree} object
* @return true if {@code tree} is being edited
*/ */
public abstract boolean isEditing(JTree tree); public abstract boolean isEditing(JTree tree);
@ -82,24 +113,34 @@ public abstract class TreeUI extends ComponentUI
* Stops the current editing session. This has no effect if the * Stops the current editing session. This has no effect if the
* tree isn't being edited. Returns true if the editor allows the * tree isn't being edited. Returns true if the editor allows the
* editing session to stop. * editing session to stop.
*
* @param tree a {@code JTree} object
* @return true if the editor allows the editing session to stop
*/ */
public abstract boolean stopEditing(JTree tree); public abstract boolean stopEditing(JTree tree);
/** /**
* Cancels the current editing session. This has no effect if the * Cancels the current editing session. This has no effect if the
* tree isn't being edited. Returns true if the editor allows the * tree isn't being edited.
* editing session to stop. *
* @param tree a {@code JTree} object
*/ */
public abstract void cancelEditing(JTree tree); public abstract void cancelEditing(JTree tree);
/** /**
* Selects the last item in path and tries to edit it. Editing will * Selects the last item in path and tries to edit it. Editing will
* fail if the CellEditor won't allow it for the selected item. * fail if the CellEditor won't allow it for the selected item.
*
* @param tree the {@code JTree} being edited
* @param path the {@code TreePath} to be edited
*/ */
public abstract void startEditingAtPath(JTree tree, TreePath path); public abstract void startEditingAtPath(JTree tree, TreePath path);
/** /**
* Returns the path to the element that is being edited. * Returns the path to the element that is being edited.
*
* @param tree the {@code JTree} for which to return a path
* @return a {@code TreePath} containing the path to {@code tree}
*/ */
public abstract TreePath getEditingPath(JTree tree); public abstract TreePath getEditingPath(JTree tree);
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -354,6 +354,11 @@ public class BasicInternalFrameUI extends InternalFrameUI
* Installs necessary mouse handlers on <code>newPane</code> * Installs necessary mouse handlers on <code>newPane</code>
* and adds it to the frame. * and adds it to the frame.
* Reverse process for the <code>currentPane</code>. * Reverse process for the <code>currentPane</code>.
*
* @param currentPane this {@code Jcomponent} is the current pane being
* viewed that has mouse handlers installed
* @param newPane this {@code Jcomponent} is the pane which will be added
* and have mouse handlers installed
*/ */
protected void replacePane(JComponent currentPane, JComponent newPane) { protected void replacePane(JComponent currentPane, JComponent newPane) {
if(currentPane != null) { if(currentPane != null) {
@ -517,7 +522,8 @@ public class BasicInternalFrameUI extends InternalFrameUI
} }
/// DesktopManager methods /// DesktopManager methods
/** Returns the proper DesktopManager. Calls getDesktopPane() to /**
* Returns the proper DesktopManager. Calls getDesktopPane() to
* find the JDesktop component and returns the desktopManager from * find the JDesktop component and returns the desktopManager from
* it. If this fails, it will return a default DesktopManager that * it. If this fails, it will return a default DesktopManager that
* should work in arbitrary parents. * should work in arbitrary parents.
@ -539,6 +545,8 @@ public class BasicInternalFrameUI extends InternalFrameUI
* This method is called when the user wants to close the frame. * This method is called when the user wants to close the frame.
* The <code>playCloseSound</code> Action is fired. * The <code>playCloseSound</code> Action is fired.
* This action is delegated to the desktopManager. * This action is delegated to the desktopManager.
*
* @param f the {@code JInternalFrame} being viewed
*/ */
protected void closeFrame(JInternalFrame f) { protected void closeFrame(JInternalFrame f) {
// Internal Frame Auditory Cue Activation // Internal Frame Auditory Cue Activation
@ -551,6 +559,8 @@ public class BasicInternalFrameUI extends InternalFrameUI
* This method is called when the user wants to maximize the frame. * This method is called when the user wants to maximize the frame.
* The <code>playMaximizeSound</code> Action is fired. * The <code>playMaximizeSound</code> Action is fired.
* This action is delegated to the desktopManager. * This action is delegated to the desktopManager.
*
* @param f the {@code JInternalFrame} being viewed
*/ */
protected void maximizeFrame(JInternalFrame f) { protected void maximizeFrame(JInternalFrame f) {
// Internal Frame Auditory Cue Activation // Internal Frame Auditory Cue Activation
@ -563,6 +573,8 @@ public class BasicInternalFrameUI extends InternalFrameUI
* This method is called when the user wants to minimize the frame. * This method is called when the user wants to minimize the frame.
* The <code>playRestoreDownSound</code> Action is fired. * The <code>playRestoreDownSound</code> Action is fired.
* This action is delegated to the desktopManager. * This action is delegated to the desktopManager.
*
* @param f the {@code JInternalFrame} being viewed
*/ */
protected void minimizeFrame(JInternalFrame f) { protected void minimizeFrame(JInternalFrame f) {
// Internal Frame Auditory Cue Activation // Internal Frame Auditory Cue Activation
@ -579,6 +591,8 @@ public class BasicInternalFrameUI extends InternalFrameUI
* This method is called when the user wants to iconify the frame. * This method is called when the user wants to iconify the frame.
* The <code>playMinimizeSound</code> Action is fired. * The <code>playMinimizeSound</code> Action is fired.
* This action is delegated to the desktopManager. * This action is delegated to the desktopManager.
*
* @param f the {@code JInternalFrame} being viewed
*/ */
protected void iconifyFrame(JInternalFrame f) { protected void iconifyFrame(JInternalFrame f) {
// Internal Frame Auditory Cue Activation // Internal Frame Auditory Cue Activation
@ -591,6 +605,8 @@ public class BasicInternalFrameUI extends InternalFrameUI
* This method is called when the user wants to deiconify the frame. * This method is called when the user wants to deiconify the frame.
* The <code>playRestoreUpSound</code> Action is fired. * The <code>playRestoreUpSound</code> Action is fired.
* This action is delegated to the desktopManager. * This action is delegated to the desktopManager.
*
* @param f the {@code JInternalFrame} being viewed
*/ */
protected void deiconifyFrame(JInternalFrame f) { protected void deiconifyFrame(JInternalFrame f) {
// Internal Frame Auditory Cue Activation // Internal Frame Auditory Cue Activation
@ -603,14 +619,20 @@ public class BasicInternalFrameUI extends InternalFrameUI
getDesktopManager().deiconifyFrame(f); getDesktopManager().deiconifyFrame(f);
} }
/** This method is called when the frame becomes selected. /**
* This method is called when the frame becomes selected.
* This action is delegated to the desktopManager. * This action is delegated to the desktopManager.
*
* @param f the {@code JInternalFrame} being viewed
*/ */
protected void activateFrame(JInternalFrame f) { protected void activateFrame(JInternalFrame f) {
getDesktopManager().activateFrame(f); getDesktopManager().activateFrame(f);
} }
/** This method is called when the frame is no longer selected. /**
* This method is called when the frame is no longer selected.
* This action is delegated to the desktopManager. * This action is delegated to the desktopManager.
*
* @param f the {@code JInternalFrame} being viewed
*/ */
protected void deactivateFrame(JInternalFrame f) { protected void deactivateFrame(JInternalFrame f) {
getDesktopManager().deactivateFrame(f); getDesktopManager().deactivateFrame(f);

View file

@ -93,8 +93,10 @@ public class BasicScrollBarUI
private final static int scrollSpeedThrottle = 60; // delay in milli seconds private final static int scrollSpeedThrottle = 60; // delay in milli seconds
/** True indicates a middle click will absolutely position the /**
* scrollbar. */ * True indicates a middle click will absolutely position the
* scrollbar.
*/
private boolean supportsAbsolutePositioning; private boolean supportsAbsolutePositioning;
/** /**
@ -877,6 +879,10 @@ public class BasicScrollBarUI
* Set the bounds of the thumb and force a repaint that includes * Set the bounds of the thumb and force a repaint that includes
* the old thumbBounds and the new one. * the old thumbBounds and the new one.
* *
* @param x set the x location of the thumb
* @param y set the y location of the thumb
* @param width set the width of the thumb
* @param height set the height of the thumb
* @see #getThumbBounds * @see #getThumbBounds
*/ */
protected void setThumbBounds(int x, int y, int width, int height) protected void setThumbBounds(int x, int y, int width, int height)

View file

@ -656,10 +656,15 @@ public class BasicSliderUI extends SliderUI{
} }
/** /**
* Gets the height of the tick area for horizontal sliders and the width of the * Gets the height of the tick area for horizontal sliders and the width of
* tick area for vertical sliders. BasicSliderUI uses the returned value to * the tick area for vertical sliders. BasicSliderUI uses the returned value
* determine the tick area rectangle. If you want to give your ticks some room, * to determine the tick area rectangle. If you want to give your ticks some
* make this larger than you need and paint your ticks away from the sides in paintTicks(). * room, make this larger than you need and paint your ticks away from the
* sides in paintTicks().
*
* @return an integer representing the height of the tick area for
* horizontal sliders, and the width of the tick area for the vertical
* sliders
*/ */
protected int getTickLength() { protected int getTickLength() {
return 8; return 8;
@ -894,7 +899,11 @@ public class BasicSliderUI extends SliderUI{
/** /**
* Returns the label that corresponds to the highest slider value in the label table. * Returns the label that corresponds to the highest slider value in the
* label table.
*
* @return the label that corresponds to the highest slider value in the
* label table
* @see JSlider#setLabelTable * @see JSlider#setLabelTable
*/ */
protected Component getLowestValueLabel() { protected Component getLowestValueLabel() {
@ -906,7 +915,11 @@ public class BasicSliderUI extends SliderUI{
} }
/** /**
* Returns the label that corresponds to the lowest slider value in the label table. * Returns the label that corresponds to the lowest slider value in the
* label table.
*
* @return the label that corresponds to the lowest slider value in the
* label table
* @see JSlider#setLabelTable * @see JSlider#setLabelTable
*/ */
protected Component getHighestValueLabel() { protected Component getHighestValueLabel() {
@ -1166,8 +1179,14 @@ public class BasicSliderUI extends SliderUI{
} }
/** /**
* Called for every label in the label table. Used to draw the labels for horizontal sliders. * Called for every label in the label table. Used to draw the labels for
* The graphics have been translated to labelRect.y already. * horizontal sliders. The graphics have been translated to labelRect.y
* already.
*
* @param g the graphics context in which to paint
* @param value the value of the slider
* @param label the component label in the label table that needs to be
* painted
* @see JSlider#setLabelTable * @see JSlider#setLabelTable
*/ */
protected void paintHorizontalLabel( Graphics g, int value, Component label ) { protected void paintHorizontalLabel( Graphics g, int value, Component label ) {
@ -1179,8 +1198,14 @@ public class BasicSliderUI extends SliderUI{
} }
/** /**
* Called for every label in the label table. Used to draw the labels for vertical sliders. * Called for every label in the label table. Used to draw the labels for
* The graphics have been translated to labelRect.x already. * vertical sliders. The graphics have been translated to labelRect.x
* already.
*
* @param g the graphics context in which to paint
* @param value the value of the slider
* @param label the component label in the label table that needs to be
* painted
* @see JSlider#setLabelTable * @see JSlider#setLabelTable
*/ */
protected void paintVerticalLabel( Graphics g, int value, Component label ) { protected void paintVerticalLabel( Graphics g, int value, Component label ) {
@ -1342,9 +1367,12 @@ public class BasicSliderUI extends SliderUI{
} }
/** /**
* This function is called when a mousePressed was detected in the track, not * This function is called when a mousePressed was detected in the track,
* in the thumb. The default behavior is to scroll by block. You can * not in the thumb. The default behavior is to scroll by block. You can
* override this method to stop it from scrolling or to add additional behavior. * override this method to stop it from scrolling or to add additional
* behavior.
*
* @param dir the direction and number of blocks to scroll
*/ */
protected void scrollDueToClickInTrack( int dir ) { protected void scrollDueToClickInTrack( int dir ) {
scrollByBlock( dir ); scrollByBlock( dir );
@ -1387,6 +1415,7 @@ public class BasicSliderUI extends SliderUI{
* @param value the slider value to get the location for * @param value the slider value to get the location for
* @param trackY y-origin of the track * @param trackY y-origin of the track
* @param trackHeight the height of the track * @param trackHeight the height of the track
* @return the y location for the specified value of the slider
* @since 1.6 * @since 1.6
*/ */
protected int yPositionForValue(int value, int trackY, int trackHeight) { protected int yPositionForValue(int value, int trackY, int trackHeight) {
@ -1417,6 +1446,9 @@ public class BasicSliderUI extends SliderUI{
* track at the the bottom or the top, this method sets the value to either * track at the the bottom or the top, this method sets the value to either
* the minimum or maximum value of the slider, depending on if the slider * the minimum or maximum value of the slider, depending on if the slider
* is inverted or not. * is inverted or not.
*
* @param yPos the location of the slider along the y axis
* @return the value at the y position
*/ */
public int valueForYPosition( int yPos ) { public int valueForYPosition( int yPos ) {
int value; int value;
@ -1449,6 +1481,9 @@ public class BasicSliderUI extends SliderUI{
* track at the left or the right, this method sets the value to either the * track at the left or the right, this method sets the value to either the
* minimum or maximum value of the slider, depending on if the slider is * minimum or maximum value of the slider, depending on if the slider is
* inverted or not. * inverted or not.
*
* @param xPos the location of the slider along the x axis
* @return the value of the x position
*/ */
public int valueForXPosition( int xPos ) { public int valueForXPosition( int xPos ) {
int value; int value;

View file

@ -1174,6 +1174,16 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants {
* this function draws the border around each tab * this function draws the border around each tab
* note that this function does now draw the background of the tab. * note that this function does now draw the background of the tab.
* that is done elsewhere * that is done elsewhere
*
* @param g the graphics context in which to paint
* @param tabPlacement the placement (left, right, bottom, top) of the tab
* @param tabIndex the index of the tab with respect to other tabs
* @param x the x coordinate of tab
* @param y the y coordinate of tab
* @param w the width of the tab
* @param h the height of the tab
* @param isSelected a {@code boolean} which determines whether or not
* the tab is selected
*/ */
protected void paintTabBorder(Graphics g, int tabPlacement, protected void paintTabBorder(Graphics g, int tabPlacement,
int tabIndex, int tabIndex,
@ -3530,12 +3540,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants {
else if (name =="indexForTitle") { else if (name =="indexForTitle") {
calculatedBaseline = false; calculatedBaseline = false;
Integer index = (Integer) e.getNewValue(); Integer index = (Integer) e.getNewValue();
// remove the current index updateHtmlViews(index, false);
// to let updateHtmlViews() insert the correct one
if (htmlViews != null) {
htmlViews.removeElementAt(index);
}
updateHtmlViews(index);
} else if (name == "tabLayoutPolicy") { } else if (name == "tabLayoutPolicy") {
BasicTabbedPaneUI.this.uninstallUI(pane); BasicTabbedPaneUI.this.uninstallUI(pane);
BasicTabbedPaneUI.this.installUI(pane); BasicTabbedPaneUI.this.installUI(pane);
@ -3574,13 +3579,13 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants {
calculatedBaseline = false; calculatedBaseline = false;
} else if (name == "indexForNullComponent") { } else if (name == "indexForNullComponent") {
isRunsDirty = true; isRunsDirty = true;
updateHtmlViews((Integer)e.getNewValue()); updateHtmlViews((Integer)e.getNewValue(), true);
} else if (name == "font") { } else if (name == "font") {
calculatedBaseline = false; calculatedBaseline = false;
} }
} }
private void updateHtmlViews(int index) { private void updateHtmlViews(int index, boolean inserted) {
String title = tabPane.getTitleAt(index); String title = tabPane.getTitleAt(index);
boolean isHTML = BasicHTML.isHTMLString(title); boolean isHTML = BasicHTML.isHTMLString(title);
if (isHTML) { if (isHTML) {
@ -3588,16 +3593,24 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants {
htmlViews = createHTMLVector(); htmlViews = createHTMLVector();
} else { // Vector already exists } else { // Vector already exists
View v = BasicHTML.createHTMLView(tabPane, title); View v = BasicHTML.createHTMLView(tabPane, title);
htmlViews.insertElementAt(v, index); setHtmlView(v, inserted, index);
} }
} else { // Not HTML } else { // Not HTML
if (htmlViews!=null) { // Add placeholder if (htmlViews!=null) { // Add placeholder
htmlViews.insertElementAt(null, index); setHtmlView(null, inserted, index);
} // else nada! } // else nada!
} }
updateMnemonics(); updateMnemonics();
} }
private void setHtmlView(View v, boolean inserted, int index) {
if (inserted || index >= htmlViews.size()) {
htmlViews.insertElementAt(v, index);
} else {
htmlViews.setElementAt(v, index);
}
}
// //
// ChangeListener // ChangeListener
// //
@ -3716,7 +3729,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants {
return; return;
} }
isRunsDirty = true; isRunsDirty = true;
updateHtmlViews(tp.indexOfComponent(child)); updateHtmlViews(tp.indexOfComponent(child), true);
} }
public void componentRemoved(ContainerEvent e) { public void componentRemoved(ContainerEvent e) {
JTabbedPane tp = (JTabbedPane)e.getContainer(); JTabbedPane tp = (JTabbedPane)e.getContainer();

View file

@ -1426,11 +1426,18 @@ public abstract class AbstractDocument implements Document, Serializable {
// --- serialization --------------------------------------------- // --- serialization ---------------------------------------------
@SuppressWarnings("unchecked")
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException throws ClassNotFoundException, IOException
{ {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
documentProperties =
(Dictionary<Object, Object>) f.get("documentProperties", null);
listenerList = new EventListenerList(); listenerList = new EventListenerList();
data = (Content) f.get("data", null);
context = (AttributeContext) f.get("context", null);
documentFilter = (DocumentFilter) f.get("documentFilter", null);
// Restore bidi structure // Restore bidi structure
//REMIND(bcb) This creates an initial bidi element to account for //REMIND(bcb) This creates an initial bidi element to account for

View file

@ -1516,7 +1516,30 @@ public class DefaultCaret extends Rectangle implements Caret, FocusListener, Mou
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException throws ClassNotFoundException, IOException
{ {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
EventListenerList newListenerList = (EventListenerList) f.get("listenerList", null);
if (newListenerList == null) {
throw new InvalidObjectException("Null listenerList");
}
listenerList = newListenerList;
component = (JTextComponent) f.get("component", null);
updatePolicy = f.get("updatePolicy", 0);
visible = f.get("visible", false);
active = f.get("active", false);
dot = f.get("dot", 0);
mark = f.get("mark", 0);
selectionTag = f.get("selectionTag", null);
selectionVisible = f.get("selectionVisible", false);
flasher = (Timer) f.get("flasher", null);
magicCaretPosition = (Point) f.get("magicCaretPosition", null);
dotLTR = f.get("dotLTR", false);
markLTR = f.get("markLTR", false);
ownsSelection = f.get("ownsSelection", false);
forceCaretPositionChange = f.get("forceCaretPositionChange", false);
caretWidth = f.get("caretWidth", 0);
aspectRatio = f.get("aspectRatio", 0.0f);
handler = new Handler(); handler = new Handler();
if (!s.readBoolean()) { if (!s.readBoolean()) {
dotBias = Position.Bias.Forward; dotBias = Position.Bias.Forward;

View file

@ -1082,8 +1082,9 @@ public class DefaultStyledDocument extends AbstractDocument implements StyledDoc
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException { throws ClassNotFoundException, IOException {
listeningStyles = new Vector<Style>(); listeningStyles = new Vector<>();
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
buffer = (ElementBuffer) f.get("buffer", null);
// Reinstall style listeners. // Reinstall style listeners.
if (styleContextChangeListener == null && if (styleContextChangeListener == null &&
listenerList.getListenerCount(DocumentListener.class) > 0) { listenerList.getListenerCount(DocumentListener.class) > 0) {

View file

@ -280,7 +280,7 @@ public class GapContent extends GapVector implements AbstractDocument.Content, S
* is held by the mark, so it is adjusted according * is held by the mark, so it is adjusted according
* to it's relationship to the gap. * to it's relationship to the gap.
*/ */
public final int getOffset() { public int getOffset() {
int g0 = getGapStart(); int g0 = getGapStart();
int g1 = getGapEnd(); int g1 = getGapEnd();
int offs = (index < g0) ? index : index - (g1 - g0); int offs = (index < g0) ? index : index - (g1 - g0);
@ -302,7 +302,7 @@ public class GapContent extends GapVector implements AbstractDocument.Content, S
this.mark = mark; this.mark = mark;
} }
public final int getOffset() { public int getOffset() {
return mark.getOffset(); return mark.getOffset();
} }

View file

@ -683,10 +683,14 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A
* bound: false * bound: false
*/ */
public void setDragEnabled(boolean b) { public void setDragEnabled(boolean b) {
checkDragEnabled(b);
dragEnabled = b;
}
private static void checkDragEnabled(boolean b) {
if (b && GraphicsEnvironment.isHeadless()) { if (b && GraphicsEnvironment.isHeadless()) {
throw new HeadlessException(); throw new HeadlessException();
} }
dragEnabled = b;
} }
/** /**
@ -727,11 +731,15 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A
* @since 1.6 * @since 1.6
*/ */
public final void setDropMode(DropMode dropMode) { public final void setDropMode(DropMode dropMode) {
checkDropMode(dropMode);
this.dropMode = dropMode;
}
private static void checkDropMode(DropMode dropMode) {
if (dropMode != null) { if (dropMode != null) {
switch (dropMode) { switch (dropMode) {
case USE_SELECTION: case USE_SELECTION:
case INSERT: case INSERT:
this.dropMode = dropMode;
return; return;
} }
} }
@ -3747,7 +3755,34 @@ public abstract class JTextComponent extends JComponent implements Scrollable, A
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException throws IOException, ClassNotFoundException
{ {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
model = (Document) f.get("model", null);
navigationFilter = (NavigationFilter) f.get("navigationFilter", null);
caretColor = (Color) f.get("caretColor", null);
selectionColor = (Color) f.get("selectionColor", null);
selectedTextColor = (Color) f.get("selectedTextColor", null);
disabledTextColor = (Color) f.get("disabledTextColor", null);
editable = f.get("editable", false);
margin = (Insets) f.get("margin", null);
focusAccelerator = f.get("focusAccelerator", '\0');
boolean newDragEnabled = f.get("dragEnabled", false);
checkDragEnabled(newDragEnabled);
dragEnabled = newDragEnabled;
DropMode newDropMode = (DropMode) f.get("dropMode",
DropMode.USE_SELECTION);
checkDropMode(newDropMode);
dropMode = newDropMode;
composedTextAttribute = (SimpleAttributeSet) f.get("composedTextAttribute", null);
composedTextContent = (String) f.get("composedTextContent", null);
composedTextStart = (Position) f.get("composedTextStart", null);
composedTextEnd = (Position) f.get("composedTextEnd", null);
latestCommittedTextStart = (Position) f.get("latestCommittedTextStart", null);
latestCommittedTextEnd = (Position) f.get("latestCommittedTextEnd", null);
composedTextCaret = (ComposedTextCaret) f.get("composedTextCaret", null);
checkedInputOverride = f.get("checkedInputOverride", false);
needToSendKeyTypedEvent = f.get("needToSendKeyTypedEvent", false);
caretEvent = new MutableCaretEvent(this); caretEvent = new MutableCaretEvent(this);
addMouseListener(caretEvent); addMouseListener(caretEvent);
addFocusListener(caretEvent); addFocusListener(caretEvent);

View file

@ -649,7 +649,15 @@ public class MaskFormatter extends DefaultFormatter {
*/ */
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
s.defaultReadObject(); ObjectInputStream.GetField f = s.readFields();
validCharacters = (String) f.get("validCharacters", null);
invalidCharacters = (String) f.get("invalidCharacters", null);
placeholderString = (String) f.get("placeholderString", null);
placeholder = f.get("placeholder", '\0');
containsLiteralChars = f.get("containsLiteralChars", false);
mask = (String) f.get("mask", null);
try { try {
updateInternalMask(); updateInternalMask();
} catch (ParseException pe) { } catch (ParseException pe) {

View file

@ -714,11 +714,19 @@ public class StyleContext implements Serializable, AbstractDocument.AttributeCon
throws ClassNotFoundException, IOException throws ClassNotFoundException, IOException
{ {
fontSearch = new FontKey(null, 0, 0); fontSearch = new FontKey(null, 0, 0);
fontTable = new Hashtable<FontKey, Font>(); fontTable = new Hashtable<>();
search = new SimpleAttributeSet(); search = new SimpleAttributeSet();
attributesPool = Collections. attributesPool = Collections.
synchronizedMap(new WeakHashMap<SmallAttributeSet, WeakReference<SmallAttributeSet>>()); synchronizedMap(new WeakHashMap<SmallAttributeSet,
s.defaultReadObject(); WeakReference<SmallAttributeSet>>());
ObjectInputStream.GetField f = s.readFields();
Style newStyles = (Style) f.get("styles", null);
if (newStyles == null) {
throw new InvalidObjectException("Null styles");
}
styles = newStyles;
unusedSets = f.get("unusedSets", 0);
} }
// --- variables --------------------------------------------------- // --- variables ---------------------------------------------------
@ -734,7 +742,7 @@ public class StyleContext implements Serializable, AbstractDocument.AttributeCon
private Style styles; private Style styles;
private transient FontKey fontSearch = new FontKey(null, 0, 0); private transient FontKey fontSearch = new FontKey(null, 0, 0);
private transient Hashtable<FontKey, Font> fontTable = new Hashtable<FontKey, Font>(); private transient Hashtable<FontKey, Font> fontTable = new Hashtable<>();
private transient Map<SmallAttributeSet, WeakReference<SmallAttributeSet>> attributesPool = Collections. private transient Map<SmallAttributeSet, WeakReference<SmallAttributeSet>> attributesPool = Collections.
synchronizedMap(new WeakHashMap<SmallAttributeSet, WeakReference<SmallAttributeSet>>()); synchronizedMap(new WeakHashMap<SmallAttributeSet, WeakReference<SmallAttributeSet>>());

Some files were not shown because too many files have changed in this diff Show more