You can subscribe to this list here.
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(97) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(127) |
Feb
(34) |
Mar
(16) |
Apr
(26) |
May
(55) |
Jun
(107) |
Jul
(36) |
Aug
(72) |
Sep
(90) |
Oct
(41) |
Nov
(27) |
Dec
(13) |
| 2008 |
Jan
(37) |
Feb
(39) |
Mar
(98) |
Apr
(115) |
May
(134) |
Jun
(120) |
Jul
(86) |
Aug
(149) |
Sep
(68) |
Oct
(66) |
Nov
(104) |
Dec
(49) |
| 2009 |
Jan
(131) |
Feb
(132) |
Mar
(125) |
Apr
(172) |
May
(161) |
Jun
(43) |
Jul
(47) |
Aug
(38) |
Sep
(18) |
Oct
(6) |
Nov
(1) |
Dec
(15) |
| 2010 |
Jan
(21) |
Feb
(8) |
Mar
(10) |
Apr
(4) |
May
(9) |
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
(4) |
| 2011 |
Jan
(23) |
Feb
(10) |
Mar
(13) |
Apr
(3) |
May
|
Jun
(19) |
Jul
(11) |
Aug
(22) |
Sep
|
Oct
(4) |
Nov
(2) |
Dec
(12) |
| 2012 |
Jan
(3) |
Feb
(4) |
Mar
(7) |
Apr
(3) |
May
|
Jun
(1) |
Jul
(1) |
Aug
(30) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(8) |
| 2013 |
Jan
(3) |
Feb
(40) |
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(12) |
Dec
|
| 2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
|
From: <fd...@us...> - 2007-02-11 22:25:22
|
Revision: 3119
http://jnode.svn.sourceforge.net/jnode/?rev=3119&view=rev
Author: fduminy
Date: 2007-02-11 14:25:20 -0800 (Sun, 11 Feb 2007)
Log Message:
-----------
fixed bug in splitInColumns method
Modified Paths:
--------------
trunk/shell/src/shell/org/jnode/shell/Line.java
Modified: trunk/shell/src/shell/org/jnode/shell/Line.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/Line.java 2007-02-11 22:23:44 UTC (rev 3118)
+++ trunk/shell/src/shell/org/jnode/shell/Line.java 2007-02-11 22:25:20 UTC (rev 3119)
@@ -213,7 +213,7 @@
}
}
- final int columnWidth = maxWidth + separatorWidth;
+ final int columnWidth = Math.min(SCREEN_WIDTH, maxWidth + separatorWidth);
final int nbColumns = SCREEN_WIDTH / columnWidth;
final boolean lastLineIsFull = ((items.length % nbColumns) == 0);
final int nbLines = (items.length / nbColumns) + (lastLineIsFull ? 0 : 1);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fd...@us...> - 2007-02-11 22:23:45
|
Revision: 3118
http://jnode.svn.sourceforge.net/jnode/?rev=3118&view=rev
Author: fduminy
Date: 2007-02-11 14:23:44 -0800 (Sun, 11 Feb 2007)
Log Message:
-----------
removed "ugly workaround" :-) that is no more needed since we went to generics
Modified Paths:
--------------
trunk/shell/src/shell/org/jnode/shell/help/Argument.java
Modified: trunk/shell/src/shell/org/jnode/shell/help/Argument.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/help/Argument.java 2007-02-11 22:19:06 UTC (rev 3117)
+++ trunk/shell/src/shell/org/jnode/shell/help/Argument.java 2007-02-11 22:23:44 UTC (rev 3118)
@@ -76,11 +76,7 @@
if (list.size() == 1) return (String) list.iterator().next() + " ";
// list matching
- String[] result = (String[]) list
- .toArray(new String[ list.size()/*
- * TODO remove this ugly
- * workaround
- */]);
+ String[] result = list.toArray(new String[list.size()]);
list(result);
// return the common part, i.e. complete as much as possible
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fd...@us...> - 2007-02-11 22:19:11
|
Revision: 3117
http://jnode.svn.sourceforge.net/jnode/?rev=3117&view=rev
Author: fduminy
Date: 2007-02-11 14:19:06 -0800 (Sun, 11 Feb 2007)
Log Message:
-----------
- IBMPartitionTypes is now an enum instead of an interface
- added some functions for disk partitionning
- extracted partionning functions from FDiskCommand to put them in the class PartitionHelper
Modified Paths:
--------------
trunk/fs/build.xml
trunk/fs/descriptors/org.jnode.partitions.command.xml
trunk/fs/src/driver/org/jnode/driver/block/PartitionableBlockAlignmentSupport.java
trunk/fs/src/driver/org/jnode/driver/block/PartitionableBlockDeviceAPI.java
trunk/fs/src/driver/org/jnode/driver/block/ide/disk/IDEDiskDriver.java
trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEDeviceAPI.java
trunk/fs/src/fs/org/jnode/fs/fat/BootSector.java
trunk/fs/src/fs/org/jnode/fs/fat/FatFileSystemType.java
trunk/fs/src/fs/org/jnode/fs/jfat/FatFileSystemType.java
trunk/fs/src/fs/org/jnode/fs/ntfs/NTFSFileSystemType.java
trunk/fs/src/fs/org/jnode/partitions/PartitionTable.java
trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java
trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTable.java
trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTableEntry.java
trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTypes.java
trunk/fs/src/test/org/jnode/test/fs/filesystem/AbstractFSTest.java
trunk/fs/src/test/org/jnode/test/fs/filesystem/FSConfigurations.java
trunk/fs/src/test/org/jnode/test/fs/filesystem/FSContext.java
trunk/fs/src/test/org/jnode/test/fs/filesystem/FSTestSuite.java
trunk/fs/src/test/org/jnode/test/fs/filesystem/config/DeviceParam.java
trunk/fs/src/test/org/jnode/test/fs/filesystem/config/FileParam.java
trunk/fs/src/test/org/jnode/test/fs/filesystem/config/JNodeDeviceParam.java
trunk/fs/src/test/org/jnode/test/fs/filesystem/config/ResourceParam.java
Modified: trunk/fs/build.xml
===================================================================
--- trunk/fs/build.xml 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/build.xml 2007-02-11 22:19:06 UTC (rev 3117)
@@ -63,6 +63,16 @@
<target name="clean">
<jnode.clean/>
</target>
+
+<!-- tests FileSystems -->
+ <target name="tests" depends="compile" description="Run FS tests with JUnit">
+ <junit fork="yes" haltonerror="false" haltonfailure="false" printsummary="on" includeantruntime="true">
+ <classpath refid="cp-jnode" />
+
+ <formatter type="plain" usefile="false" />
+ <test name="org.jnode.test.fs.AllFSTest" />
+ </junit>
+ </target>
</project>
Modified: trunk/fs/descriptors/org.jnode.partitions.command.xml
===================================================================
--- trunk/fs/descriptors/org.jnode.partitions.command.xml 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/descriptors/org.jnode.partitions.command.xml 2007-02-11 22:19:06 UTC (rev 3117)
@@ -17,6 +17,7 @@
<runtime>
<library name="jnode-fs.jar">
<export name="org.jnode.partitions.command.*"/>
+ <export name="org.jnode.partitions.help.argument.*"/>
</library>
</runtime>
Modified: trunk/fs/src/driver/org/jnode/driver/block/PartitionableBlockAlignmentSupport.java
===================================================================
--- trunk/fs/src/driver/org/jnode/driver/block/PartitionableBlockAlignmentSupport.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/driver/org/jnode/driver/block/PartitionableBlockAlignmentSupport.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -24,20 +24,22 @@
import java.io.IOException;
import org.jnode.partitions.PartitionTable;
+import org.jnode.partitions.PartitionTableEntry;
/**
* @author Ewout Prangsma (ep...@us...)
*/
-public class PartitionableBlockAlignmentSupport extends BlockAlignmentSupport
- implements PartitionableBlockDeviceAPI {
+public class PartitionableBlockAlignmentSupport <PTE extends PartitionTableEntry>
+ extends BlockAlignmentSupport
+ implements PartitionableBlockDeviceAPI<PTE> {
- private final PartitionableBlockDeviceAPI parentApi;
+ private final PartitionableBlockDeviceAPI<PTE> parentApi;
/**
* @param parentApi
* @param alignment
*/
- public PartitionableBlockAlignmentSupport(PartitionableBlockDeviceAPI parentApi, int alignment) {
+ public PartitionableBlockAlignmentSupport(PartitionableBlockDeviceAPI<PTE> parentApi, int alignment) {
super(parentApi, alignment);
this.parentApi = parentApi;
}
@@ -54,7 +56,7 @@
* @return Null if no partition table is found.
* @throws IOException
*/
- public PartitionTable getPartitionTable() throws IOException {
+ public PartitionTable<PTE> getPartitionTable() throws IOException {
return parentApi.getPartitionTable();
}
}
Modified: trunk/fs/src/driver/org/jnode/driver/block/PartitionableBlockDeviceAPI.java
===================================================================
--- trunk/fs/src/driver/org/jnode/driver/block/PartitionableBlockDeviceAPI.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/driver/org/jnode/driver/block/PartitionableBlockDeviceAPI.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -24,6 +24,7 @@
import java.io.IOException;
import org.jnode.partitions.PartitionTable;
+import org.jnode.partitions.PartitionTableEntry;
/**
* This device API is implemented by block devices that
@@ -31,7 +32,9 @@
*
* @author Ewout Prangsma (ep...@us...)
*/
-public interface PartitionableBlockDeviceAPI extends BlockDeviceAPI {
+public interface PartitionableBlockDeviceAPI
+ <PTE extends PartitionTableEntry>
+ extends BlockDeviceAPI {
/**
* Gets the sector size for this device.
@@ -45,5 +48,5 @@
* @return Null if no partition table is found.
* @throws IOException
*/
- public PartitionTable getPartitionTable() throws IOException;
+ public PartitionTable<PTE> getPartitionTable() throws IOException;
}
Modified: trunk/fs/src/driver/org/jnode/driver/block/ide/disk/IDEDiskDriver.java
===================================================================
--- trunk/fs/src/driver/org/jnode/driver/block/ide/disk/IDEDiskDriver.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/driver/org/jnode/driver/block/ide/disk/IDEDiskDriver.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -52,11 +52,9 @@
import org.jnode.driver.bus.ide.command.IDEReadSectorsCommand;
import org.jnode.driver.bus.ide.command.IDEWriteSectorsCommand;
import org.jnode.naming.InitialNaming;
-import org.jnode.partitions.PartitionTable;
import org.jnode.partitions.ibm.IBMPartitionTable;
import org.jnode.partitions.ibm.IBMPartitionTableEntry;
import org.jnode.system.BootLog;
-import org.jnode.util.ByteBufferUtils;
import org.jnode.util.TimeoutException;
/**
@@ -64,7 +62,8 @@
*
* @author epr
*/
-public class IDEDiskDriver extends Driver implements IDEDeviceAPI, IDEConstants {
+public class IDEDiskDriver extends Driver
+ implements IDEDeviceAPI<IBMPartitionTableEntry>, IDEConstants {
/** My logger */
private static final Logger log = Logger.getLogger(IDEDiskDriver.class);
@@ -115,35 +114,23 @@
this.pt = factory.createIBMPartitionTable(bs, dev);
int partIndex = 0;
- final int max = pt.getLength();
- for (int i = 0; i < max; i++) {
- final IBMPartitionTableEntry pte = (IBMPartitionTableEntry)pt.getEntry(i);
+ int i = 0;
+ for (IBMPartitionTableEntry pte : pt) {
if(pte == null)
{
BootLog.warn("PartitionTableEntry #"+i+" is null");
}
else if (pte.isValid()) {
if (pte.isExtended()) {
- //now we should have an filled vector in the pt
- final List<IBMPartitionTableEntry> extendedPartitions = pt.getExtendedPartitions();
- log.info("Have "+ extendedPartitions.size()+ " Extended partitions found");
-
- for(int iPart = 0 ; iPart < extendedPartitions.size() ; iPart++)
- {
- IBMPartitionTableEntry pteExt =
- extendedPartitions.get(iPart);
- registerPartition(devMan, dev, pteExt, partIndex);
-
- if(iPart < (extendedPartitions.size() -1))
- partIndex++;
- }
-
+ // Create partition devices for the extended partition
+ partIndex = registerExtendedPartition(devMan, dev, partIndex);
} else {
// Create a partition device.
registerPartition(devMan, dev, pte, partIndex);
}
}
partIndex++;
+ i++;
}
} catch (DeviceAlreadyRegisteredException ex) {
throw new DriverException("Partition device is already known???? Probably a bug", ex);
@@ -314,6 +301,34 @@
pdev.setDriver(new IDEDiskPartitionDriver());
devMan.register(pdev);
}
+
+ /**
+ * register all the partitions included in the extended partition
+ * @param devMan
+ * @param dev
+ * @param partIndex
+ * @return
+ * @throws DeviceAlreadyRegisteredException
+ * @throws DriverException
+ */
+ private int registerExtendedPartition(DeviceManager devMan, IDEDevice dev,
+ int partIndex) throws DeviceAlreadyRegisteredException, DriverException
+ {
+ //now we should have an filled vector in the pt
+ final List<IBMPartitionTableEntry> extendedPartitions = pt.getExtendedPartitions();
+ log.info("Have "+ extendedPartitions.size()+ " Extended partitions found");
+
+ for(int iPart = 0 ; iPart < extendedPartitions.size() ; iPart++)
+ {
+ IBMPartitionTableEntry pteExt =
+ extendedPartitions.get(iPart);
+ registerPartition(devMan, dev, pteExt, partIndex);
+
+ if(iPart < (extendedPartitions.size() -1))
+ partIndex++;
+ }
+ return partIndex;
+ }
/**
* @see org.jnode.driver.block.PartitionableBlockDeviceAPI#getSectorSize()
@@ -327,7 +342,7 @@
* @return Null if no partition table is found.
* @throws IOException
*/
- public PartitionTable getPartitionTable() throws IOException {
+ public IBMPartitionTable getPartitionTable() throws IOException {
return pt;
}
}
Modified: trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEDeviceAPI.java
===================================================================
--- trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEDeviceAPI.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/driver/org/jnode/driver/bus/ide/IDEDeviceAPI.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -22,10 +22,12 @@
package org.jnode.driver.bus.ide;
import org.jnode.driver.block.PartitionableBlockDeviceAPI;
+import org.jnode.partitions.PartitionTableEntry;
/**
* @author epr
*/
-public interface IDEDeviceAPI extends PartitionableBlockDeviceAPI {
+public interface IDEDeviceAPI <PTE extends PartitionTableEntry>
+ extends PartitionableBlockDeviceAPI<PTE> {
// nothing different
}
Modified: trunk/fs/src/fs/org/jnode/fs/fat/BootSector.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/fat/BootSector.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/fs/org/jnode/fs/fat/BootSector.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -356,6 +356,11 @@
return dirty;
}
+ public int getNbPartitions()
+ {
+ return partitions.length;
+ }
+
public synchronized IBMPartitionTableEntry getPartition(int partNr) {
if (partitions[partNr] == null) {
partitions[partNr] = new IBMPartitionTableEntry(null, data, partNr);
Modified: trunk/fs/src/fs/org/jnode/fs/fat/FatFileSystemType.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/fat/FatFileSystemType.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/fs/org/jnode/fs/fat/FatFileSystemType.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -69,15 +69,17 @@
return false;
}
final IBMPartitionTableEntry ipte = (IBMPartitionTableEntry)pte;
- final int type = ipte.getSystemIndicator();
- switch (type) {
- case IBMPartitionTypes.PARTTYPE_DOS_FAT12 :
- case IBMPartitionTypes.PARTTYPE_DOS_FAT16_LT32M :
- case IBMPartitionTypes.PARTTYPE_DOS_FAT16_GT32M :
- return true;
- default :
- return false;
+ final IBMPartitionTypes type = ipte.getSystemIndicator();
+ if((type == IBMPartitionTypes.PARTTYPE_DOS_FAT12) ||
+ (type == IBMPartitionTypes.PARTTYPE_DOS_FAT16_LT32M) ||
+ (type == IBMPartitionTypes.PARTTYPE_DOS_FAT16_GT32M) )
+ {
+ return true;
}
+ else
+ {
+ return false;
+ }
}
Modified: trunk/fs/src/fs/org/jnode/fs/jfat/FatFileSystemType.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/jfat/FatFileSystemType.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/fs/org/jnode/fs/jfat/FatFileSystemType.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -43,18 +43,18 @@
return false;
final IBMPartitionTableEntry ipte =
- (IBMPartitionTableEntry)pte;
+ (IBMPartitionTableEntry)pte;
- final int type = ipte.getSystemIndicator();
-
- switch ( type ) {
- case IBMPartitionTypes.PARTTYPE_WIN95_FAT32:
- case IBMPartitionTypes.PARTTYPE_WIN95_FAT32_LBA:
- return true;
-
- default:
- return false;
- }
+ final IBMPartitionTypes type = ipte.getSystemIndicator();
+ if((type == IBMPartitionTypes.PARTTYPE_WIN95_FAT32) ||
+ (type == IBMPartitionTypes.PARTTYPE_WIN95_FAT32_LBA) )
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
return false;
Modified: trunk/fs/src/fs/org/jnode/fs/ntfs/NTFSFileSystemType.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/ntfs/NTFSFileSystemType.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/fs/org/jnode/fs/ntfs/NTFSFileSystemType.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -52,8 +52,10 @@
FSBlockDeviceAPI devApi) {
if (pte instanceof IBMPartitionTableEntry) {
IBMPartitionTableEntry iPte = (IBMPartitionTableEntry) pte;
- if (iPte.getSystemIndicator() == IBMPartitionTypes.PARTTYPE_NTFS) { return new String(
- firstSector, 0x03, 8).startsWith(TAG); }
+ if (iPte.getSystemIndicator() == IBMPartitionTypes.PARTTYPE_NTFS)
+ {
+ return new String(firstSector, 0x03, 8).startsWith(TAG);
+ }
}
return false;
}
Modified: trunk/fs/src/fs/org/jnode/partitions/PartitionTable.java
===================================================================
--- trunk/fs/src/fs/org/jnode/partitions/PartitionTable.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/fs/org/jnode/partitions/PartitionTable.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -24,21 +24,11 @@
/**
* @author epr
*/
-public interface PartitionTable {
+public interface PartitionTable <PTE extends PartitionTableEntry>
+ extends Iterable<PTE> {
/**
* Gets the type of this partition table
*/
public PartitionTableType getType();
-
- /**
- * Gets the number of entries in this table
- */
- public int getLength();
-
- /**
- * Gets the partition table entry at the given index.
- * @param index
- */
- public PartitionTableEntry getEntry(int index);
}
Modified: trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java
===================================================================
--- trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/fs/org/jnode/partitions/command/FdiskCommand.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -25,7 +25,7 @@
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.List;
-import java.util.StringTokenizer;
+import java.util.NoSuchElementException;
import javax.naming.NameNotFoundException;
@@ -33,14 +33,12 @@
import org.jnode.driver.Device;
import org.jnode.driver.DeviceManager;
import org.jnode.driver.DeviceNotFoundException;
-import org.jnode.driver.DriverException;
import org.jnode.driver.block.BlockDeviceAPI;
import org.jnode.driver.bus.ide.IDEConstants;
import org.jnode.driver.bus.ide.IDEDevice;
import org.jnode.driver.bus.ide.IDEDriveDescriptor;
-import org.jnode.fs.fat.BootSector;
-import org.jnode.fs.fat.GrubBootSector;
import org.jnode.naming.InitialNaming;
+import org.jnode.partitions.help.argument.IBMPartitionTypeArgument;
import org.jnode.partitions.ibm.IBMPartitionTable;
import org.jnode.partitions.ibm.IBMPartitionTableEntry;
import org.jnode.partitions.ibm.IBMPartitionTableType;
@@ -51,8 +49,11 @@
import org.jnode.shell.help.Syntax;
import org.jnode.shell.help.SyntaxErrorException;
import org.jnode.shell.help.argument.DeviceArgument;
+import org.jnode.shell.help.argument.IntegerArgument;
+import org.jnode.shell.help.argument.LongArgument;
import org.jnode.shell.help.argument.OptionArgument;
-import org.jnode.shell.help.argument.StringArgument;
+import org.jnode.shell.help.argument.SizeArgument;
+
/**
* @author gbin
* @author Trickkiste
@@ -72,50 +73,54 @@
"Action on a specified partition",
new OptionArgument.Option[] {
new OptionArgument.Option("-d", "Delete a partition"),
- new OptionArgument.Option("-b", "Switch the bootable flag of a partition"),
+ new OptionArgument.Option("-b", "Switch the bootable flag of a partition")});
+
+ static final OptionArgument ACTION_MODIFY =
+ new OptionArgument(
+ "action",
+ "Action on a specified partition",
+ new OptionArgument.Option[] {
new OptionArgument.Option("-m", "Modify/create a partition")});
- static final StringArgument PARTITION = new StringArgument("partition number", "Targeted partition");
- static final StringArgument PARTITION_DESCRIPTION = new StringArgument("description", "Partition description" +
- " \"ID:start:size:filesystem\"" +
- " ID : ID of the partition" +
- " start : Sector where the partition starts" +
- " size : Size of the partition in sectors" +
- " filesystem : Number of the filesystem type");
+ static final IntegerArgument PARTITION = new IntegerArgument("partition number", "Targeted partition");
+ static final LongArgument START = new LongArgument("start", "Sector where the partition starts");
+ static final SizeArgument SIZE = new SizeArgument("size", "Size of the partition in sectors or in bytes(use prefixes K, M, G, ...)");
+ static final IBMPartitionTypeArgument PARTITION_TYPE = new IBMPartitionTypeArgument(
+ "partition type", "partition type code");
static final DeviceArgument ARG_DEVICE =
new DeviceArgument("device-id", "the device on which you want to change/create the partition");
static final Parameter PARAM_INITMBR = new Parameter(INITMBR, Parameter.MANDATORY);
static final Parameter PARAM_ACTION = new Parameter(ACTION, Parameter.MANDATORY);
+ static final Parameter PARAM_ACTION_MODIFY = new Parameter(ACTION_MODIFY, Parameter.MANDATORY);
static final Parameter PARAM_DEVICE = new Parameter(ARG_DEVICE, Parameter.MANDATORY);
static final Parameter PARAM_PARTITION = new Parameter(PARTITION, Parameter.MANDATORY);
- static final Parameter PARAM_PARTITION_DESCRIPTION = new Parameter(PARTITION_DESCRIPTION, Parameter.MANDATORY);
+ static final Parameter PARAM_START = new Parameter(START, Parameter.MANDATORY);
+ static final Parameter PARAM_SIZE = new Parameter(SIZE, Parameter.MANDATORY);
+ static final Parameter PARAM_PARTITION_TYPE = new Parameter(PARTITION_TYPE, Parameter.MANDATORY);
public static Help.Info HELP_INFO =
new Help.Info(
"fdisk",
new Syntax[] {
new Syntax("Lists the available devices"),
- new Syntax("Print the partition table of a device", new Parameter[] { PARAM_DEVICE }),
- new Syntax("Initialize the MBR of a device", new Parameter[] { PARAM_INITMBR, PARAM_DEVICE }),
- new Syntax(
- "Create / Delete / change a partition",
- new Parameter[] { PARAM_ACTION, PARAM_PARTITION, PARAM_DEVICE }),
- new Syntax(
- "Create / Delete / change a partition",
- new Parameter[] { PARAM_ACTION, PARAM_PARTITION_DESCRIPTION, PARAM_DEVICE })
+ new Syntax("Print the partition table of a device",
+ new Parameter[] {
+ PARAM_DEVICE }),
+ new Syntax("Initialize the MBR of a device",
+ new Parameter[] {
+ PARAM_INITMBR, PARAM_DEVICE }),
+ new Syntax("Change a partition",
+ new Parameter[] {
+ PARAM_ACTION_MODIFY, PARAM_PARTITION, PARAM_START,
+ PARAM_SIZE, PARAM_PARTITION_TYPE,
+ PARAM_DEVICE }),
+ new Syntax("Delete a partition / switch bootable flag",
+ new Parameter[] {
+ PARAM_ACTION, PARAM_PARTITION, PARAM_DEVICE }),
});
- /*
- * public static Help.Info HELP_INFO = new Help.Info( "fdisk", "With no
- * argument, it lists the available devices\n" + "With only the device, it
- * lists the current partitions on the device\n" + "--initmbr initialize the
- * Master Boot Record of the device\n" + "-m add or modify the id partition
- * with first sector at start, size of size sectors and fs id fs\n" + "-d
- * delete the partition with id id" + "-b switch boot flag on parition id",
- */
-
public static void main(String[] args) throws SyntaxErrorException {
ParsedArguments cmdLine = HELP_INFO.parse(args);
@@ -124,6 +129,7 @@
dm = InitialNaming.lookup(DeviceManager.NAME);
boolean isAction = PARAM_ACTION.isSet(cmdLine);
+ boolean isActionModify = PARAM_ACTION_MODIFY.isSet(cmdLine);
boolean isInitMBR = PARAM_INITMBR.isSet(cmdLine);
boolean isDevice = PARAM_DEVICE.isSet(cmdLine);
@@ -134,56 +140,41 @@
}
// only device is set
- if (!isAction && !isInitMBR && isDevice) {
+ if (!isAction && !isActionModify && !isInitMBR && isDevice) {
printTable(ARG_DEVICE.getValue(cmdLine), dm);
return;
}
+ final String deviceId = ARG_DEVICE.getValue(cmdLine);
+ final PartitionHelper helper = new PartitionHelper(deviceId, dm);
+
// initMBR
if (isInitMBR) {
- initMbr(ARG_DEVICE.getValue(cmdLine), dm);
+ helper.initMbr();
+ helper.write();
return;
}
- // now it is a change on a specific partition so read the table
+ int partNumber = getPartitionNumber(helper, cmdLine);
- IDEDevice current = (IDEDevice)dm.getDevice(ARG_DEVICE.getValue(cmdLine));
- BlockDeviceAPI api = current.getAPI(BlockDeviceAPI.class);
- ByteBuffer mbr = ByteBuffer.allocate(IDEConstants.SECTOR_SIZE);
- api.read(0, mbr);
- if (!IBMPartitionTable.containsPartitionTable(mbr.array()))
- throw new IOException("This device doesn't contain a valid MBR, use --initmbr.");
-
- BootSector bs = new BootSector(mbr.array());
-
- if (ACTION.getValue(cmdLine).intern() == "-m") {
- modifyPartition(PARTITION.getValue(cmdLine), api, bs, current);
- bs.write(api);
+ // modify a partition ?
+ if (ACTION_MODIFY.getValue(cmdLine).intern() == "-m") {
+ modifyPartition(helper, partNumber, cmdLine);
+ helper.write();
return;
}
- // it is not a modify so the PARTITION parameter is only a partition
- // number
-
- int partNumber;
- try {
- partNumber = Integer.parseInt(PARTITION.getValue(cmdLine));
- } catch (NumberFormatException f) {
- throw new IllegalArgumentException("Partition number is invalid");
- }
-
- if (partNumber > 3 || partNumber < 0)
- throw new IllegalArgumentException("Partition number is invalid");
-
+ // delete a partition ?
if (ACTION.getValue(cmdLine).intern() == "-d") {
- deletePartition(bs, partNumber);
- bs.write(api);
+ helper.deletePartition(partNumber);
+ helper.write();
return;
}
+ // toggle boot flag for a partition ?
if (ACTION.getValue(cmdLine).intern() == "-b") {
- toggleBootable(bs, partNumber);
- bs.write(api);
+ helper.toggleBootable(partNumber);
+ helper.write();
}
} catch (IOException e) {
e.printStackTrace();
@@ -194,99 +185,56 @@
} catch (DeviceNotFoundException e) {
e.printStackTrace();
}
-
}
+
+ private static int getPartitionNumber(PartitionHelper helper, ParsedArguments cmdLine)
+ {
+ int partNumber = PARTITION.getInteger(cmdLine);
- private static void toggleBootable(BootSector bs, int partNumber) {
- // save the current state for the targeted partition
- boolean currentStatus = bs.getPartition(partNumber).getBootIndicator();
-
- // erase all the states
- for (int i = 0; i < 4; i++) {
- bs.getPartition(i).setBootIndicator(false);
- }
-
- // put back the reversed state for the targeted partition
- bs.getPartition(partNumber).setBootIndicator(!currentStatus);
+ if ((partNumber >= helper.getNbPartitions()) ||
+ (partNumber < 0) )
+ throw new IllegalArgumentException("Partition number is invalid");
+
+ return partNumber;
}
- private static void deletePartition(BootSector bs, int partNumber) {
- bs.getPartition(partNumber).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY);
- }
-
- private static void modifyPartition(String description, BlockDeviceAPI api, BootSector bs, Device dev) throws IOException {
- // arg 1 should be in the form id:start:size:fs
- StringTokenizer st = new StringTokenizer(description, ":");
- int id = Integer.parseInt(st.nextToken());
- //BUG in long
- //long start = Long.parseLong(st.nextToken());
- //long size = Long.parseLong(st.nextToken());
- int start = Integer.parseInt(st.nextToken());
- int size = Integer.parseInt(st.nextToken());
- int fs = Integer.parseInt(st.nextToken(), 16);
- System.out.println(
- "Init " + id + " with start = " + start + ", size = " + size + ", fs = " + Integer.toHexString(fs & 0xff));
- IBMPartitionTableEntry entry = bs.getPartition(id);
- entry.setBootIndicator(false);
- entry.setSystemIndicator(fs);
- entry.setStartLba(start);
- entry.setNrSectors(size);
- bs.write(api);
-
-// restart the device
- DeviceManager dm = null;
-
- try {
- dm = InitialNaming.lookup(DeviceManager.NAME);
- dm.stop(dev);
- dm.start(dev);
+ private static void modifyPartition(PartitionHelper helper,
+ int id,
+ ParsedArguments cmdLine)
+ throws IOException
+ {
+ long start = START.getLong(cmdLine);
+ long size = SIZE.getLong(cmdLine);
+ IBMPartitionTypes type = PARTITION_TYPE.getArgValue(cmdLine);
- } catch (NameNotFoundException e) {
-
- e.printStackTrace();
- } catch (DeviceNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (DriverException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
-
- return;
+// try {
+ System.out.println("D");
+ System.out.println("Init " + id + " with start = " + start
+ + ", size = " + size + ", fs = "
+ + Integer.toHexString(type.getCode() & 0xff));
+ System.out.println("E");
+ boolean sizeUnit = SIZE.hasSizeUnit(cmdLine) ?
+ PartitionHelper.BYTES : PartitionHelper.SECTORS;
+ helper.modifyPartition(id, false, start, size, sizeUnit, type);
+ System.out.println("F");
+// }
+// catch (NumberFormatException nfe)
+// {
+// System.err.println("not an integer");
+// System.err.println(helpMsg);
+// }
+// catch (NoSuchElementException nsee)
+// {
+// System.err.println("not enough elements");
+// System.err.println(helpMsg);
+// }
+// catch (IllegalArgumentException iae)
+// {
+// System.err.println(iae.getMessage());
+// System.err.println(helpMsg);
+// }
}
-
- private static void initMbr(String device, DeviceManager dm)
- throws DeviceNotFoundException, ApiNotFoundException, IOException {
- IDEDevice current = (IDEDevice)dm.getDevice(device);
- BlockDeviceAPI api = current.getAPI(BlockDeviceAPI.class);
- ByteBuffer MBR = ByteBuffer.allocate(IDEConstants.SECTOR_SIZE);
- api.read(0, MBR);
-
- System.out.println("Initialize MBR ...");
-
- GrubBootSector newMBR = new GrubBootSector(PLAIN_MASTER_BOOT_SECTOR);
-
- if (IBMPartitionTable.containsPartitionTable(MBR.array())) {
- BootSector oldMBR = new BootSector(MBR.array());
- System.out.println("This device already contains a partition table. Copy the already existing partitions.");
- for (int i = 0; i < 4; i++) {
- IBMPartitionTableEntry entry = newMBR.getPartition(i);
- entry.setBootIndicator(oldMBR.getPartition(i).getBootIndicator());
- entry.setStartLba(oldMBR.getPartition(i).getStartLba());
- entry.setNrSectors(oldMBR.getPartition(i).getNrSectors());
- entry.setSystemIndicator(oldMBR.getPartition(i).getSystemIndicator());
-
- }
- } else {
- newMBR.getPartition(0).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY);
- newMBR.getPartition(1).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY);
- newMBR.getPartition(2).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY);
- newMBR.getPartition(3).setSystemIndicator(IBMPartitionTypes.PARTTYPE_EMPTY);
- }
- newMBR.write(api);
- }
-
+
private static void printTable(String deviceName, DeviceManager dm)
throws DeviceNotFoundException, ApiNotFoundException, IOException {
{
@@ -297,16 +245,16 @@
api.read(0, MBR);
if (IBMPartitionTable.containsPartitionTable(MBR.array())) {
IBMPartitionTable partitionTable = new IBMPartitionTable(new IBMPartitionTableType(), MBR.array(), current);
- int nbPartitions = partitionTable.getLength();
System.out.println(
"Disk : " + current.getId() + ": " + descriptor.getSectorsIn28bitAddressing() * 512 + " bytes");
System.out.println("Device Boot Start End Blocks System");
- for (int i = 0; i < nbPartitions; i++) {
- IBMPartitionTableEntry entry = (IBMPartitionTableEntry)partitionTable.getEntry(i);
- int si = entry.getSystemIndicator();
- if (si != 0)
+ int i = 0;
+ for (IBMPartitionTableEntry entry : partitionTable) {
+ //IBMPartitionTableEntry entry = (IBMPartitionTableEntry)partitionTable.getEntry(i);
+ IBMPartitionTypes si = entry.getSystemIndicator();
+ if (si != IBMPartitionTypes.PARTTYPE_EMPTY)
System.out.println(
"ID "
+ i
@@ -319,7 +267,7 @@
+ " "
+ entry.getNrSectors()
+ " "
- + Integer.toHexString(si));
+ + si);
if(entry.isExtended()) {
final List<IBMPartitionTableEntry> exPartitions = partitionTable.getExtendedPartitions();
int j = 0;
@@ -337,11 +285,11 @@
+ " "
+ "-----"//exEntry.getNrSectors()
+ " "
- + Integer.toHexString(si));
+ + si);
j++;
}
}
-
+ i++;
}
} else {
@@ -371,520 +319,4 @@
}
}
}
-
- private static final byte PLAIN_MASTER_BOOT_SECTOR[] =
- {
- (byte)0xEB,
- (byte)0x48,
- (byte)0x90,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x03,
- (byte)0x02,
- (byte)0xFF,
- (byte)0x00,
- (byte)0x00,
- (byte)0x80,
- (byte)0x01,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x08,
- (byte)0xFA,
- (byte)0xEA,
- (byte)0x50,
- (byte)0x7C,
- (byte)0x00,
- (byte)0x00,
- (byte)0x31,
- (byte)0xC0,
- (byte)0x8E,
- (byte)0xD8,
- (byte)0x8E,
- (byte)0xD0,
- (byte)0xBC,
- (byte)0x00,
- (byte)0x20,
- (byte)0xFB,
- (byte)0xA0,
- (byte)0x40,
- (byte)0x7C,
- (byte)0x3C,
- (byte)0xFF,
- (byte)0x74,
- (byte)0x02,
- (byte)0x88,
- (byte)0xC2,
- (byte)0x52,
- (byte)0xBE,
- (byte)0x76,
- (byte)0x7D,
- (byte)0xE8,
- (byte)0x34,
- (byte)0x01,
- (byte)0xF6,
- (byte)0xC2,
- (byte)0x80,
- (byte)0x74,
- (byte)0x54,
- (byte)0xB4,
- (byte)0x41,
- (byte)0xBB,
- (byte)0xAA,
- (byte)0x55,
- (byte)0xCD,
- (byte)0x13,
- (byte)0x5A,
- (byte)0x52,
- (byte)0x72,
- (byte)0x49,
- (byte)0x81,
- (byte)0xFB,
- (byte)0x55,
- (byte)0xAA,
- (byte)0x75,
- (byte)0x43,
- (byte)0xA0,
- (byte)0x41,
- (byte)0x7C,
- (byte)0x84,
- (byte)0xC0,
- (byte)0x75,
- (byte)0x05,
- (byte)0x83,
- (byte)0xE1,
- (byte)0x01,
- (byte)0x74,
- (byte)0x37,
- (byte)0x66,
- (byte)0x8B,
- (byte)0x4C,
- (byte)0x10,
- (byte)0xBE,
- (byte)0x05,
- (byte)0x7C,
- (byte)0xC6,
- (byte)0x44,
- (byte)0xFF,
- (byte)0x01,
- (byte)0x66,
- (byte)0x8B,
- (byte)0x1E,
- (byte)0x44,
- (byte)0x7C,
- (byte)0xC7,
- (byte)0x04,
- (byte)0x10,
- (byte)0x00,
- (byte)0xC7,
- (byte)0x44,
- (byte)0x02,
- (byte)0x01,
- (byte)0x00,
- (byte)0x66,
- (byte)0x89,
- (byte)0x5C,
- (byte)0x08,
- (byte)0xC7,
- (byte)0x44,
- (byte)0x06,
- (byte)0x00,
- (byte)0x70,
- (byte)0x66,
- (byte)0x31,
- (byte)0xC0,
- (byte)0x89,
- (byte)0x44,
- (byte)0x04,
- (byte)0x66,
- (byte)0x89,
- (byte)0x44,
- (byte)0x0C,
- (byte)0xB4,
- (byte)0x42,
- (byte)0xCD,
- (byte)0x13,
- (byte)0x72,
- (byte)0x05,
- (byte)0xBB,
- (byte)0x00,
- (byte)0x70,
- (byte)0xEB,
- (byte)0x7D,
- (byte)0xB4,
- (byte)0x08,
- (byte)0xCD,
- (byte)0x13,
- (byte)0x73,
- (byte)0x0A,
- (byte)0xF6,
- (byte)0xC2,
- (byte)0x80,
- (byte)0x0F,
- (byte)0x84,
- (byte)0xF3,
- (byte)0x00,
- (byte)0xE9,
- (byte)0x8D,
- (byte)0x00,
- (byte)0xBE,
- (byte)0x05,
- (byte)0x7C,
- (byte)0xC6,
- (byte)0x44,
- (byte)0xFF,
- (byte)0x00,
- (byte)0x66,
- (byte)0x31,
- (byte)0xC0,
- (byte)0x88,
- (byte)0xF0,
- (byte)0x40,
- (byte)0x66,
- (byte)0x89,
- (byte)0x44,
- (byte)0x04,
- (byte)0x31,
- (byte)0xD2,
- (byte)0x88,
- (byte)0xCA,
- (byte)0xC1,
- (byte)0xE2,
- (byte)0x02,
- (byte)0x88,
- (byte)0xE8,
- (byte)0x88,
- (byte)0xF4,
- (byte)0x40,
- (byte)0x89,
- (byte)0x44,
- (byte)0x08,
- (byte)0x31,
- (byte)0xC0,
- (byte)0x88,
- (byte)0xD0,
- (byte)0xC0,
- (byte)0xE8,
- (byte)0x02,
- (byte)0x66,
- (byte)0x89,
- (byte)0x04,
- (byte)0x66,
- (byte)0xA1,
- (byte)0x44,
- (byte)0x7C,
- (byte)0x66,
- (byte)0x31,
- (byte)0xD2,
- (byte)0x66,
- (byte)0xF7,
- (byte)0x34,
- (byte)0x88,
- (byte)0x54,
- (byte)0x0A,
- (byte)0x66,
- (byte)0x31,
- (byte)0xD2,
- (byte)0x66,
- (byte)0xF7,
- (byte)0x74,
- (byte)0x04,
- (byte)0x88,
- (byte)0x54,
- (byte)0x0B,
- (byte)0x89,
- (byte)0x44,
- (byte)0x0C,
- (byte)0x3B,
- (byte)0x44,
- (byte)0x08,
- (byte)0x7D,
- (byte)0x3C,
- (byte)0x8A,
- (byte)0x54,
- (byte)0x0D,
- (byte)0xC0,
- (byte)0xE2,
- (byte)0x06,
- (byte)0x8A,
- (byte)0x4C,
- (byte)0x0A,
- (byte)0xFE,
- (byte)0xC1,
- (byte)0x08,
- (byte)0xD1,
- (byte)0x8A,
- (byte)0x6C,
- (byte)0x0C,
- (byte)0x5A,
- (byte)0x8A,
- (byte)0x74,
- (byte)0x0B,
- (byte)0xBB,
- (byte)0x00,
- (byte)0x70,
- (byte)0x8E,
- (byte)0xC3,
- (byte)0x31,
- (byte)0xDB,
- (byte)0xB8,
- (byte)0x01,
- (byte)0x02,
- (byte)0xCD,
- (byte)0x13,
- (byte)0x72,
- (byte)0x2A,
- (byte)0x8C,
- (byte)0xC3,
- (byte)0x8E,
- (byte)0x06,
- (byte)0x48,
- (byte)0x7C,
- (byte)0x60,
- (byte)0x1E,
- (byte)0xB9,
- (byte)0x00,
- (byte)0x01,
- (byte)0x8E,
- (byte)0xDB,
- (byte)0x31,
- (byte)0xF6,
- (byte)0x31,
- (byte)0xFF,
- (byte)0xFC,
- (byte)0xF3,
- (byte)0xA5,
- (byte)0x1F,
- (byte)0x61,
- (byte)0xFF,
- (byte)0x26,
- (byte)0x42,
- (byte)0x7C,
- (byte)0xBE,
- (byte)0x7C,
- (byte)0x7D,
- (byte)0xE8,
- (byte)0x40,
- (byte)0x00,
- (byte)0xEB,
- (byte)0x0E,
- (byte)0xBE,
- (byte)0x81,
- (byte)0x7D,
- (byte)0xE8,
- (byte)0x38,
- (byte)0x00,
- (byte)0xEB,
- (byte)0x06,
- (byte)0xBE,
- (byte)0x8B,
- (byte)0x7D,
- (byte)0xE8,
- (byte)0x30,
- (byte)0x00,
- (byte)0xBE,
- (byte)0x90,
- (byte)0x7D,
- (byte)0xE8,
- (byte)0x2A,
- (byte)0x00,
- (byte)0xEB,
- (byte)0xFE,
- (byte)0x47,
- (byte)0x52,
- (byte)0x55,
- (byte)0x42,
- (byte)0x20,
- (byte)0x00,
- (byte)0x47,
- (byte)0x65,
- (byte)0x6F,
- (byte)0x6D,
- (byte)0x00,
- (byte)0x48,
- (byte)0x61,
- (byte)0x72,
- (byte)0x64,
- (byte)0x20,
- (byte)0x44,
- (byte)0x69,
- (byte)0x73,
- (byte)0x6B,
- (byte)0x00,
- (byte)0x52,
- (byte)0x65,
- (byte)0x61,
- (byte)0x64,
- (byte)0x00,
- (byte)0x20,
- (byte)0x45,
- (byte)0x72,
- (byte)0x72,
- (byte)0x6F,
- (byte)0x72,
- (byte)0x00,
- (byte)0xBB,
- (byte)0x01,
- (byte)0x00,
- (byte)0xB4,
- (byte)0x0E,
- (byte)0xCD,
- (byte)0x10,
- (byte)0xAC,
- (byte)0x3C,
- (byte)0x00,
- (byte)0x75,
- (byte)0xF4,
- (byte)0xC3,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x24,
- (byte)0x12,
- (byte)0x0F,
- (byte)0x09,
- (byte)0x00,
- (byte)0xBE,
- (byte)0xBD,
- (byte)0x7D,
- (byte)0x31,
- (byte)0xC0,
- (byte)0xCD,
- (byte)0x13,
- (byte)0x46,
- (byte)0x8A,
- (byte)0x0C,
- (byte)0x80,
- (byte)0xF9,
- (byte)0x00,
- (byte)0x75,
- (byte)0x0F,
- (byte)0xBE,
- (byte)0xDA,
- (byte)0x7D,
- (byte)0xE8,
- (byte)0xC6,
- (byte)0xFF,
- (byte)0xEB,
- (byte)0x94,
- (byte)0x46,
- (byte)0x6C,
- (byte)0x6F,
- (byte)0x70,
- (byte)0x70,
- (byte)0x79,
- (byte)0x00,
- (byte)0xBB,
- (byte)0x00,
- (byte)0x70,
- (byte)0xB8,
- (byte)0x01,
- (byte)0x02,
- (byte)0xB5,
- (byte)0x00,
- (byte)0xB6,
- (byte)0x00,
- (byte)0xCD,
- (byte)0x13,
- (byte)0x72,
- (byte)0xD7,
- (byte)0xB6,
- (byte)0x01,
- (byte)0xB5,
- (byte)0x4F,
- (byte)0xE9,
- (byte)0xDD,
- (byte)0xFE,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x00,
- (byte)0x55,
- (byte)0xAA };
-
}
Modified: trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTable.java
===================================================================
--- trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTable.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTable.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -24,6 +24,9 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
@@ -38,7 +41,7 @@
/**
* @author epr
*/
-public class IBMPartitionTable implements PartitionTable {
+public class IBMPartitionTable implements PartitionTable<IBMPartitionTableEntry> {
/** The type of partition table */
private final IBMPartitionTableType tableType;
@@ -66,9 +69,9 @@
public IBMPartitionTable(IBMPartitionTableType tableType, byte[] bootSector, Device device) {
//this.bootSector = bootSector;
this.tableType = tableType;
- this.partitions = new IBMPartitionTableEntry[4];
this.drivedDevice = device;
if(containsPartitionTable(bootSector)) {
+ this.partitions = new IBMPartitionTableEntry[4];
for (int partNr = 0; partNr < partitions.length ; partNr++) {
log.debug("try part "+ partNr);
partitions[partNr] = new IBMPartitionTableEntry(this, bootSector, partNr);
@@ -79,6 +82,10 @@
}
}
}
+ else
+ {
+ partitions = null;
+ }
}
/**
@@ -142,22 +149,28 @@
return true;
}
- /**
- * Gets the number of partitions in this table.
- */
- public int getLength() {
- return partitions.length;
+ public Iterator<IBMPartitionTableEntry> iterator() {
+ return new Iterator<IBMPartitionTableEntry>()
+ {
+ private int index = 0;
+ private final int last = (partitions == null) ? 0 :
+ partitions.length - 1;
+
+ public boolean hasNext() {
+ return index < last;
+ }
+
+ public IBMPartitionTableEntry next() {
+ return partitions[index++];
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
}
/**
- * Gets a single entry.
- * @param partNr
- */
- public PartitionTableEntry getEntry(int partNr) {
- return partitions[partNr];
- }
-
- /**
* @return Returns the extendedPartitions.
*/
public List<IBMPartitionTableEntry> getExtendedPartitions() {
Modified: trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTableEntry.java
===================================================================
--- trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTableEntry.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTableEntry.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -54,7 +54,7 @@
/**
* @see org.jnode.partitions.PartitionTableEntry#getChildPartitionTable()
*/
- public PartitionTable getChildPartitionTable() {
+ public IBMPartitionTable getChildPartitionTable() {
throw new Error("Not implemented yet");
}
@@ -71,7 +71,7 @@
public boolean isExtended() {
- final int id = getSystemIndicator();
+ final IBMPartitionTypes id = getSystemIndicator();
//pgwiasda
//there are more than one type of extended Partitions
return (id == IBMPartitionTypes.PARTTYPE_WIN95_FAT32_EXTENDED ||
@@ -105,12 +105,12 @@
LittleEndian.setInt8(bs, ofs+3, chs.getCylinder() & 0xFF);
}
- public int getSystemIndicator() {
- return LittleEndian.getUInt8(bs, ofs+4);
+ public IBMPartitionTypes getSystemIndicator() {
+ return IBMPartitionTypes.valueOf(LittleEndian.getUInt8(bs, ofs+4));
}
- public void setSystemIndicator(int v) {
- LittleEndian.setInt8(bs, ofs+4, v);
+ public void setSystemIndicator(IBMPartitionTypes type) {
+ LittleEndian.setInt8(bs, ofs+4, type.getCode());
}
public CHS getEndCHS() {
@@ -171,7 +171,7 @@
b.append(getBootIndicator() ? 'A' : ' ');
b.append(' ');
- b.append(NumberUtils.hex(getSystemIndicator(), 2));
+ b.append(NumberUtils.hex(getSystemIndicator().getCode(), 2));
b.append(' ');
b.append("s:"+getStartLba());
b.append(' ');
Modified: trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTypes.java
===================================================================
--- trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTypes.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/fs/org/jnode/partitions/ibm/IBMPartitionTypes.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -25,104 +25,122 @@
* @author epr
*
**/
-public interface IBMPartitionTypes {
+public enum IBMPartitionTypes {
+ PARTTYPE_EMPTY (0x00, "empty"),
+ PARTTYPE_DOS_FAT12 (0x01, "DOS 12-bit FAT"),
+ PARTTYPE_XENIX_ROOT (0x02, "XENIX root file system"),
+ PARTTYPE_XENIX_USR (0x03, "XENIX /usr file system (obsolete)"),
+ PARTTYPE_DOS_FAT16_LT32M (0x04, "DOS 16-bit FAT (up to 32M)"),
+ PARTTYPE_DOS_EXTENDED (0x05, "DOS 3.3+ extended partition"),
+ PARTTYPE_DOS_FAT16_GT32M (0x06, "DOS 3.31+ Large File System (16-bit FAT, over 32M)"),
+ PARTTYPE_NTFS (0x07, "NTFS, OS/2 HPFS, Advanced Unix"),
+ PARTTYPE_AIX_BOOTABLE (0x08, "AIX bootable partition, SplitDrive"),
+ PARTTYPE_AIX_DATA (0x09, "AIX data partition, Coherent filesystem"),
+ PARTTYPE_OS2_BOOT_MANAGER (0x0A, "OS/2 Boot Manager, OPUS, Coherent swap partition"),
+ PARTTYPE_WIN95_FAT32 (0x0B, "Win 95 Fat Partition"),
+ PARTTYPE_WIN95_FAT32_LBA (0x0C, "Win 95 Fat 32 Partition (LBA)"),
+ PARTTYPE_WIN95_FAT16_LBA (0x0E, "Win 95 Fat 16 Partition (LBA)"),
+ PARTTYPE_WIN95_FAT32_EXTENDED (0x0F, "WIN95 EXTENDED"),
+ PARTTYPE_OPUS (0x10, "OPUS"),
+ PARTTYPE_OS2_BOOT_HIDDEN_12 (0x11, "OS/2 Boot Manager hidden 12-bit FAT partition"),
+ PARTTYPE_COMPAQ_DIAG (0x12, "Compaq Diagnostics partition"),
+ PARTTYPE_OS2_BOOT_HIDDEN_16_S32 (0x14, "(resulted from using Novell DOS 7.0 FDISK to delete Linux Native part), OS/2 Boot Manager hidden sub-32M 16-bit FAT partition"),
+ PARTTYPE_OS2_BOOT_HIDDEN_16_O32 (0x16, "OS/2 Boot Manager hidden over-32M 16-bit FAT partition"),
+ PARTTYPE_OS2_BOOT_HIDDEN_HPFS (0x17, "OS/2 Boot Manager hidden HPFS partition"),
+ PARTTYPE_WINDOWS_SWAP (0x18, "AST special Windows swap file"),
+ PARTTYPE_WIN95_FAT_16_HIDDEN (0x1B, "Hidden Win95"),
+ PARTTYPE_WIN95_FAT_32_HIDDEN (0x1E, "Hidden Win95"),
+ PARTTYPE_NEC_MSDOS (0x24, "NEC MS-DOS 3.x"),
+ PARTTYPE_PLAN_9 (0x39, "Plan 9"),
+ PARTTYPE_POWERQUEST_RECOVERY (0x3C, "PowerQuest PartitionMagic recovery partition"),
+ PARTTYPE_VENIX80286 (0x40, "VENIX 80286"),
+ PARTTYPE_PPC_BOOT (0x41, "PPC_BOOT"),
+ PARTTYPE_SFS (0x42, "SFS (Secure File System) by Peter Gutmann"),
+ PARTTYPE_QNX (0x4d, "QNX"),
+ PARTTYPE_QNX_SECOND (0x4e, "QNX second Part"),
+ PARTTYPE_QNX_THIRD (0x4f, "QNX third Part"),
+ PARTTYPE_DISK_MANAGER_RO (0x50, "Disk Manager, read-only partition"),
+ PARTTYPE_DISK_MANAGER_RW (0x51, "Disk Manager, read/write partition, Novell???"),
+ PARTTYPE_CPM (0x52, "CP/M, Microport System V/386"),
+ PARTTYPE_ONTRACK_AUX (0x53, "Ontrack ?"),
+ PARTTYPE_ONTRACK (0x54, "Ontrack ?"),
+ PARTTYPE_EZ_DRIVE (0x55, "EZ_DRIVE"),
+ PARTTYPE_VFEATURE (0x56, "GoldenBow VFeature"),
+ PARTTYPE_PRIAM_EDISK (0x5c, "Priam Edisk"),
+ PARTTYPE_SPEEDSTOR (0x61, "SpeedStor"),
+ PARTTYPE_UNIX_SYS_V (0x63, "Unix SysV/386, 386/ix; ach, MtXinu BSD 4.3 on Mach; GNU HURD"),
+ PARTTYPE_NOVELL (0x64, "Novell NetWare"),
+ PARTTYPE_NOVELL_31 (0x65, "Novell NetWare (3.11)"),
+ PARTTYPE_DISK_SECURE (0x70, "DiskSecure Multi-Boot"),
+ PARTTYPE_PC_IX (0x75, "PC/IX"),
+ PARTTYPE_MINIX (0x80, "Minix v1.1 - 1.4a"),
+ PARTTYPE_LINUX (0x81, "Linux; Mitac Advanced Disk Manager"),
+ PARTTYPE_LINUX_SWAP (0x82, "Linux Swap partition"),
+ PARTTYPE_LINUXNATIVE (0x83, "Linux native file system (ext2fs/xiafs)"),
+ PARTTYPE_OS2_HIDING_DOS (0x84, "OS/2-renumbered type 04h partition (related to hiding DOS C: drive);"),
+ PARTTYPE_LINUX_EXTENDED (0x85, "Linux extendet partition"),
+ PARTTYPE_LINUX_LVM (0x8E, "Linux LVM"),
+ PARTTYPE_AMOEBA (0x93, "Amoeba file system"),
+ PARTTYPE_AMOEBA_BAD_BLOCK (0x94, "Amoeba bad block table"),
+ PARTTYPE_BSD (0x9F, "BSD"),
+ PARTTYPE_THIK_PAD_HIDDEN (0xA0, "IBM Thinkpad hidden partition"),
+ PARTTYPE_FREE_BSD (0xA5, "FreeBSD"),
+ PARTTYPE_OPEN_BSD (0xA6, "OpenBSD"),
+ PARTTYPE_NEXT_STEP (0xA7, "NextStep"),
+ PARTTYPE_NETBSD (0xA9, "NetBSD"),
+ PARTTYPE_BSDI (0xB7, "BSDI file system (secondarily swap)"),
+ PARTTYPE_BSDI_SWAP (0xB8, "BSDI swap partition (secondarily file system)"),
+ PARTTYPE_DR_DOS_12 (0xC1, "DR-DOS 6.0 LOGIN.EXE-secured 12-bit FAT partition;"),
+ PARTTYPE_DR_DOS_16 (0xC4, "DR-DOS 6.0 LOGIN.EXE-secured 16-bit FAT partition"),
+ PARTTYPE_DR_DOS_HUGE (0xC6, "DR-DOS 6.0 LOGIN.EXE-secured Huge partition"),
+ PARTTYPE_CYRNIX (0xC7, "Cyrnix Boot;"),
+ PARTTYPE_NON_FS (0xDA, "Non FS Data;"),
+ PARTTYPE_CPM_DOS (0xDB, "CP/M, Concurrent CP/M, Concurrent DOS; CTOS (Convergent Technologies OS)"),
+ PARTTYPE_DELL_UTILITY (0xDE, "DELL Utility partition"),
+ PARTTYPE_BOOT_IT (0xDF, "Boot it"),
+ PARTTYPE_SPEEDSTOR_FAT_12 (0xE1, "SpeedStor 12-bit FAT extended partition"),
+ PARTTYPE_DOS_R_O (0xE3, "Readonly Dos Partition"),
+ PARTTYPE_SPEEDSTOR_FAT_16 (0xE4, "SpeedStor 16-bit FAT extended partition"),
+ PARTTYPE_BEOS_FS (0xEB, "BEO_FS"),
+ PARTTYPE_EFI_GPT (0xEE, "EFI GPT"),
+ PARTTYPE_EFI_FAT (0xEF, "BEO_FS"),
+ PARTTYPE_LINUX_PA_RISK (0xF0, "Linux PA Risk"),
+ PARTTYPE_SPEEDSTORE_A (0xF1, "Speedstore ???"),
+ PARTTYPE_DOS3_3_SECENDORY (0xF2, "DOS 3.3+ secondary"),
+ PARTTYPE_SPEEDSTORE_B (0xF4, "Speedstore ???"),
+ PARTTYPE_LINUX_RAID (0xFD, "Linux Raid"),
+ PARTTYPE_LANSTEP (0xFE, "LANstep"),
+ PARTTYPE_XENIX_BAD_BLOCK (0xFF, "Xenix bad block table");
- public static final int PARTTYPE_EMPTY = 0x00; // empty
- public static final int PARTTYPE_DOS_FAT12 = 0x01; // DOS 12-bit FAT
- public static final int PARTTYPE_XENIX_ROOT = 0x02; // XENIX root file system
- public static final int PARTTYPE_XENIX_USR = 0x03; // XENIX /usr file system (obsolete)
- public static final int PARTTYPE_DOS_FAT16_LT32M = 0x04; // DOS 16-bit FAT (up to 32M)
- public static final int PARTTYPE_DOS_EXTENDED = 0x05; // DOS 3.3+ extended partition
- public static final int PARTTYPE_DOS_FAT16_GT32M = 0x06; // DOS 3.31+ Large File System (16-bit FAT, over 32M)
- public static final int PARTTYPE_NTFS = 0x07; // NTFS
- // OS/2 HPFS
- // Advanced Unix
- public static final int PARTTYPE_AIX_BOOTABLE = 0x08; // AIX bootable partition, SplitDrive
- public static final int PARTTYPE_AIX_DATA = 0x09; // AIX data partition;
- // Coherent filesystem;
- public static final int PARTTYPE_OS2_BOOT_MANAGER = 0x0A; // OS/2 Boot Manager
- // OPUS
- // Coherent swap partition
- public static final int PARTTYPE_WIN95_FAT32 = 0x0B; // Win 95 Fat Partition
- public static final int PARTTYPE_WIN95_FAT32_LBA = 0x0C; // Win 95 Fat 32 Partition (LBA)
- public static final int PARTTYPE_WIN95_FAT16_LBA = 0x0E; // Win 95 Fat 16 Partition (LBA)
- public static final int PARTTYPE_WIN95_FAT32_EXTENDED = 0x0F; // WIN95 EXTENDED
- public static final int PARTTYPE_OPUS = 0x10; // OPUS
- public static final int PARTTYPE_OS2_BOOT_HIDDEN_12 = 0x11; // OS/2 Boot Manager hidden 12-bit FAT partition
- public static final int PARTTYPE_COMPAQ_DIAG = 0x12; // Compaq Diagnostics partition
- public static final int PARTTYPE_OS2_BOOT_HIDDEN_16_S32 = 0x14; // (resulted from using Novell DOS 7.0 FDISK to delete Linux Native part)
- // OS/2 Boot Manager hidden sub-32M 16-bit FAT partition
- public static final int PARTTYPE_OS2_BOOT_HIDDEN_16_O32 = 0x16; // OS/2 Boot Manager hidden over-32M 16-bit FAT partition
- public static final int PARTTYPE_OS2_BOOT_HIDDEN_HPFS = 0x17; // OS/2 Boot Manager hidden HPFS partition
- public static final int PARTTYPE_WINDOWS_SWAP = 0x18; // AST special Windows swap file
- public static final int PARTTYPE_WIN95_FAT_16_HIDDEN = 0x1B; // Hidden Win95
- public static final int PARTTYPE_WIN95_FAT_32_HIDDEN = 0x1E; // Hidden Win95
- public static final int PARTTYPE_NEC_MSDOS = 0x24; // NEC MS-DOS 3.x
- public static final int PARTTYPE_PLAN_9 = 0x39; // Plan 9
- public static final int PARTTYPE_POWERQUEST_RECOVERY = 0x3C; // PowerQuest PartitionMagic recovery partition
- public static final int PARTTYPE_VENIX80286 = 0x40; // VENIX 80286
- public static final int PARTTYPE_PPC_BOOT = 0x41; // PPC_BOOT
- public static final int PARTTYPE_SFS = 0x42; // SFS (Secure File System) by Peter Gutmann
- public static final int PARTTYPE_QNX = 0x4d; // QNX
- public static final int PARTTYPE_QNX_SECOND = 0x4e; // QNX second Part
- public static final int PARTTYPE_QNX_THIRD = 0x4f; // QNX third Part
- public static final int PARTTYPE_DISK_MANAGER_RO = 0x50; // Disk Manager, read-only partition
- public static final int PARTTYPE_DISK_MANAGER_RW = 0x51; // Disk Manager, read/write partition
- // Novell???
- public static final int PARTTYPE_CPM = 0x52; // CP/M;
- // Microport System V/386
- public static final int PARTTYPE_ONTRACK_AUX = 0x53; // Ontrack ?;
- public static final int PARTTYPE_ONTRACK = 0x54; // Ontrack ?;
- public static final int PARTTYPE_EZ_DRIVE = 0x55; // EZ_DRIVE
- public static final int PARTTYPE_VFEATURE = 0x56; // GoldenBow VFeature
- public static final int PARTTYPE_PRIAM_EDISK = 0x5c; // Priam Edisk;
- public static final int PARTTYPE_SPEEDSTOR = 0x61; // SpeedStor
- public static final int PARTTYPE_UNIX_SYS_V = 0x63; // Unix SysV/386, 386/ix;
- // ach, MtXinu BSD 4.3 on Mach;
- // GNU HURD
- public static final int PARTTYPE_NOVELL = 0x64; // Novell NetWare
- public static final int PARTTYPE_NOVELL_31 = 0x65; // Novell NetWare (3.11)
- public static final int PARTTYPE_DISK_SECURE = 0x70; // DiskSecure Multi-Boot
- public static final int PARTTYPE_PC_IX = 0x75; // PC/IX
- public static final int PARTTYPE_MINIX = 0x80; // Minix v1.1 - 1.4a
- public static final int PARTTYPE_LINUX = 0x81; // Linux
- // Mitac Advanced Disk Manager
- public static final int PARTTYPE_LINUX_SWAP = 0x82; // Linux Swap partition
- public static final int PARTTYPE_LINUXNATIVE = 0x83; // Linux native file system (ext2fs/xiafs)
- public static final int PARTTYPE_OS2_HIDING_DOS = 0x84; // OS/2-renumbered type 04h partition (related to hiding DOS C: drive);
- public static final int PARTTYPE_LINUX_EXTENDED = 0x85; // Linux extendet partition
- public static final int PARTTYPE_LINUX_LVM = 0x8E; // Linux LVM
- public static final int PARTTYPE_AMOEBA = 0x93; // Amoeba file system
- public static final int PARTTYPE_AMOEBA_BAD_BLOCK = 0x94; // Amoeba bad block table
- public static final int PARTTYPE_BSD = 0x9F; // BSD
- public static final int PARTTYPE_THIK_PAD_HIDDEN = 0xA0; // IBM Thinkpad hidden partition
- public static final int PARTTYPE_FREE_BSD = 0xA5; // FreeBSD
- public static final int PARTTYPE_OPEN_BSD = 0xA6; // OpenBSD
- public static final int PARTTYPE_NEXT_STEP = 0xA7; // NextStep
- public static final int PARTTYPE_NETBSD = 0xA9; // NetBSD
- public static final int PARTTYPE_BSDI = 0xB7; // BSDI file system (secondarily swap)
- public static final int PARTTYPE_BSDI_SWAP = 0xB8; // BSDI swap partition (secondarily file system)
- public static final int PARTTYPE_DR_DOS_12 = 0xC1; // DR-DOS 6.0 LOGIN.EXE-secured 12-bit FAT partition;
- public static final int PARTTYPE_DR_DOS_16 = 0xC4; // DR-DOS 6.0 LOGIN.EXE-secured 16-bit FAT partition
- public static final int PARTTYPE_DR_DOS_HUGE = 0xC6; // DR-DOS 6.0 LOGIN.EXE-secured Huge partition
- public static final int PARTTYPE_CYRNIX = 0xC7; // Cyrnix Boot;
- public static final int PARTTYPE_NON_FS = 0xDA; // Non FS Data;
- public static final int PARTTYPE_CPM_DOS = 0xDB; // CP/M, Concurrent CP/M, Concurrent DOS
- // CTOS (Convergent Technologies OS)
- public static final int PARTTYPE_DELL_UTILITY = 0xDE; // DELL Utility partition
- public static final int PARTTYPE_BOOT_IT = 0xDF; // Boot it
- public static final int PARTTYPE_SPEEDSTOR_FAT_12 = 0xE1; // SpeedStor 12-bit FAT extended partition
- public static final int PARTTYPE_DOS_R_O = 0xE3; // Readonly Dos Partition
- public static final int PARTTYPE_SPEEDSTOR_FAT_16 = 0xE4; // SpeedStor 16-bit FAT extended partition
- public static final int PARTTYPE_BEOS_FS = 0xEB; // BEO_FS
- public static final int PARTTYPE_EFI_GPT = 0xEE; // EFI GPT
- public static final int PARTTYPE_EFI_FAT = 0xEF; // BEO_FS
- public static final int PARTTYPE_LINUX_PA_RISK = 0xF0; // Linux PA Risk
- public static final int PARTTYPE_SPEEDSTORE_A = 0xF1; // Speedstore ???
- public static final int PARTTYPE_DOS3_3_SECENDORY = 0xF2; // DOS 3.3+ secondary
- public static final int PARTTYPE_SPEEDSTORE_B = 0xF4; // Speedstore ???
- public static final int PARTTYPE_LINUX_RAID = 0xFD; // Linux Raid
- public static final int PARTTYPE_LANSTEP = 0xFE; // LANstep
- public static final int PARTTYPE_XENIX_BAD_BLOCK = 0xFF; // Xenix bad block table
+ public static IBMPartitionTypes valueOf(int code) {
+ for(IBMPartitionTypes type : IBMPartitionTypes.values())
+ {
+ if(type.getCode() == code)
+ {
+ return type;
+ }
+ }
+ throw new IllegalArgumentException(code+" isn't a partition code");
+ }
+
+ private final int code;
+ private final String name;
+ private IBMPartitionTypes(int code, String name) {
+ this.code = code;
+ this.name = name;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String toString()
+ {
+ return Integer.toHexString(code) + " - " + name;
+ }
}
Modified: trunk/fs/src/test/org/jnode/test/fs/filesystem/AbstractFSTest.java
===================================================================
--- trunk/fs/src/test/org/jnode/test/fs/filesystem/AbstractFSTest.java 2007-02-11 22:12:18 UTC (rev 3116)
+++ trunk/fs/src/test/org/jnode/test/fs/filesystem/AbstractFSTest.java 2007-02-11 22:19:06 UTC (rev 3117)
@@ -55,7 +55,7 @@
private FileSystem fs;
private FSTestConfig config;
-// private Device device;
+ private Device device;
public AbstractFSTest()
{
@@ -68,19 +68,21 @@
protected AbstractFSTest(String name)
{
super(name);
-// this.fs = null;
-// this.device = null;
}
final protected void setUp(FSTestConfig config) throws NameNotFoundException, FileSystemException, IOException, InstantiationException, IllegalAccessException, Exception
{
+ super.setUp();
+
this.config = config;
- this.fs = config.getFileSystem().mount(config.getDeviceParam().getDevice());
+ this.device = config.getDeviceParam().createDevice();
+ this.fs = config.getFileSystem().mount(this.device);
}
final public void tearDown() throws E...
[truncated message content] |
|
From: <fd...@us...> - 2007-02-11 22:12:21
|
Revision: 3116
http://jnode.svn.sourceforge.net/jnode/?rev=3116&view=rev
Author: fduminy
Date: 2007-02-11 14:12:18 -0800 (Sun, 11 Feb 2007)
Log Message:
-----------
for size computation :
- created SizeUnit enum
- added more units (that can fit in a long value)
Modified Paths:
--------------
trunk/core/src/core/org/jnode/util/NumberUtils.java
Added Paths:
-----------
trunk/core/src/core/org/jnode/util/SizeUnit.java
Modified: trunk/core/src/core/org/jnode/util/NumberUtils.java
===================================================================
--- trunk/core/src/core/org/jnode/util/NumberUtils.java 2007-02-10 21:22:09 UTC (rev 3115)
+++ trunk/core/src/core/org/jnode/util/NumberUtils.java 2007-02-11 22:12:18 UTC (rev 3116)
@@ -25,12 +25,6 @@
* @author epr
*/
public class NumberUtils {
-
- public static final int K = 1024;
- public static final int M = 1024*1024;
- public static final int G = 1024*1024*1024;
- public static final long T = 1024l*1024l*1024l*1024l;
-
/**
* Convert a float to a string with a given maximum number of fraction digits.
* @param value
@@ -219,61 +213,57 @@
* @return the text for of the size
*/
public static String size(long v) {
- // Is < 1Kb?
- if (v < K) {
- return String.valueOf(v) + "B";
- }
- // Is < 1Mb?
- v = v >>> 10;
- if (v < K) {
- return String.valueOf(v) + "KB";
- }
- // Is < 1Gb?
- v = v >>> 10;
- if (v < K) {
- return String.valueOf(v) + "MB";
- }
- // Is < 1Tb?
- v = v >>> 10;
- if (v < K) {
- return String.valueOf(v) + "GB";
- }
- // Large...
- v = v >>> 10;
- return String.valueOf(v) + "TB";
+ SizeUnit prevUnit = SizeUnit.MIN;
+ for(SizeUnit unit : SizeUnit.values())
+ {
+ if (v < unit.getMultiplier())
+ {
+ return String.valueOf(v) + prevUnit.getUnit();
+ }
+ v = v >>> 10;
+ prevUnit = unit;
+ }
+ return String.valueOf(v) + prevUnit.getUnit();
}
/**
*
- * @param size a number eventually followed by a multiplier (K: Kilobytes, M: Megabytes, G:Gigabytes)
+ * @param size a number eventually followed by a multiplier (K: Kilobytes, M: Megabytes, G:Gigabytes, ...)
* @return the numeric value of the size
*/
public static long getSize(String size) {
if((size == null) || size.trim().equals(""))
return 0;
-
- long multiplier = 1;
- if(size.endsWith("B"))
- size = size.substring(0, size.length() - 1);
-
- if(size.endsWith("T")) {
- multiplier = T;
- size = size.substring(0, size.length() - 1);
- } else if(size.endsWith("G")) {
- multiplier = G;
- size = size.substring(0, size.length() - 1);
- } else if(size.endsWith("M")) {
- multiplier = M;
- size = size.substring(0, size.length() - 1);
- } else if(size.endsWith("K")) {
- multiplier = K;
- size = size.substring(0, size.length() - 1);
+ size = size.trim();
+ long multiplier = SizeUnit.MIN.getMultiplier();
+ SizeUnit sizeUnit = getSizeUnit(size);
+ if(sizeUnit != null)
+ {
+ multiplier = sizeUnit.getMultiplier();
+ size = size.substring(0, size.length() - sizeUnit.getUnit().length());
}
return Long.parseLong(size) * multiplier;
}
-
+
+ public static SizeUnit getSizeUnit(String size) {
+ if((size == null) || size.trim().equals(""))
+ return null;
+
+ size = size.trim();
+ for(SizeUnit unit : SizeUnit.values())
+ {
+ String unitStr = unit.getUnit();
+ if(size.endsWith(unitStr))
+ {
+ return unit;
+ }
+ }
+
+ return null;
+ }
+
/**
* This method avoids the use on Integer.toHexString, since this class may be used
* during the boot-phase when the Integer class in not yet initialized.
Added: trunk/core/src/core/org/jnode/util/SizeUnit.java
===================================================================
--- trunk/core/src/core/org/jnode/util/SizeUnit.java (rev 0)
+++ trunk/core/src/core/org/jnode/util/SizeUnit.java 2007-02-11 22:12:18 UTC (rev 3116)
@@ -0,0 +1,39 @@
+package org.jnode.util;
+
+import java.math.BigInteger;
+
+public enum SizeUnit {
+ B(1l, "B"),
+ K(1024l, "K"),
+ M(1024l*1024l, "M"),
+ G(1024l*1024l*1024l, "G"),
+ T(1024l*1024l*1024l*1024l, "T"),
+ P(1024l*1024l*1024l*1024l*1024l, "P"),
+ E(1024l*1024l*1024l*1024l*1024l*1024l, "E");
+ //these units have too big multipliers to fit in a long
+ // (aka they are greater than 2^64) :
+ //Z(1024l*1024l*1024l*1024l*1024l*1024l*1024l, "Z"),
+ //Y(1024l*1024l*1024l*1024l*1024l*1024l*1024l*1024l, "Y");
+
+ public static final SizeUnit MIN = B;
+ public static final SizeUnit MAX = E;
+
+ final private long multiplier;
+ final private String unit;
+
+ private SizeUnit(long multiplier, String unit)
+ {
+ this.multiplier = multiplier;
+ this.unit = unit;
+ }
+
+ public long getMultiplier() {
+ return multiplier;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-10 21:22:10
|
Revision: 3115
http://jnode.svn.sourceforge.net/jnode/?rev=3115&view=rev
Author: lsantha
Date: 2007-02-10 13:22:09 -0800 (Sat, 10 Feb 2007)
Log Message:
-----------
Updated to beanshell 2.0b4.
Modified Paths:
--------------
trunk/all/build.xml
Modified: trunk/all/build.xml
===================================================================
--- trunk/all/build.xml 2007-02-10 19:29:29 UTC (rev 3114)
+++ trunk/all/build.xml 2007-02-10 21:22:09 UTC (rev 3115)
@@ -63,7 +63,7 @@
<property name="gnu-crypto.jar" value="${root.dir}/core/lib/gnu-crypto.jar"/>
<property name="javax-crypto.jar" value="${root.dir}/core/lib/javax-crypto.jar"/>
<!-- property name="javax-security.jar" value="${root.dir}/core/lib/javax-security.jar" / -->
- <property name="beanshell.jar" value="${root.dir}/shell/lib/bsh-2.0b1.jar"/>
+ <property name="beanshell.jar" value="${root.dir}/shell/lib/bsh-2.0b4.jar"/>
<!-- libraries needed to check plugin dependencies -->
<property name="bcel-5.1.jar" value="${root.dir}/builder/lib/bcel-5.1.jar" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-10 19:29:33
|
Revision: 3114
http://jnode.svn.sourceforge.net/jnode/?rev=3114&view=rev
Author: lsantha
Date: 2007-02-10 11:29:29 -0800 (Sat, 10 Feb 2007)
Log Message:
-----------
Removing the old beanshell.
Removed Paths:
-------------
trunk/shell/lib/bsh-2.0b1.jar
Deleted: trunk/shell/lib/bsh-2.0b1.jar
===================================================================
(Binary files differ)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-10 19:23:33
|
Revision: 3113
http://jnode.svn.sourceforge.net/jnode/?rev=3113&view=rev
Author: lsantha
Date: 2007-02-10 11:23:31 -0800 (Sat, 10 Feb 2007)
Log Message:
-----------
Fixed bsh command and updated beanshell to 2.0b4.
Modified Paths:
--------------
trunk/shell/descriptors/org.jnode.shell.command.bsh.xml
Added Paths:
-----------
trunk/shell/lib/bsh-2.0b4.jar
trunk/shell/src/shell/org/jnode/shell/command/bsh/BshCommand.java
Removed Paths:
-------------
trunk/shell/src/shell/org/jnode/shell/command/bsh/BeanshellCommand.java
Modified: trunk/shell/descriptors/org.jnode.shell.command.bsh.xml
===================================================================
--- trunk/shell/descriptors/org.jnode.shell.command.bsh.xml 2007-02-04 20:28:05 UTC (rev 3112)
+++ trunk/shell/descriptors/org.jnode.shell.command.bsh.xml 2007-02-10 19:23:31 UTC (rev 3113)
@@ -19,7 +19,7 @@
</runtime>
<extension point="org.jnode.shell.aliases">
- <alias name="bsh" class="org.jnode.shell.command.bsh.BeanshellCommand"/>
+ <alias name="bsh" class="org.jnode.shell.command.bsh.BshCommand"/>
</extension>
<extension point="org.jnode.security.permissions">
Added: trunk/shell/lib/bsh-2.0b4.jar
===================================================================
(Binary files differ)
Property changes on: trunk/shell/lib/bsh-2.0b4.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Deleted: trunk/shell/src/shell/org/jnode/shell/command/bsh/BeanshellCommand.java
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/command/bsh/BeanshellCommand.java 2007-02-04 20:28:05 UTC (rev 3112)
+++ trunk/shell/src/shell/org/jnode/shell/command/bsh/BeanshellCommand.java 2007-02-10 19:23:31 UTC (rev 3113)
@@ -1,235 +0,0 @@
-/*
- * $Id$
- *
- * JNode.org
- * Copyright (C) 2003-2006 JNode.org
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-package org.jnode.shell.command.bsh;
-
-import gnu.java.io.NullOutputStream;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.PrintStream;
-import java.io.Reader;
-import java.io.StringReader;
-
-import bsh.ConsoleInterface;
-import bsh.EvalError;
-import bsh.Interpreter;
-
-/**
- * User: Sam Reid Date: Jan 1, 2004 Time: 10:40:34 AM Copyright (c) Jan 1, 2004
- * by Sam Reid
- */
-public class BeanshellCommand {
-
- private static Interpreter interpreter;
- /*static {
- //ConsoleInterface ci=new BshConsole();
- }*/
-
- static class BshPrintStream extends PrintStream {
-
- public BshPrintStream() {
- super(new NullOutputStream());
- }
-
- public void print(boolean b) {
- // System.out.print
- }
-
- public void print(char c) {
- super.print(c);
- }
-
- public void print(int i) {
- super.print(i);
- }
-
- public void print(long l) {
- super.print(l);
- }
-
- public void print(float f) {
- super.print(f);
- }
-
- public void print(double d) {
- super.print(d);
- }
-
- public void print(char[] s) {
- super.print(s);
- }
-
- public void print(String s) {
- super.print(s);
- }
-
- public void print(Object obj) {
- super.print(obj);
- }
-
- public void println() {
- super.println();
- }
-
- public void println(boolean b) {
- super.println(b);
- }
-
- public void println(char c) {
- super.println(c);
- }
-
- public void println(int i) {
- super.println(i);
- }
-
- public void println(long l) {
- super.println(l);
- }
-
- public void println(float f) {
- super.println(f);
- }
-
- public void println(double d) {
- super.println(d);
- }
-
- public void println(char[] s) {
- super.println(s);
- }
-
- public void println(String s) {
- super.println(s);
- }
-
- public void println(Object obj) {
- super.println(obj);
- }
- }
-
- static class BshConsole implements ConsoleInterface {
-
- StringReader in = new StringReader("234");
-
- public Reader getIn() {
- return in;//dummy
- }
-
- public PrintStream getOut() {
- return null;
- }
-
- public PrintStream getErr() {
- return null;
- }
-
- public void println(Object o) {
- }
-
- public void print(Object o) {
- }
-
- public void error(Object o) {
- }
-
- }
-
- /**
- * Normal usage will be BeanshellCommand filename.bsh But you could also
- * inline java code like this: BeanshellCommand -code "new
- * JFrame().setVisible(true)"; <p/>BeanshellCommand should start an
- * interactive session with beanshell. BeanshellCommand file.bsh should
- * interpret and run the script. BeanshellCommand -code "code" should
- * interpret and run the code.
- */
- public static void showHelp() {
- System.err
- .println("Usage: \nbsh: interactive beanshell.\n"
- + "bsh -help: this usage menu\n"
- + "bsh -code CODE: evaluate the following shell code.\n"
- + "bsh FILE: run the beanshell interpreter on the source FILE.");
- }
-
- private static void evaluateFile(String arg) {
- try {
- System.err.println("Evaluating beanshell source=" + arg);
- new Interpreter().source(arg);
- } catch (IOException e) {
- e.printStackTrace(); //To change body of catch statement use
- // Options | File Templates.
- } catch (EvalError evalError) {
- evalError.printStackTrace(); //To change body of catch statement
- // use Options | File Templates.
- }
- }
-
- public static void main(String[] args) {
- // System.out.println("Started beanshell command.");
- if (args.length == 0) {
- //run interactive shell
- // System.err.println("Interactive shell not yet written.");
- runInteractiveShell();
- return;
- } else if (args.length == 1 && args[ 0].toLowerCase().equals("-help")) {
- System.err
- .println("Usage: bsh: interactive beanshell. <not yet working>\n"
- + "bsh FILE: run the beanshell interpreter on the source FILE. <not yet written>\n"
- + "bsh -help: this usage menu\n"
- + "bsh -code CODE: evaluate the following shell code.");
- } else if (args.length == 1) {
- evaluateFile(args[ 0]);
- } else if (args.length == 2 && args[ 0].toLowerCase().equals("-code")) {
- String sourcecode = args[ 1];
- evaluateSourceString(sourcecode);
- } else if (args.length == 1 && args[ 0].toLowerCase().equals("-charva")) {
- // runCharvaShell();
- } else {
- showHelp();
- }
- }
-
- private static void runInteractiveShell() {
- System.err.println("Starting Interactive beanshell.");
- Reader reader = new InputStreamReader(System.in);
- Reader r2 = new BufferedReader(reader);
- PrintStream out = new PrintStream(System.out);
- PrintStream err = new PrintStream(System.err);
-
- Interpreter interpreter = new Interpreter(r2, out, err, true);
- interpreter.run();
- System.err.println("Finished Interactive beanshell.");
- }
-
- private static void evaluateSourceString(String sourcecode) {
- System.out.println("Evaluating source string=" + sourcecode);
- try {
- Object out = interpreter.eval(sourcecode);
- System.out.println(out);
- } catch (EvalError evalError) {
- evalError.printStackTrace(); //To change body of catch statement
- // use Options | File Templates.
- }
- }
-
-}
Copied: trunk/shell/src/shell/org/jnode/shell/command/bsh/BshCommand.java (from rev 3112, trunk/shell/src/shell/org/jnode/shell/command/bsh/BeanshellCommand.java)
===================================================================
--- trunk/shell/src/shell/org/jnode/shell/command/bsh/BshCommand.java (rev 0)
+++ trunk/shell/src/shell/org/jnode/shell/command/bsh/BshCommand.java 2007-02-10 19:23:31 UTC (rev 3113)
@@ -0,0 +1,116 @@
+/*
+ * $Id$
+ *
+ * JNode.org
+ * Copyright (C) 2003-2006 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package org.jnode.shell.command.bsh;
+
+import java.io.*;
+
+import bsh.Interpreter;
+import org.jnode.shell.help.*;
+import org.jnode.shell.help.argument.StringArgument;
+import org.jnode.shell.help.argument.FileArgument;
+import org.jnode.shell.help.argument.OptionArgument;
+import org.jnode.shell.CommandLine;
+
+/**
+ * @author Levente S\u00e1ntha
+ */
+public class BshCommand {
+
+ private static final StringArgument ARG_CODE = new StringArgument("code", "a BeanShell code snippet to execute");
+ static final OptionArgument ARG_C = new OptionArgument("-c", "execute code",
+ new OptionArgument.Option("-c", "execute code"));
+ private static final Parameter PARAM_C = new Parameter(ARG_C, Parameter.MANDATORY);
+ private static final Parameter PARAM_CODE = new Parameter(ARG_CODE, Parameter.MANDATORY);
+ private static final FileArgument ARG_FILE = new FileArgument("file", "a BeanShell script file to execute");
+ static final OptionArgument ARG_F = new OptionArgument("-f", "execute file",
+ new OptionArgument.Option("-f", "execute file"));
+ private static final Parameter PARAM_F = new Parameter(ARG_F, Parameter.MANDATORY);
+ private static final Parameter PARAM_FILE = new Parameter(ARG_FILE, Parameter.MANDATORY);
+ static final OptionArgument ARG_I = new OptionArgument("-i", "go interactive",
+ new OptionArgument.Option("-i", "go interactive"));
+ private static final Parameter PARAM_INTERACTIVE = new Parameter(ARG_I, Parameter.MANDATORY);
+ public static Help.Info HELP_INFO = new Help.Info(
+ "bsh",
+ new Syntax("start the interactive BeanShell interpreter"),
+ new Syntax("invoke the BeanShell interpreter", PARAM_C, PARAM_CODE),
+ new Syntax("invoke the BeanShell interpreter", PARAM_F, PARAM_FILE),
+ new Syntax("invoke the BeanShell interpreter", PARAM_C, PARAM_CODE, PARAM_F, PARAM_FILE),
+ new Syntax("invoke the BeanShell interpreter", PARAM_INTERACTIVE, PARAM_C, PARAM_CODE),
+ new Syntax("invoke the BeanShell interpreter", PARAM_INTERACTIVE, PARAM_F, PARAM_FILE),
+ new Syntax("invoke the BeanShell interpreter", PARAM_INTERACTIVE, PARAM_C, PARAM_CODE, PARAM_F, PARAM_FILE)
+ );
+
+ public static void main(String[] args) throws Exception {
+ new BshCommand().execute(new CommandLine(args), System.in, System.out, System.err);
+ }
+
+ public void execute(CommandLine commandLine, InputStream in, PrintStream out, PrintStream err) throws Exception {
+ ParsedArguments parsedArguments = HELP_INFO.parse(commandLine.toStringArray());
+ Interpreter bsh = null;
+ Object ret;
+ boolean interactive = false;
+
+ if(PARAM_INTERACTIVE.isSet(parsedArguments)){
+ bsh = createInterpreter(in, out, err, true);
+ interactive = true;
+ }
+
+
+ if (PARAM_C.isSet(parsedArguments)){
+ if(bsh == null)
+ bsh = createInterpreter(in, out, err, false);
+
+ String code = ARG_CODE.getValue(parsedArguments);
+ ret = bsh.eval(code);
+
+ if(ret != null)
+ out.println(ret);
+ }
+
+
+ if(PARAM_F.isSet(parsedArguments)){
+ if(bsh == null)
+ bsh = createInterpreter(in, out, err, false);
+
+ String file = ARG_FILE.getValue(parsedArguments);
+ ret = bsh.source(file);
+
+ if(ret != null)
+ out.println(ret);
+ }
+
+ if(bsh == null){
+ bsh = createInterpreter(in, out, err, true);
+ interactive = true;
+ }
+
+ if(interactive)
+ bsh.run();
+ }
+
+ private static Interpreter createInterpreter(InputStream in, OutputStream out, OutputStream err, boolean interactive){
+ return new Interpreter(
+ new BufferedReader(new InputStreamReader(in)),
+ new PrintStream(out),
+ new PrintStream(err), interactive);
+ }
+}
Property changes on: trunk/shell/src/shell/org/jnode/shell/command/bsh/BshCommand.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-04 20:28:15
|
Revision: 3112
http://jnode.svn.sourceforge.net/jnode/?rev=3112&view=rev
Author: lsantha
Date: 2007-02-04 12:28:05 -0800 (Sun, 04 Feb 2007)
Log Message:
-----------
Fixed overwritten text. (issue http://www.jnode.org/node/926)
Modified Paths:
--------------
trunk/core/src/driver/org/jnode/driver/console/textscreen/TextScreenConsole.java
Modified: trunk/core/src/driver/org/jnode/driver/console/textscreen/TextScreenConsole.java
===================================================================
--- trunk/core/src/driver/org/jnode/driver/console/textscreen/TextScreenConsole.java 2007-02-04 16:03:05 UTC (rev 3111)
+++ trunk/core/src/driver/org/jnode/driver/console/textscreen/TextScreenConsole.java 2007-02-04 20:28:05 UTC (rev 3112)
@@ -124,6 +124,10 @@
if(ln > 0){
screen.set(screen.getOffset(curX, curY), v, offset + mark, ln, color);
curX += ln;
+ if (curX >= scrWidth) {
+ curY++;
+ curX = curX - scrWidth;
+ }
}
mark = i + 1;
putChar(c, color);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-04 16:03:08
|
Revision: 3111
http://jnode.svn.sourceforge.net/jnode/?rev=3111&view=rev
Author: lsantha
Date: 2007-02-04 08:03:05 -0800 (Sun, 04 Feb 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTabbedPaneUI.java
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTabbedPaneUI.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTabbedPaneUI.java 2007-02-04 16:01:44 UTC (rev 3110)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTabbedPaneUI.java 2007-02-04 16:03:05 UTC (rev 3111)
@@ -902,6 +902,7 @@
default:
tabAreaHeight = calculateTabAreaHeight(tabPlacement, runCount,
maxTabHeight);
+
compX = insets.left + contentBorderInsets.left;
compY = tabAreaHeight + insets.top + contentBorderInsets.top;
}
@@ -956,81 +957,50 @@
protected void normalizeTabRuns(int tabPlacement, int tabCount, int start,
int max)
{
- if (tabPlacement == SwingUtilities.TOP
- || tabPlacement == SwingUtilities.BOTTOM)
+ boolean horizontal = tabPlacement == TOP || tabPlacement == BOTTOM;
+ int currentRun = runCount - 1;
+ double weight = 1.25;
+ for (boolean adjust = true; adjust == true;)
{
- // We should only do this for runCount - 1, cause we can
- // only shift that many times between runs.
- for (int i = 1; i < runCount; i++)
- {
- Rectangle currRun = rects[lastTabInRun(tabCount, i)];
- Rectangle nextRun = rects[lastTabInRun(tabCount,
- getNextTabRun(i))];
- int spaceInCurr = currRun.x + currRun.width;
- int spaceInNext = nextRun.x + nextRun.width;
-
- int diffNow = spaceInCurr - spaceInNext;
- int diffLater = (spaceInCurr - currRun.width)
- - (spaceInNext + currRun.width);
-
- while (Math.abs(diffLater) < Math.abs(diffNow)
- && spaceInNext + currRun.width < max)
+ int last = lastTabInRun(tabCount, currentRun);
+ int prevLast = lastTabInRun(tabCount, currentRun - 1);
+ int end;
+ int prevLength;
+ if (horizontal)
{
- tabRuns[i]--;
- spaceInNext += currRun.width;
- spaceInCurr -= currRun.width;
- currRun = rects[lastTabInRun(tabCount, i)];
- diffNow = spaceInCurr - spaceInNext;
- diffLater = (spaceInCurr - currRun.width)
- - (spaceInNext + currRun.width);
- }
-
- // Fixes the bounds of all tabs in the current
- // run.
- int first = tabRuns[i];
- int last = lastTabInRun(tabCount, i);
- int currX = start;
- for (int j = first; j <= last; j++)
- {
- rects[j].x = currX;
- currX += rects[j].width;
- }
- }
+ end = rects[last].x + rects[last].width;
+ prevLength = (int) (maxTabWidth * weight);
}
else
{
- for (int i = 1; i < runCount; i++)
+ end = rects[last].y + rects[last].height;
+ prevLength = (int) (maxTabWidth * weight * 2);
+ }
+ if (max - end > prevLength)
{
- Rectangle currRun = rects[lastTabInRun(tabCount, i)];
- Rectangle nextRun = rects[lastTabInRun(tabCount,
- getNextTabRun(i))];
- int spaceInCurr = currRun.y + currRun.height;
- int spaceInNext = nextRun.y + nextRun.height;
-
- int diffNow = spaceInCurr - spaceInNext;
- int diffLater = (spaceInCurr - currRun.height)
- - (spaceInNext + currRun.height);
- while (Math.abs(diffLater) < Math.abs(diffNow)
- && spaceInNext + currRun.height < max)
+ tabRuns[currentRun] = prevLast;
+ if (horizontal)
+ rects[prevLast].x = start;
+ else
+ rects[prevLast].y = start;
+ for (int i = prevLast + 1; i <= last; i++)
{
- tabRuns[i]--;
- spaceInNext += currRun.height;
- spaceInCurr -= currRun.height;
- currRun = rects[lastTabInRun(tabCount, i)];
- diffNow = spaceInCurr - spaceInNext;
- diffLater = (spaceInCurr - currRun.height)
- - (spaceInNext + currRun.height);
+ if (horizontal)
+ rects[i].x = rects[i - 1].x + rects[i - 1].width;
+ else
+ rects[i].y = rects[i - 1].y + rects[i - 1].height;
}
-
- // Fixes the bounds of tabs in the current run.
- int first = tabRuns[i];
- int last = lastTabInRun(tabCount, i);
- int currY = start;
- for (int j = first; j <= last; j++)
- {
- rects[j].y = currY;
- currY += rects[j].height;
}
+ else if (currentRun == runCount - 1)
+ adjust = false;
+ if (currentRun - 1 > 0)
+ currentRun -= 1;
+ else
+ {
+ // Check again, but with higher ratio to avoid
+ // clogging up the last run.
+ currentRun = runCount - 1;
+ weight += 0.25;
}
}
}
@@ -1394,7 +1364,7 @@
calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom;
int height = 0;
- int runHeight = tabAreaInsets.top + insets.top;;
+ int runHeight = tabAreaInsets.top + insets.top;
int fontHeight = fm.getHeight();
int left = insets.left + tabAreaInsets.left;
for (int i = 0; i < tabCount; i++)
@@ -3528,7 +3498,8 @@
{
Insets insets = getTabAreaInsets(tabPlacement);
int tabAreaHeight = horizRunCount * maxTabHeight
- - (horizRunCount - 1) * tabRunOverlay;
+ - (horizRunCount - 1)
+ * getTabRunOverlay(tabPlacement);
tabAreaHeight += insets.top + insets.bottom;
@@ -3550,7 +3521,8 @@
{
Insets insets = getTabAreaInsets(tabPlacement);
int tabAreaWidth = vertRunCount * maxTabWidth
- - (vertRunCount - 1) * tabRunOverlay;
+ - (vertRunCount - 1)
+ * getTabRunOverlay(tabPlacement);
tabAreaWidth += insets.left + insets.right;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-04 16:01:50
|
Revision: 3110
http://jnode.svn.sourceforge.net/jnode/?rev=3110&view=rev
Author: lsantha
Date: 2007-02-04 08:01:44 -0800 (Sun, 04 Feb 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicToolBarUI.java
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicToolBarUI.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicToolBarUI.java 2007-02-04 16:00:42 UTC (rev 3109)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicToolBarUI.java 2007-02-04 16:01:44 UTC (rev 3110)
@@ -898,6 +898,7 @@
b.setRolloverEnabled(false);
// Save old border in hashtable.
+ if (b.getBorder() != null)
borders.put(b, b.getBorder());
b.setBorder(nonRolloverBorder);
@@ -932,6 +933,7 @@
b.setRolloverEnabled(false);
// Save old border in hashtable.
+ if (b.getBorder() != null)
borders.put(b, b.getBorder());
b.setBorder(rolloverBorder);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-04 16:00:52
|
Revision: 3109
http://jnode.svn.sourceforge.net/jnode/?rev=3109&view=rev
Author: lsantha
Date: 2007-02-04 08:00:42 -0800 (Sun, 04 Feb 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTableUI.java
trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTreeUI.java
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTableUI.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTableUI.java 2007-02-04 12:10:47 UTC (rev 3108)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTableUI.java 2007-02-04 16:00:42 UTC (rev 3109)
@@ -443,11 +443,14 @@
public Dimension getPreferredSize(JComponent comp)
{
int prefTotalColumnWidth = 0;
- for (int i = 0; i < table.getColumnCount(); i++)
+ TableColumnModel tcm = table.getColumnModel();
+
+ for (int i = 0; i < tcm.getColumnCount(); i++)
{
- TableColumn col = table.getColumnModel().getColumn(i);
+ TableColumn col = tcm.getColumn(i);
prefTotalColumnWidth += col.getPreferredWidth();
}
+
return new Dimension(prefTotalColumnWidth, getHeight());
}
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTreeUI.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTreeUI.java 2007-02-04 12:10:47 UTC (rev 3108)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/basic/BasicTreeUI.java 2007-02-04 16:00:42 UTC (rev 3109)
@@ -195,7 +195,7 @@
protected AbstractLayoutCache treeState;
/** Used for minimizing the drawing of vertical lines. */
- protected Hashtable drawingCache;
+ protected Hashtable<TreePath, Boolean> drawingCache;
/**
* True if doing optimizations for a largeModel. Subclasses that don't support
@@ -1587,12 +1587,15 @@
for (int i = startIndex; i <= endIndex; i++, k++)
{
path[k] = treeState.getPathForRow(i);
+ if (path[k] != null)
+ {
isLeaf[k] = treeModel.isLeaf(path[k].getLastPathComponent());
isExpanded[k] = tree.isExpanded(path[k]);
bounds[k] = getPathBounds(tree, path[k]);
- paintHorizontalPartOfLeg(g, clip, insets, bounds[k], path[k], i,
- isExpanded[k], false, isLeaf[k]);
+ paintHorizontalPartOfLeg(g, clip, insets, bounds[k], path[k],
+ i, isExpanded[k], false, isLeaf[k]);
+ }
if (isLastChild(path[k]))
paintVerticalPartOfLeg(g, clip, insets, path[k]);
}
@@ -1600,6 +1603,7 @@
k = 0;
for (int i = startIndex; i <= endIndex; i++, k++)
{
+ if (path[k] != null)
paintRow(g, clip, insets, bounds[k], path[k], i, isExpanded[k],
false, isLeaf[k]);
}
@@ -1611,7 +1615,9 @@
*/
private boolean isLastChild(TreePath path)
{
- if (path instanceof GnuPath)
+ if (path == null)
+ return false;
+ else if (path instanceof GnuPath)
{
// Except the seldom case when the layout cache is changed, this
// optimized code will be executed.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-04 12:10:50
|
Revision: 3108
http://jnode.svn.sourceforge.net/jnode/?rev=3108&view=rev
Author: lsantha
Date: 2007-02-04 04:10:47 -0800 (Sun, 04 Feb 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/javax/javax/swing/tree/AbstractLayoutCache.java
trunk/core/src/classpath/javax/javax/swing/tree/DefaultMutableTreeNode.java
trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeCellRenderer.java
trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeModel.java
trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeSelectionModel.java
trunk/core/src/classpath/javax/javax/swing/tree/FixedHeightLayoutCache.java
Modified: trunk/core/src/classpath/javax/javax/swing/tree/AbstractLayoutCache.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/tree/AbstractLayoutCache.java 2007-02-04 10:20:16 UTC (rev 3107)
+++ trunk/core/src/classpath/javax/javax/swing/tree/AbstractLayoutCache.java 2007-02-04 12:10:47 UTC (rev 3108)
@@ -149,9 +149,11 @@
protected Rectangle getNodeDimensions(Object value, int row, int depth,
boolean expanded, Rectangle bounds)
{
- if (nodeDimensions == null)
- throw new InternalError("The NodeDimensions are not set");
- return nodeDimensions.getNodeDimensions(value, row, depth, expanded, bounds);
+ Rectangle d = null;
+ if (nodeDimensions != null)
+ d = nodeDimensions.getNodeDimensions(value, row, depth, expanded,
+ bounds);
+ return d;
}
/**
@@ -224,7 +226,12 @@
*/
public void setSelectionModel(TreeSelectionModel model)
{
+ if (treeSelectionModel != null)
+ treeSelectionModel.setRowMapper(null);
treeSelectionModel = model;
+ if (treeSelectionModel != null)
+ treeSelectionModel.setRowMapper(this);
+
}
/**
@@ -337,7 +344,7 @@
*
* @return Enumeration
*/
- public abstract Enumeration getVisiblePathsFrom(TreePath path);
+ public abstract Enumeration<TreePath> getVisiblePathsFrom(TreePath path);
/**
* getVisibleChildCount
@@ -425,9 +432,13 @@
*/
public int[] getRowsForPaths(TreePath[] paths)
{
- int[] rows = new int[paths.length];
+ int[] rows = null;
+ if (paths != null)
+ {
+ rows = new int[paths.length];
for (int i = 0; i < rows.length; i++)
rows[i] = getRowForPath(paths[i]);
+ }
return rows;
}
@@ -440,6 +451,6 @@
*/
protected boolean isFixedRowHeight()
{
- return false;
+ return rowHeight > 0;
}
}
Modified: trunk/core/src/classpath/javax/javax/swing/tree/DefaultMutableTreeNode.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/tree/DefaultMutableTreeNode.java 2007-02-04 10:20:16 UTC (rev 3107)
+++ trunk/core/src/classpath/javax/javax/swing/tree/DefaultMutableTreeNode.java 2007-02-04 12:10:47 UTC (rev 3108)
@@ -67,7 +67,7 @@
* An empty enumeration, returned by {@link #children()} if a node has no
* children.
*/
- public static final Enumeration EMPTY_ENUMERATION =
+ public static final Enumeration<TreeNode> EMPTY_ENUMERATION =
EmptyEnumeration.getInstance();
/**
@@ -78,7 +78,7 @@
/**
* The child nodes for this node (may be empty).
*/
- protected Vector children = new Vector();
+ protected Vector<MutableTreeNode> children = new Vector<MutableTreeNode>();
/**
* userObject
@@ -480,7 +480,7 @@
public TreeNode getSharedAncestor(DefaultMutableTreeNode node)
{
TreeNode current = this;
- ArrayList list = new ArrayList();
+ ArrayList<TreeNode> list = new ArrayList<TreeNode>();
while (current != null)
{
@@ -527,7 +527,7 @@
|| children.size() == 0)
return 0;
- Stack stack = new Stack();
+ Stack<Integer> stack = new Stack<Integer>();
stack.push(new Integer(0));
TreeNode node = getChildAt(0);
int depth = 0;
@@ -765,7 +765,7 @@
throw new IllegalArgumentException();
TreeNode parent = this;
- Vector nodes = new Vector();
+ Vector<TreeNode> nodes = new Vector<TreeNode>();
nodes.add(this);
while (parent != node && parent != null)
@@ -1148,7 +1148,7 @@
static class PostorderEnumeration implements Enumeration
{
- Stack nodes = new Stack();
+ Stack<TreeNode> nodes = new Stack<TreeNode>();
Stack childrenEnums = new Stack();
PostorderEnumeration(TreeNode node)
Modified: trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeCellRenderer.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeCellRenderer.java 2007-02-04 10:20:16 UTC (rev 3107)
+++ trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeCellRenderer.java 2007-02-04 12:10:47 UTC (rev 3108)
@@ -77,7 +77,7 @@
protected boolean hasFocus;
/**
- * drawsFocusBorderAroundIcon // FIXME: is this used?
+ * Indicates if the focus border is also drawn around the icon.
*/
private boolean drawsFocusBorderAroundIcon;
@@ -152,6 +152,8 @@
setBackgroundNonSelectionColor(UIManager.getColor("Tree.textBackground"));
setBackgroundSelectionColor(UIManager.getColor("Tree.selectionBackground"));
setBorderSelectionColor(UIManager.getColor("Tree.selectionBorderColor"));
+ Object val = UIManager.get("Tree.drawsFocusBorderAroundIcon");
+ drawsFocusBorderAroundIcon = val != null && ((Boolean) val).booleanValue();
}
/**
@@ -499,45 +501,63 @@
*/
public void paint(Graphics g)
{
- // paint background
- Rectangle vr = new Rectangle();
- Rectangle ir = new Rectangle();
- Rectangle tr = new Rectangle();
+ // Determine background color.
+ Color bgColor;
+ if (selected)
+ bgColor = getBackgroundSelectionColor();
+ else
+ {
+ bgColor = getBackgroundNonSelectionColor();
+ if (bgColor == null)
+ bgColor = getBackground();
+ }
+ // Paint background.
+ int xOffset = -1;
+ if (bgColor != null)
+ {
+ Icon i = getIcon();
+ xOffset = getXOffset();
+ g.setColor(bgColor);
+ g.fillRect(xOffset, 0, getWidth() - xOffset, getHeight());
+ }
- Insets insets = new Insets(0, 0, 0, 0);
- Border border = UIManager.getBorder("Tree.selectionBorder");
- if (border != null)
- insets = border.getBorderInsets(this);
-
- FontMetrics fm = getToolkit().getFontMetrics(getFont());
- SwingUtilities.layoutCompoundLabel((JLabel) this, fm, getText(),
- getIcon(), getVerticalAlignment(),
- getHorizontalAlignment(),
- getVerticalTextPosition(),
- getHorizontalTextPosition(), vr, ir, tr,
- getIconTextGap());
-
- // Reusing one rectangle.
- Rectangle bounds = getBounds(ir);
-
- bounds.x = tr.x - insets.left;
- bounds.width = tr.width + insets.left + insets.right;
-
- g.setColor(super.getBackground());
- g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
-
+ if (hasFocus)
+ {
+ if (drawsFocusBorderAroundIcon)
+ xOffset = 0;
+ else if (xOffset == -1)
+ xOffset = getXOffset();
+ paintFocus(g, xOffset, 0, getWidth() - xOffset, getHeight());
+ }
super.paint(g);
+ }
- // Paint the border of the focused element only (lead selection)
- if (hasFocus)
+ /**
+ * Paints the focus indicator.
+ */
+ private void paintFocus(Graphics g, int x, int y, int w, int h)
{
- Color b = getBorderSelectionColor();
- if (b != null)
+ Color col = getBorderSelectionColor();
+ if (col != null)
{
- g.setColor(b);
- g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height - 1);
+ g.setColor(col);
+ g.drawRect(x, y, w - 1, h - 1);
}
}
+
+ /**
+ * Determines the X offset of the label that is caused by
+ * the icon.
+ *
+ * @return the X offset of the label
+ */
+ private int getXOffset()
+ {
+ Icon i = getIcon();
+ int offs = 0;
+ if (i != null && getText() != null)
+ offs = i.getIconWidth() + Math.max(0, getIconTextGap() - 1);
+ return offs;
}
/**
Modified: trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeModel.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeModel.java 2007-02-04 10:20:16 UTC (rev 3107)
+++ trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeModel.java 2007-02-04 12:10:47 UTC (rev 3108)
@@ -210,17 +210,32 @@
}
/**
- * isLeaf
+ * Returns if the specified node is a leaf or not. When
+ * {@link #asksAllowsChildren} is true, then this checks if the TreeNode
+ * allows children, otherwise it returns the TreeNode's <code>leaf</code>
+ * property.
*
- * @param node TODO
- * @return boolean
+ * @param node the node to check
+ *
+ * @return boolean <code>true</code> if the node is a leaf node,
+ * <code>false</code> otherwise
+ *
+ * @throws ClassCastException if the specified node is not a
+ * <code>TreeNode</code> instance
+ *
+ * @see TreeNode#getAllowsChildren()
+ * @see TreeNode#isLeaf()
*/
public boolean isLeaf(Object node)
{
- if (node instanceof TreeNode)
- return ((TreeNode) node).isLeaf();
+ // The RI throws a ClassCastException when node isn't a TreeNode, so do we.
+ TreeNode treeNode = (TreeNode) node;
+ boolean leaf;
+ if (asksAllowsChildren)
+ leaf = ! treeNode.getAllowsChildren();
else
- return true;
+ leaf = treeNode.isLeaf();
+ return leaf;
}
/**
@@ -600,7 +615,7 @@
*
* @since 1.3
*/
- public EventListener[] getListeners(Class listenerType)
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
{
return listenerList.getListeners(listenerType);
}
Modified: trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeSelectionModel.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeSelectionModel.java 2007-02-04 10:20:16 UTC (rev 3107)
+++ trunk/core/src/classpath/javax/javax/swing/tree/DefaultTreeSelectionModel.java 2007-02-04 12:10:47 UTC (rev 3108)
@@ -44,6 +44,7 @@
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.EventListener;
import java.util.HashSet;
import java.util.Iterator;
@@ -69,6 +70,38 @@
{
/**
+ * According to the API docs, the method
+ * {@link DefaultTreeSelectionModel#notifyPathChange} should
+ * expect instances of a class PathPlaceHolder in the Vector parameter.
+ * This seems to be a non-public class, so I can only make guesses about the
+ * use of it.
+ */
+ private static class PathPlaceHolder
+ {
+ /**
+ * The path that we wrap.
+ */
+ TreePath path;
+
+ /**
+ * Indicates if the path is new or already in the selection.
+ */
+ boolean isNew;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param p the path to wrap
+ * @param n if the path is new or already in the selection
+ */
+ PathPlaceHolder(TreePath p, boolean n)
+ {
+ path = p;
+ isNew = n;
+ }
+ }
+
+ /**
* Use serialVersionUID for interoperability.
*/
static final long serialVersionUID = 3288129636638950196L;
@@ -124,12 +157,36 @@
protected int leadRow = -1;
/**
+ * A supporting datastructure that is used in addSelectionPaths() and
+ * removeSelectionPaths(). It contains currently selected paths.
+ *
+ * @see #addSelectionPaths(TreePath[])
+ * @see #removeSelectionPaths(TreePath[])
+ * @see #setSelectionPaths(TreePath[])
+ */
+ private transient HashSet selectedPaths;
+
+ /**
+ * A supporting datastructure that is used in addSelectionPaths() and
+ * removeSelectionPaths(). It contains the paths that are added or removed.
+ *
+ * @see #addSelectionPaths(TreePath[])
+ * @see #removeSelectionPaths(TreePath[])
+ * @see #setSelectionPaths(TreePath[])
+ */
+ private transient HashSet tmpPaths;
+
+ /**
* Constructs a new DefaultTreeSelectionModel.
*/
public DefaultTreeSelectionModel()
{
setSelectionMode(DISCONTIGUOUS_TREE_SELECTION);
+ listSelectionModel = new DefaultListSelectionModel();
listenerList = new EventListenerList();
+ leadIndex = -1;
+ tmpPaths = new HashSet();
+ selectedPaths = new HashSet();
}
/**
@@ -144,12 +201,14 @@
{
DefaultTreeSelectionModel cloned =
(DefaultTreeSelectionModel) super.clone();
-
- // Clone the selection and the list selection model.
+ cloned.changeSupport = null;
cloned.selection = (TreePath[]) selection.clone();
- if (listSelectionModel != null)
- cloned.listSelectionModel
- = (DefaultListSelectionModel) listSelectionModel.clone();
+ cloned.listenerList = new EventListenerList();
+ cloned.listSelectionModel =
+ (DefaultListSelectionModel) listSelectionModel.clone();
+ cloned.selectedPaths = new HashSet();
+ cloned.tmpPaths = new HashSet();
+
return cloned;
}
@@ -209,6 +268,7 @@
public void setRowMapper(RowMapper mapper)
{
rowMapper = mapper;
+ resetRowSelection();
}
/**
@@ -236,8 +296,18 @@
*/
public void setSelectionMode(int mode)
{
+ int oldMode = selectionMode;
selectionMode = mode;
- insureRowContinuity();
+ // Make sure we have a valid selection mode.
+ if (selectionMode != SINGLE_TREE_SELECTION
+ && selectionMode != CONTIGUOUS_TREE_SELECTION
+ && selectionMode != DISCONTIGUOUS_TREE_SELECTION)
+ selectionMode = DISCONTIGUOUS_TREE_SELECTION;
+
+ // Fire property change event.
+ if (oldMode != selectionMode && changeSupport != null)
+ changeSupport.firePropertyChange(SELECTION_MODE_PROPERTY, oldMode,
+ selectionMode);
}
/**
@@ -262,32 +332,10 @@
*/
public void setSelectionPath(TreePath path)
{
- // The most frequently only one cell in the tree is selected.
- TreePath[] ose = selection;
- selection = new TreePath[] { path };
- TreePath oldLead = leadPath;
- leadIndex = 0;
- leadRow = getRow(path);
- leadPath = path;
-
- TreeSelectionEvent event;
-
- if (ose != null && ose.length > 0)
- {
- // The first item in the path list is the selected path.
- // The remaining items are unselected pathes.
- TreePath[] changed = new TreePath[ose.length + 1];
- boolean[] news = new boolean[changed.length];
- news[0] = true;
- changed[0] = path;
- System.arraycopy(ose, 0, changed, 1, ose.length);
- event = new TreeSelectionEvent(this, changed, news, oldLead, path);
- }
- else
- {
- event = new TreeSelectionEvent(this, path, true, oldLead, path);
- }
- fireValueChanged(event);
+ TreePath[] paths = null;
+ if (path != null)
+ paths = new TreePath[]{ path };
+ setSelectionPaths(paths);
}
/**
@@ -307,7 +355,7 @@
AbstractLayoutCache ama = (AbstractLayoutCache) mapper;
return ama.getRowForPath(path);
}
- else
+ else if (mapper != null)
{
// Generic non optimized implementation.
int[] rows = mapper.getRowsForPaths(new TreePath[] { path });
@@ -316,6 +364,7 @@
else
return rows[0];
}
+ return -1;
}
/**
@@ -327,10 +376,90 @@
*/
public void setSelectionPaths(TreePath[] paths)
{
- // Must be called, as defined in JDK API 1.4.
+ int oldLength = 0;
+ if (selection != null)
+ oldLength = selection.length;
+ int newLength = 0;
+ if (paths != null)
+ newLength = paths.length;
+ if (newLength > 0 || oldLength > 0)
+ {
+ // For SINGLE_TREE_SELECTION and for CONTIGUOUS_TREE_SELECTION with
+ // a non-contiguous path, we only allow the first path element.
+ if ((selectionMode == SINGLE_TREE_SELECTION && newLength > 1)
+ || (selectionMode == CONTIGUOUS_TREE_SELECTION && newLength > 0
+ && ! arePathsContiguous(paths)))
+ {
+ paths = new TreePath[] { paths[0] };
+ newLength = 1;
+ }
+ // Find new paths.
+ Vector changedPaths = null;
+ tmpPaths.clear();
+ int validPaths = 0;
+ TreePath oldLeadPath = leadPath;
+ for (int i = 0; i < newLength; i++)
+ {
+ if (paths[i] != null && ! tmpPaths.contains(paths[i]))
+ {
+ validPaths++;
+ tmpPaths.add(paths[i]);
+ if (! selectedPaths.contains(paths[i]))
+ {
+ if (changedPaths == null)
+ changedPaths = new Vector();
+ changedPaths.add(new PathPlaceHolder(paths[i], true));
+ }
+ leadPath = paths[i];
+ }
+ }
+ // Put together the new selection.
+ TreePath[] newSelection = null;
+ if (validPaths != 0)
+ {
+ if (validPaths != newLength)
+ {
+ // Some of the paths are already selected, put together
+ // the new selection carefully.
+ newSelection = new TreePath[validPaths];
+ Iterator newPaths = tmpPaths.iterator();
+ validPaths = 0;
+ for (int i = 0; newPaths.hasNext(); i++)
+ newSelection[i] = (TreePath) newPaths.next();
+ }
+ else
+ {
+ newSelection = new TreePath[paths.length];
+ System.arraycopy(paths, 0, newSelection, 0, paths.length);
+ }
+ }
+
+ // Find paths that have been selected, but are no more.
+ for (int i = 0; i < oldLength; i++)
+ {
+ if (selection[i] != null && ! tmpPaths.contains(selection[i]))
+ {
+ if (changedPaths == null)
+ changedPaths = new Vector();
+ changedPaths.add(new PathPlaceHolder(selection[i], false));
+ }
+ }
+
+ // Perform changes and notification.
+ selection = newSelection;
+ HashSet tmp = selectedPaths;
+ selectedPaths = tmpPaths;
+ tmpPaths = tmp;
+ tmpPaths.clear();
+
+ // Not necessary, but required according to the specs and to tests.
+ if (selection != null)
insureUniqueness();
- clearSelection();
- addSelectionPaths(paths);
+ updateLeadIndex();
+ resetRowSelection();
+ if (changedPaths != null && changedPaths.size() > 0)
+ notifyPathChange(changedPaths, oldLeadPath);
+ }
}
/**
@@ -345,29 +474,10 @@
*/
public void addSelectionPath(TreePath path)
{
- if (! isPathSelected(path))
- {
- if (selectionMode == SINGLE_TREE_SELECTION || isSelectionEmpty()
- || ! canPathBeAdded(path))
- setSelectionPath(path);
- else
- {
- TreePath[] temp = new TreePath[selection.length + 1];
- System.arraycopy(selection, 0, temp, 0, selection.length);
- temp[temp.length - 1] = path;
- selection = new TreePath[temp.length];
- System.arraycopy(temp, 0, selection, 0, temp.length);
- }
- }
-
- if (path != leadPath)
+ if (path != null)
{
- TreePath oldLead = leadPath;
- leadPath = path;
- leadRow = getRow(path);
- leadIndex = selection.length - 1;
- fireValueChanged(new TreeSelectionEvent(this, path, true, oldLead,
- leadPath));
+ TreePath[] add = new TreePath[]{ path };
+ addSelectionPaths(add);
}
}
@@ -380,37 +490,76 @@
*/
public void addSelectionPaths(TreePath[] paths)
{
- // Must be called, as defined in JDK API 1.4.
- insureUniqueness();
-
- if (paths != null)
- {
- TreePath v0 = null;
- for (int i = 0; i < paths.length; i++)
+ int length = paths != null ? paths.length : 0;
+ if (length > 0)
{
- v0 = paths[i];
- if (! isPathSelected(v0))
+ if (selectionMode == SINGLE_TREE_SELECTION)
+ setSelectionPaths(paths);
+ else if (selectionMode == CONTIGUOUS_TREE_SELECTION
+ && ! canPathsBeAdded(paths))
{
- if (isSelectionEmpty())
- setSelectionPath(v0);
+ if (arePathsContiguous(paths))
+ setSelectionPaths(paths);
+ else
+ setSelectionPaths(new TreePath[] { paths[0] });
+ }
else
{
- TreePath[] temp = new TreePath[selection.length + 1];
- System.arraycopy(selection, 0, temp, 0, selection.length);
- temp[temp.length - 1] = v0;
- selection = new TreePath[temp.length];
- System.arraycopy(temp, 0, selection, 0, temp.length);
+ Vector changedPaths = null;
+ tmpPaths.clear();
+ int validPaths = 0;
+ TreePath oldLeadPath = leadPath;
+ int oldPaths = 0;
+ if (selection != null)
+ oldPaths = selection.length;
+ int i;
+ for (i = 0; i < length; i++)
+ {
+ if (paths[i] != null)
+ {
+ if (! selectedPaths.contains(paths[i]))
+ {
+ validPaths++;
+ if (changedPaths == null)
+ changedPaths = new Vector();
+ changedPaths.add(new PathPlaceHolder(paths[i], true));
+ selectedPaths.add(paths[i]);
+ tmpPaths.add(paths[i]);
}
- TreePath oldLead = leadPath;
- leadPath = paths[paths.length - 1];
- leadRow = getRow(leadPath);
- leadIndex = selection.length - 1;
-
- fireValueChanged(new TreeSelectionEvent(this, v0, true,
- oldLead, leadPath));
+ leadPath = paths[i];
}
}
- insureRowContinuity();
+ if (validPaths > 0)
+ {
+ TreePath[] newSelection = new TreePath[oldPaths + validPaths];
+ if (oldPaths > 0)
+ System.arraycopy(selection, 0, newSelection, 0, oldPaths);
+ if (validPaths != paths.length)
+ {
+ // Some of the paths are already selected, put together
+ // the new selection carefully.
+ Iterator newPaths = tmpPaths.iterator();
+ i = oldPaths;
+ while (newPaths.hasNext())
+ {
+ newSelection[i] = (TreePath) newPaths.next();
+ i++;
+ }
+ }
+ else
+ System.arraycopy(paths, 0, newSelection, oldPaths,
+ validPaths);
+ selection = newSelection;
+ insureUniqueness();
+ updateLeadIndex();
+ resetRowSelection();
+ if (changedPaths != null && changedPaths.size() > 0)
+ notifyPathChange(changedPaths, oldLeadPath);
+ }
+ else
+ leadPath = oldLeadPath;
+ tmpPaths.clear();
+ }
}
}
@@ -422,36 +571,8 @@
*/
public void removeSelectionPath(TreePath path)
{
- if (isSelectionEmpty())
- return;
-
- int index = - 1;
- if (isPathSelected(path))
- {
- for (int i = 0; i < selection.length; i++)
- {
- if (selection[i].equals(path))
- {
- index = i;
- break;
- }
- }
- TreePath[] temp = new TreePath[selection.length - 1];
- System.arraycopy(selection, 0, temp, 0, index);
- System.arraycopy(selection, index + 1, temp, index, selection.length
- - index - 1);
- selection = new TreePath[temp.length];
- System.arraycopy(temp, 0, selection, 0, temp.length);
-
- // If the removed path was the lead path, set the lead path to null.
- TreePath oldLead = leadPath;
- if (path != null && leadPath != null && path.equals(leadPath))
- leadPath = null;
-
- fireValueChanged(new TreeSelectionEvent(this, path, false, oldLead,
- leadPath));
- insureRowContinuity();
- }
+ if (path != null)
+ removeSelectionPaths(new TreePath[]{ path });
}
/**
@@ -462,40 +583,54 @@
*/
public void removeSelectionPaths(TreePath[] paths)
{
- if (isSelectionEmpty())
- return;
- if (paths != null)
+ if (paths != null && selection != null && paths.length > 0)
{
- int index = - 1;
- TreePath v0 = null;
- TreePath oldLead = leadPath;
- for (int i = 0; i < paths.length; i++)
+ if (! canPathsBeRemoved(paths))
+ clearSelection();
+ else
+ {
+ Vector pathsToRemove = null;
+ for (int i = paths.length - 1; i >= 0; i--)
{
- v0 = paths[i];
- if (isPathSelected(v0))
+ if (paths[i] != null && selectedPaths.contains(paths[i]))
{
- for (int x = 0; x < selection.length; x++)
+ if (pathsToRemove == null)
+ pathsToRemove = new Vector();
+ selectedPaths.remove(paths[i]);
+ pathsToRemove.add(new PathPlaceHolder(paths[i],
+ false));
+ }
+ }
+ if (pathsToRemove != null)
{
- if (selection[i].equals(v0))
+ int numRemove = pathsToRemove.size();
+ TreePath oldLead = leadPath;
+ if (numRemove == selection.length)
+ selection = null;
+ else
{
- index = x;
- break;
+ selection = new TreePath[selection.length - numRemove];
+ Iterator keep = selectedPaths.iterator();
+ for (int valid = 0; keep.hasNext(); valid++)
+ selection[valid] = (TreePath) keep.next();
}
- if (leadPath != null && leadPath.equals(v0))
+ // Update lead path.
+ if (leadPath != null && ! selectedPaths.contains(leadPath))
+ {
+ if (selection != null)
+ leadPath = selection[selection.length - 1];
+ else
leadPath = null;
}
- TreePath[] temp = new TreePath[selection.length - 1];
- System.arraycopy(selection, 0, temp, 0, index);
- System.arraycopy(selection, index + 1, temp, index,
- selection.length - index - 1);
- selection = new TreePath[temp.length];
- System.arraycopy(temp, 0, selection, 0, temp.length);
-
- fireValueChanged(new TreeSelectionEvent(this, v0, false,
- oldLead, leadPath));
+ else if (selection != null)
+ leadPath = selection[selection.length - 1];
+ else
+ leadPath = null;
+ updateLeadIndex();
+ resetRowSelection();
+ notifyPathChange(pathsToRemove, oldLead);
}
}
- insureRowContinuity();
}
}
@@ -572,20 +707,23 @@
*/
public void clearSelection()
{
- if (! isSelectionEmpty())
+ if (selection != null)
{
- TreeSelectionEvent event = new TreeSelectionEvent(
- this, selection, new boolean[selection.length], leadPath, null);
+ int selectionLength = selection.length;
+ boolean[] news = new boolean[selectionLength];
+ Arrays.fill(news, false);
+ TreeSelectionEvent event = new TreeSelectionEvent(this, selection,
+ news, leadPath,
+ null);
leadPath = null;
+ leadIndex = 0;
+ leadRow = 0;
+ selectedPaths.clear();
selection = null;
+ resetRowSelection();
fireValueChanged(event);
}
- else
- {
- leadPath = null;
- selection = null;
}
- }
/**
* Adds a <code>TreeSelectionListener</code> object to this model.
@@ -638,7 +776,7 @@
* @return an array of listeners
* @since 1.3
*/
- public EventListener[] getListeners(Class listenerType)
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
{
return listenerList.getListeners(listenerType);
}
@@ -650,10 +788,43 @@
*/
public int[] getSelectionRows()
{
- if (rowMapper == null)
- return null;
+ int[] rows = null;
+ if (rowMapper != null && selection != null)
+ {
+ rows = rowMapper.getRowsForPaths(selection);
+ if (rows != null)
+ {
+ // Find invisible rows.
+ int invisible = 0;
+ for (int i = rows.length - 1; i >= 0; i--)
+ {
+ if (rows[i] == -1)
+ invisible++;
+
+ }
+ // Clean up invisible rows.
+ if (invisible > 0)
+ {
+ if (invisible == rows.length)
+ rows = null;
else
- return rowMapper.getRowsForPaths(selection);
+ {
+ int[] newRows = new int[rows.length - invisible];
+ int visCount = 0;
+ for (int i = rows.length - 1; i >= 0; i--)
+ {
+ if (rows[i] != -1)
+ {
+ newRows[visCount] = rows[i];
+ visCount++;
+ }
+ }
+ rows = newRows;
+ }
+ }
+ }
+ }
+ return rows;
}
/**
@@ -663,16 +834,7 @@
*/
public int getMinSelectionRow()
{
- if ((rowMapper == null) || (selection == null) || (selection.length == 0))
- return - 1;
- else
- {
- int[] rows = rowMapper.getRowsForPaths(selection);
- int minRow = Integer.MAX_VALUE;
- for (int index = 0; index < rows.length; index++)
- minRow = Math.min(minRow, rows[index]);
- return minRow;
- }
+ return listSelectionModel.getMinSelectionIndex();
}
/**
@@ -682,16 +844,7 @@
*/
public int getMaxSelectionRow()
{
- if ((rowMapper == null) || (selection == null) || (selection.length == 0))
- return - 1;
- else
- {
- int[] rows = rowMapper.getRowsForPaths(selection);
- int maxRow = - 1;
- for (int index = 0; index < rows.length; index++)
- maxRow = Math.max(maxRow, rows[index]);
- return maxRow;
- }
+ return listSelectionModel.getMaxSelectionIndex();
}
/**
@@ -706,29 +859,7 @@
*/
public boolean isRowSelected(int row)
{
- // Return false if nothing is selected.
- if (isSelectionEmpty())
- return false;
-
- RowMapper mapper = getRowMapper();
-
- if (mapper instanceof AbstractLayoutCache)
- {
- // The absolute majority of cases, unless the TreeUI is very
- // seriously rewritten
- AbstractLayoutCache ama = (AbstractLayoutCache) mapper;
- TreePath path = ama.getPathForRow(row);
- return isPathSelected(path);
- }
- else
- {
- // Generic non optimized implementation.
- int[] rows = mapper.getRowsForPaths(selection);
- for (int i = 0; i < rows.length; i++)
- if (rows[i] == row)
- return true;
- return false;
- }
+ return listSelectionModel.isSelectedIndex(row);
}
/**
@@ -736,7 +867,32 @@
*/
public void resetRowSelection()
{
- // Nothing to do here.
+ listSelectionModel.clearSelection();
+ if (selection != null && rowMapper != null)
+ {
+ int[] rows = rowMapper.getRowsForPaths(selection);
+ // Update list selection model.
+ for (int i = 0; i < rows.length; i++)
+ {
+ int row = rows[i];
+ if (row != -1)
+ listSelectionModel.addSelectionInterval(row, row);
+ }
+ // Update lead selection.
+ if (leadIndex != -1 && rows != null)
+ leadRow = rows[leadIndex];
+ else if (leadPath != null)
+ {
+ TreePath[] tmp = new TreePath[]{ leadPath };
+ rows = rowMapper.getRowsForPaths(tmp);
+ leadRow = rows != null ? rows[0] : -1;
+ }
+ else
+ leadRow = -1;
+ insureRowContinuity();
+ }
+ else
+ leadRow = -1;
}
/**
@@ -766,6 +922,8 @@
*/
public void addPropertyChangeListener(PropertyChangeListener listener)
{
+ if (changeSupport == null)
+ changeSupport = new SwingPropertyChangeSupport(this);
changeSupport.addPropertyChangeListener(listener);
}
@@ -776,6 +934,7 @@
*/
public void removePropertyChangeListener(PropertyChangeListener listener)
{
+ if (changeSupport != null)
changeSupport.removePropertyChangeListener(listener);
}
@@ -787,7 +946,12 @@
*/
public PropertyChangeListener[] getPropertyChangeListeners()
{
- return changeSupport.getPropertyChangeListeners();
+ PropertyChangeListener[] listeners = null;
+ if (changeSupport != null)
+ listeners = changeSupport.getPropertyChangeListeners();
+ else
+ listeners = new PropertyChangeListener[0];
+ return listeners;
}
/**
@@ -801,65 +965,39 @@
*/
protected void insureRowContinuity()
{
- if (selection == null || selection.length < 2)
- return;
- else if (selectionMode == CONTIGUOUS_TREE_SELECTION)
+ if (selectionMode == CONTIGUOUS_TREE_SELECTION && selection != null
+ && rowMapper != null)
{
- if (rowMapper == null)
- // This is the best we can do without the row mapper:
- selectOne();
+ int min = listSelectionModel.getMinSelectionIndex();
+ if (min != -1)
+ {
+ int max = listSelectionModel.getMaxSelectionIndex();
+ for (int i = min; i <= max; i++)
+ {
+ if (! listSelectionModel.isSelectedIndex(i))
+ {
+ if (i == min)
+ clearSelection();
else
{
+ TreePath[] newSelection = new TreePath[i - min];
int[] rows = rowMapper.getRowsForPaths(selection);
- Arrays.sort(rows);
- int i;
- for (i = 1; i < rows.length; i++)
+ for (int j = 0; j < rows.length; j++)
{
- if (rows[i - 1] != rows[i] - 1)
- // Break if no longer continuous.
+ if (rows[j] < i)
+ newSelection[rows[j] - min] = selection[j];
+ }
+ setSelectionPaths(newSelection);
break;
}
-
- if (i < rows.length)
- {
- TreePath[] ns = new TreePath[i];
- for (int j = 0; j < ns.length; j++)
- ns[i] = getPath(j);
- setSelectionPaths(ns);
}
}
}
- else if (selectionMode == SINGLE_TREE_SELECTION)
- selectOne();
}
-
- /**
- * Keep only one (normally last or leading) path in the selection.
- */
- private void selectOne()
- {
- if (leadIndex > 0 && leadIndex < selection.length)
- setSelectionPath(selection[leadIndex]);
- else
- setSelectionPath(selection[selection.length - 1]);
+ else if (selectionMode == SINGLE_TREE_SELECTION && selection != null
+ && selection.length > 1)
+ setSelectionPath(selection[0]);
}
-
- /**
- * Get path for the given row that must be in the current selection.
- */
- private TreePath getPath(int row)
- {
- if (rowMapper instanceof AbstractLayoutCache)
- return ((AbstractLayoutCache) rowMapper).getPathForRow(row);
- else
- {
- int[] rows = rowMapper.getRowsForPaths(selection);
- for (int i = 0; i < rows.length; i++)
- if (rows[i] == row)
- return selection[i];
- }
- throw new InternalError(row + " not in selection");
- }
/**
* Returns <code>true</code> if the paths are contiguous (take subsequent
@@ -875,16 +1013,36 @@
if (rowMapper == null || paths.length < 2)
return true;
- int[] rows = rowMapper.getRowsForPaths(paths);
-
- // The patches may not be sorted.
- Arrays.sort(rows);
+ int length = paths.length;
+ TreePath[] tmp = new TreePath[1];
+ tmp[0] = paths[0];
+ int min = rowMapper.getRowsForPaths(tmp)[0];
+ BitSet selected = new BitSet();
+ int valid = 0;
+ for (int i = 0; i < length; i++)
+ {
+ if (paths[i] != null)
+ {
+ tmp[0] = paths[i];
+ int[] rows = rowMapper.getRowsForPaths(tmp);
+ if (rows == null)
+ return false; // No row mapping yet, can't be selected.
+ int row = rows[0];
+ if (row == -1 || row < (min - length) || row > (min + length))
+ return false; // Not contiguous.
+ min = Math.min(min, row);
+ if (! selected.get(row))
+ {
+ selected.set(row);
+ valid++;
+ }
- for (int i = 1; i < rows.length; i++)
- {
- if (rows[i - 1] != rows[i] - 1)
- return false;
}
+ }
+ int max = valid + min;
+ for (int i = min; i < max; i++)
+ if (! selected.get(i))
+ return false; // Not contiguous.
return true;
}
@@ -904,31 +1062,48 @@
*/
protected boolean canPathsBeAdded(TreePath[] paths)
{
- if (rowMapper == null || isSelectionEmpty()
- || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
+ if (paths == null || paths.length == 0 || rowMapper == null
+ || selection == null || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
return true;
- TreePath [] all = new TreePath[paths.length + selection.length];
- System.arraycopy(paths, 0, all, 0, paths.length);
- System.arraycopy(selection, 0, all, paths.length, selection.length);
-
- return arePathsContiguous(all);
+ BitSet selected = new BitSet();
+ int min = listSelectionModel.getMinSelectionIndex();
+ int max = listSelectionModel.getMaxSelectionIndex();
+ TreePath[] tmp = new TreePath[1];
+ if (min != -1)
+ {
+ // Set the bitmask of selected elements.
+ for (int i = min; i <= max; i++)
+ selected.set(i);
}
-
- /**
- * Checks if the single path can be added to selection.
- */
- private boolean canPathBeAdded(TreePath path)
+ else
{
- if (rowMapper == null || isSelectionEmpty()
- || selectionMode == DISCONTIGUOUS_TREE_SELECTION)
+ tmp[0] = paths[0];
+ min = rowMapper.getRowsForPaths(tmp)[0];
+ max = min;
+ }
+ // Mark new paths as selected.
+ for (int i = paths.length - 1; i >= 0; i--)
+ {
+ if (paths[i] != null)
+ {
+ tmp[0] = paths[i];
+ int[] rows = rowMapper.getRowsForPaths(tmp);
+ if (rows == null)
+ return false; // Now row mapping yet, can't be selected.
+ int row = rows[0];
+ if (row == -1)
+ return false; // Now row mapping yet, can't be selected.
+ min = Math.min(min, row);
+ max = Math.max(max, row);
+ selected.set(row);
+ }
+ }
+ // Now look if the new selection would be contiguous.
+ for (int i = min; i <= max; i++)
+ if (! selected.get(i))
+ return false;
return true;
-
- TreePath[] all = new TreePath[selection.length + 1];
- System.arraycopy(selection, 0, all, 0, selection.length);
- all[all.length - 1] = path;
-
- return arePathsContiguous(all);
}
/**
@@ -966,20 +1141,23 @@
* method will call listeners if invoked, but it is not called from the
* implementation of this class.
*
- * @param vPathes the vector of the changed patches
+ * @param vPaths the vector of the changed patches
* @param oldLeadSelection the old selection index
*/
- protected void notifyPathChange(Vector vPathes, TreePath oldLeadSelection)
+ protected void notifyPathChange(Vector vPaths, TreePath oldLeadSelection)
{
- TreePath[] pathes = new TreePath[vPathes.size()];
- for (int i = 0; i < pathes.length; i++)
- pathes[i] = (TreePath) vPathes.get(i);
- boolean[] news = new boolean[pathes.length];
- for (int i = 0; i < news.length; i++)
- news[i] = isPathSelected(pathes[i]);
+ int numChangedPaths = vPaths.size();
+ boolean[] news = new boolean[numChangedPaths];
+ TreePath[] paths = new TreePath[numChangedPaths];
+ for (int i = 0; i < numChangedPaths; i++)
+ {
+ PathPlaceHolder p = (PathPlaceHolder) vPaths.get(i);
+ news[i] = p.isNew;
+ paths[i] = p.path;
+ }
- TreeSelectionEvent event = new TreeSelectionEvent(this, pathes, news,
+ TreeSelectionEvent event = new TreeSelectionEvent(this, paths, news,
oldLeadSelection,
leadPath);
fireValueChanged(event);
@@ -991,22 +1169,20 @@
*/
protected void updateLeadIndex()
{
- if (isSelectionEmpty())
+ leadIndex = -1;
+ if (leadPath != null)
{
- leadRow = leadIndex = - 1;
- }
+ leadRow = -1;
+ if (selection == null)
+ leadPath = null;
else
{
- leadRow = getRow(leadPath);
- for (int i = 0; i < selection.length; i++)
- {
- if (selection[i].equals(leadPath))
+ for (int i = selection.length - 1; i >= 0 && leadIndex == -1; i--)
{
+ if (selection[i] == leadPath)
leadIndex = i;
- break;
}
}
- leadIndex = leadRow;
}
}
Modified: trunk/core/src/classpath/javax/javax/swing/tree/FixedHeightLayoutCache.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/tree/FixedHeightLayoutCache.java 2007-02-04 10:20:16 UTC (rev 3107)
+++ trunk/core/src/classpath/javax/javax/swing/tree/FixedHeightLayoutCache.java 2007-02-04 12:10:47 UTC (rev 3108)
@@ -480,7 +480,7 @@
* @param parentPath the parent path
* @return the enumeration over pathes
*/
- public Enumeration getVisiblePathsFrom(TreePath parentPath)
+ public Enumeration<TreePath> getVisiblePathsFrom(TreePath parentPath)
{
if (dirty)
update();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-04 10:20:21
|
Revision: 3107
http://jnode.svn.sourceforge.net/jnode/?rev=3107&view=rev
Author: lsantha
Date: 2007-02-04 02:20:16 -0800 (Sun, 04 Feb 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/javax/javax/swing/plaf/metal/DefaultMetalTheme.java
trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalCheckBoxIcon.java
trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalComboBoxUI.java
trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalFileChooserUI.java
trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalIconFactory.java
trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalRadioButtonUI.java
trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalScrollBarUI.java
trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalSliderUI.java
trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalUtils.java
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/metal/DefaultMetalTheme.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/metal/DefaultMetalTheme.java 2007-02-04 09:46:03 UTC (rev 3106)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/metal/DefaultMetalTheme.java 2007-02-04 10:20:16 UTC (rev 3107)
@@ -38,8 +38,11 @@
package javax.swing.plaf.metal;
+import gnu.classpath.SystemProperties;
+
import java.awt.Font;
+import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.FontUIResource;
@@ -63,10 +66,6 @@
private static final ColorUIResource SECONDARY3 =
new ColorUIResource(204, 204, 204);
- private static final FontUIResource CONTROL_TEXT_FONT =
- new FontUIResource("Dialog", Font.BOLD, 12);
- private static final FontUIResource MENU_TEXT_FONT =
- new FontUIResource("Dialog", Font.BOLD, 12);
private static final FontUIResource SUB_TEXT_FONT =
new FontUIResource("Dialog", Font.PLAIN, 10);
private static final FontUIResource SYSTEM_TEXT_FONT =
@@ -77,6 +76,40 @@
new FontUIResource("Dialog", Font.BOLD, 12);
/**
+ * The control text font for swing.boldMetal=false.
+ */
+ private static final FontUIResource PLAIN_CONTROL_TEXT_FONT =
+ new FontUIResource("Dialog", Font.PLAIN, 12);
+
+ /**
+ * The standard control text font.
+ */
+ private static final FontUIResource BOLD_CONTROL_TEXT_FONT =
+ new FontUIResource("Dialog", Font.BOLD, 12);
+
+ /**
+ * The menu text font for swing.boldMetal=false.
+ */
+ private static final FontUIResource PLAIN_MENU_TEXT_FONT =
+ new FontUIResource("Dialog", Font.PLAIN, 12);
+
+ /**
+ * The menu control text font.
+ */
+ private static final FontUIResource BOLD_MENU_TEXT_FONT =
+ new FontUIResource("Dialog", Font.BOLD, 12);
+
+ /**
+ * Indicates the control text font.
+ */
+ static final int CONTROL_TEXT_FONT = 1;
+
+ /**
+ * Indicates the menu text font.
+ */
+ static final int MENU_TEXT_FONT = 2;
+
+ /**
* Creates a new instance of this theme.
*/
public DefaultMetalTheme()
@@ -156,23 +189,28 @@
/**
* Returns the font used for text on controls. In this case, the font is
- * <code>FontUIResource("Dialog", Font.BOLD, 12)</code>.
+ * <code>FontUIResource("Dialog", Font.BOLD, 12)</code>, unless the
+ * <code>swing.boldMetal</code> UI default is set to {@link Boolean#FALSE}
+ * in which case it is <code>FontUIResource("Dialog", Font.PLAIN, 12)</code>.
*
* @return The font.
*/
public FontUIResource getControlTextFont()
{
- return CONTROL_TEXT_FONT;
+ return getFont(CONTROL_TEXT_FONT);
}
+
/**
* Returns the font used for text in menus. In this case, the font is
- * <code>FontUIResource("Dialog", Font.BOLD, 12)</code>.
+ * <code>FontUIResource("Dialog", Font.BOLD, 12)</code>, unless the
+ * <code>swing.boldMetal</code> UI default is set to {@link Boolean#FALSE}
+ * in which case it is <code>FontUIResource("Dialog", Font.PLAIN, 12)</code>.
*
* @return The font used for text in menus.
*/
public FontUIResource getMenuTextFont()
{
- return MENU_TEXT_FONT;
+ return getFont(MENU_TEXT_FONT);
}
/**
@@ -218,4 +256,50 @@
{
return WINDOW_TITLE_FONT;
}
+
+ /**
+ * Returns the appropriate font. The font type to return is identified
+ * by the specified id.
+ *
+ * @param id the font type to return
+ *
+ * @return the correct font
+ */
+ private FontUIResource getFont(int id)
+ {
+ FontUIResource font = null;
+ switch (id)
+ {
+ case CONTROL_TEXT_FONT:
+ if (isBoldMetal())
+ font = BOLD_CONTROL_TEXT_FONT;
+ else
+ font = PLAIN_CONTROL_TEXT_FONT;
+ break;
+ case MENU_TEXT_FONT:
+ if (isBoldMetal())
+ font = BOLD_MENU_TEXT_FONT;
+ else
+ font = PLAIN_MENU_TEXT_FONT;
+ break;
+ // TODO: Add other font types and their mapping here.
+ }
+ return font;
+ }
+
+ /**
+ * Determines if the theme should be bold or not. The theme is bold by
+ * default, this can be turned off by setting the system property
+ * swing.boldMetal to true, or by putting the property with the same name
+ * into the current UIManager's defaults.
+ *
+ * @return <code>true</code>, when the theme is bold, <code>false</code>
+ * otherwise
+ */
+ private boolean isBoldMetal()
+ {
+ Object boldMetal = UIManager.get("swing.boldMetal");
+ return (boldMetal == null || ! Boolean.FALSE.equals(boldMetal))
+ && ! ("false".equals(SystemProperties.getProperty("swing.boldMetal")));
+ }
}
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalCheckBoxIcon.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalCheckBoxIcon.java 2007-02-04 09:46:03 UTC (rev 3106)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalCheckBoxIcon.java 2007-02-04 10:20:16 UTC (rev 3107)
@@ -1,5 +1,5 @@
/* MetalCheckBoxIcon.java -- An icon for JCheckBoxes in the Metal L&F
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,8 +42,8 @@
import java.awt.Graphics;
import java.io.Serializable;
+import javax.swing.AbstractButton;
import javax.swing.Icon;
-import javax.swing.JCheckBox;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.plaf.UIResource;
@@ -134,8 +134,9 @@
MetalUtils.paintGradient(g, x, y, getIconWidth(), getIconHeight(),
SwingConstants.VERTICAL, "CheckBox.gradient");
border.paintBorder(c, g, x, y, getIconWidth(), getIconHeight());
- JCheckBox cb = (JCheckBox) c;
- if (cb.isSelected())
- drawCheck(c, g, x, y);
+
+ AbstractButton b = (AbstractButton) c;
+ if (b.isSelected())
+ drawCheck(b, g, x, y);
}
}
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalComboBoxUI.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalComboBoxUI.java 2007-02-04 09:46:03 UTC (rev 3106)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalComboBoxUI.java 2007-02-04 10:20:16 UTC (rev 3107)
@@ -48,7 +48,6 @@
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import javax.swing.CellRendererPane;
import javax.swing.ComboBoxEditor;
import javax.swing.Icon;
import javax.swing.JButton;
@@ -217,7 +216,7 @@
*/
protected ComboPopup createPopup()
{
- return new MetalComboPopup(comboBox);
+ return super.createPopup();
}
/**
@@ -228,7 +227,7 @@
protected JButton createArrowButton()
{
JButton button = new MetalComboBoxButton(comboBox, new MetalComboBoxIcon(),
- new CellRendererPane(), listBox);
+ currentValuePane, listBox);
button.setMargin(new Insets(0, 1, 1, 3));
return button;
}
@@ -305,7 +304,6 @@
{
MetalComboBoxButton b = (MetalComboBoxButton) arrowButton;
d = getDisplaySize();
- Insets insets = b.getInsets();
Insets arrowInsets = b.getInsets();
Insets comboInsets = comboBox.getInsets();
Icon icon = b.getComboIcon();
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalFileChooserUI.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalFileChooserUI.java 2007-02-04 09:46:03 UTC (rev 3106)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalFileChooserUI.java 2007-02-04 10:20:16 UTC (rev 3107)
@@ -42,6 +42,7 @@
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
+import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
@@ -55,7 +56,7 @@
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
-import java.util.Date;
+import java.sql.Date;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.List;
@@ -303,7 +304,8 @@
if (file == null)
setFileName(null);
- else
+ else if (file.isFile() || filechooser.getFileSelectionMode()
+ != JFileChooser.FILES_ONLY)
setFileName(file.getName());
int index = -1;
index = getModel().indexOf(file);
@@ -439,7 +441,7 @@
filechooser.revalidate();
filechooser.repaint();
}
- };
+ }
/**
* A combo box model containing the selected directory and all its parent
@@ -567,10 +569,17 @@
extends DefaultListCellRenderer
{
/**
+ * This is the icon that is displayed in the combobox. This wraps
+ * the standard icon and adds indendation.
+ */
+ private IndentIcon indentIcon;
+
+ /**
* Creates a new renderer.
*/
public DirectoryComboBoxRenderer(JFileChooser fc)
{
+ indentIcon = new IndentIcon();
}
/**
@@ -586,28 +595,83 @@
* @return The list cell renderer.
*/
public Component getListCellRendererComponent(JList list, Object value,
- int index, boolean isSelected, boolean cellHasFocus)
+ int index,
+ boolean isSelected,
+ boolean cellHasFocus)
{
- FileView fileView = getFileView(getFileChooser());
+ super.getListCellRendererComponent(list, value, index, isSelected,
+ cellHasFocus);
File file = (File) value;
- setIcon(fileView.getIcon(file));
- setText(fileView.getName(file));
+ setText(getFileChooser().getName(file));
- if (isSelected)
+ // Install indented icon.
+ Icon icon = getFileChooser().getIcon(file);
+ indentIcon.setIcon(icon);
+ int depth = directoryModel.getDepth(index);
+ indentIcon.setDepth(depth);
+ setIcon(indentIcon);
+
+ return this;
+ }
+ }
+
+ /**
+ * An icon that wraps another icon and adds indentation.
+ */
+ class IndentIcon
+ implements Icon
{
- setBackground(list.getSelectionBackground());
- setForeground(list.getSelectionForeground());
+
+ /**
+ * The indentation level.
+ */
+ private static final int INDENT = 10;
+
+ /**
+ * The wrapped icon.
+ */
+ private Icon icon;
+
+ /**
+ * The current depth.
+ */
+ private int depth;
+
+ /**
+ * Sets the icon to be wrapped.
+ *
+ * @param i the icon
+ */
+ void setIcon(Icon i)
+ {
+ icon = i;
}
- else
+
+ /**
+ * Sets the indentation depth.
+ *
+ * @param d the depth to set
+ */
+ void setDepth(int d)
{
- setBackground(list.getBackground());
- setForeground(list.getForeground());
+ depth = d;
}
- setEnabled(list.isEnabled());
- setFont(list.getFont());
- return this;
+ public int getIconHeight()
+ {
+ return icon.getIconHeight();
}
+
+ public int getIconWidth()
+ {
+ return icon.getIconWidth() + depth * INDENT;
+ }
+
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ icon.paintIcon(c, g, x + depth * INDENT, y);
+ }
+
}
/**
@@ -956,9 +1020,12 @@
{
String text = editField.getText();
if (text != null && text != "" && !text.equals(fc.getName(editFile)))
- if (editFile.renameTo(fc.getFileSystemView().createFileObject(
- fc.getCurrentDirectory(), text)))
+ {
+ File f = fc.getFileSystemView().
+ createFileObject(fc.getCurrentDirectory(), text);
+ if ( editFile.renameTo(f) )
rescanCurrentDirectory(fc);
+ }
list.remove(editField);
}
startEditing = false;
@@ -982,17 +1049,8 @@
*/
public void actionPerformed(ActionEvent e)
{
- if (e.getActionCommand().equals("notify-field-accept"))
+ if (editField != null)
completeEditing();
- else if (editField != null)
- {
- list.remove(editField);
- startEditing = false;
- editFile = null;
- lastSelected = null;
- editField = null;
- list.repaint();
- }
}
}
}
@@ -1101,7 +1159,7 @@
lastSelected = selVal;
if (f.isFile())
setFileName(path.substring(path.lastIndexOf("/") + 1));
- else if (fc.getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY)
+ else if (fc.getFileSelectionMode() != JFileChooser.FILES_ONLY)
setFileName(path);
}
fileTable.repaint();
@@ -1171,16 +1229,8 @@
*/
public void actionPerformed(ActionEvent e)
{
- if (e.getActionCommand().equals("notify-field-accept"))
+ if (editField != null)
completeEditing();
- else if (editField != null)
- {
- table.remove(editField);
- startEditing = false;
- editFile = null;
- editField = null;
- table.repaint();
- }
}
}
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalIconFactory.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalIconFactory.java 2007-02-04 09:46:03 UTC (rev 3106)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalIconFactory.java 2007-02-04 10:20:16 UTC (rev 3107)
@@ -1039,21 +1039,23 @@
g.drawLine(x + 6, y + 14, x, y + 8);
g.drawLine(x, y + 7, x, y + 1);
- // Fill the icon.
- if (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme
- && enabled)
+// The following is commented out until the masking for the gradient painting
+// is working correctly
+// // Fill the icon.
+// if (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme
+// && enabled)
+// {
+// String gradient;
+// if (focus)
+// gradient = "Slider.focusGradient";
+// else
+// gradient = "Slider.gradient";
+// MetalUtils.paintGradient(g, x + 1, y + 2, 12, 13,
+// SwingConstants.VERTICAL, gradient,
+// gradientMask);
+// }
+// else
{
- String gradient;
- if (focus)
- gradient = "Slider.focusGradient";
- else
- gradient = "Slider.gradient";
- MetalUtils.paintGradient(g, x + 1, y + 2, 12, 13,
- SwingConstants.VERTICAL, gradient,
- gradientMask);
- }
- else
- {
if (focus)
g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
else
@@ -1700,21 +1702,23 @@
g.drawLine(x + 8, y + 14, x + 1, y + 14);
g.drawLine(x, y + 13, x, y + 1);
- // Fill the icon.
- if (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme
- && enabled)
+// The following is commented out until the masking for the gradient painting
+// is working correctly
+// // Fill the icon.
+// if (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme
+// && enabled)
+// {
+// String gradient;
+// if (focus)
+// gradient = "Slider.focusGradient";
+// else
+// gradient = "Slider.gradient";
+// MetalUtils.paintGradient(g, x + 2, y + 1, 13, 12,
+// SwingConstants.HORIZONTAL, gradient,
+// gradientMask);
+// }
+// else
{
- String gradient;
- if (focus)
- gradient = "Slider.focusGradient";
- else
- gradient = "Slider.gradient";
- MetalUtils.paintGradient(g, x + 2, y + 1, 13, 12,
- SwingConstants.HORIZONTAL, gradient,
- gradientMask);
- }
- else
- {
if (focus)
g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
else
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalRadioButtonUI.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalRadioButtonUI.java 2007-02-04 09:46:03 UTC (rev 3106)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalRadioButtonUI.java 2007-02-04 10:20:16 UTC (rev 3107)
@@ -177,7 +177,7 @@
protected void paintFocus(Graphics g, Rectangle t, Dimension d)
{
g.setColor(focusColor);
- g.drawRect(t.x - 1, t.y - 1, t.width + 2, t.height + 2);
+ g.drawRect(t.x - 1, t.y - 1, t.width + 1, t.height + 1);
}
}
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalScrollBarUI.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalScrollBarUI.java 2007-02-04 09:46:03 UTC (rev 3106)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalScrollBarUI.java 2007-02-04 10:20:16 UTC (rev 3107)
@@ -1,5 +1,5 @@
/* MetalScrollBarUI.java
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -169,6 +169,7 @@
Boolean prop = (Boolean) scrollbar.getClientProperty(FREE_STANDING_PROP);
isFreeStanding = prop == null ? true : prop.booleanValue();
scrollBarShadowColor = UIManager.getColor("ScrollBar.shadow");
+ scrollBarWidth = UIManager.getInt("ScrollBar.width");
super.installDefaults();
}
@@ -187,7 +188,10 @@
/**
* Creates a new button to use as the control at the lower end of the
- * {@link JScrollBar}.
+ * {@link JScrollBar}. This method assigns the new button (an instance of
+ * {@link MetalScrollButton} to the {@link #decreaseButton} field, and also
+ * returns the button. The button width is determined by the
+ * <code>ScrollBar.width</code> setting in the UI defaults.
*
* @param orientation the orientation of the button ({@link #NORTH},
* {@link #SOUTH}, {@link #EAST} or {@link #WEST}).
@@ -196,7 +200,6 @@
*/
protected JButton createDecreaseButton(int orientation)
{
- scrollBarWidth = UIManager.getInt("ScrollBar.width");
decreaseButton = new MetalScrollButton(orientation, scrollBarWidth,
isFreeStanding);
return decreaseButton;
@@ -204,7 +207,10 @@
/**
* Creates a new button to use as the control at the upper end of the
- * {@link JScrollBar}.
+ * {@link JScrollBar}. This method assigns the new button (an instance of
+ * {@link MetalScrollButton} to the {@link #increaseButton} field, and also
+ * returns the button. The button width is determined by the
+ * <code>ScrollBar.width</code> setting in the UI defaults.
*
* @param orientation the orientation of the button ({@link #NORTH},
* {@link #SOUTH}, {@link #EAST} or {@link #WEST}).
@@ -213,7 +219,6 @@
*/
protected JButton createIncreaseButton(int orientation)
{
- scrollBarWidth = UIManager.getInt("ScrollBar.width");
increaseButton = new MetalScrollButton(orientation, scrollBarWidth,
isFreeStanding);
return increaseButton;
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalSliderUI.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalSliderUI.java 2007-02-04 09:46:03 UTC (rev 3106)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalSliderUI.java 2007-02-04 10:20:16 UTC (rev 3107)
@@ -352,7 +352,10 @@
*/
public int getTickLength()
{
- return tickLength + TICK_BUFFER;
+ int len = tickLength + TICK_BUFFER + 1;
+ if (slider.getOrientation() == JSlider.VERTICAL)
+ len += 2;
+ return len;
}
/**
@@ -406,9 +409,9 @@
// Note the incoming 'g' has a translation in place to get us to the
// start of the tick rect already...
if (slider.isEnabled())
- g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
+ g.setColor(slider.getForeground());
else
- g.setColor(MetalLookAndFeel.getControlDisabled());
+ g.setColor(MetalLookAndFeel.getControlShadow());
g.drawLine(x, TICK_BUFFER, x, TICK_BUFFER + tickLength / 2);
}
@@ -425,10 +428,10 @@
// Note the incoming 'g' has a translation in place to get us to the
// start of the tick rect already...
if (slider.isEnabled())
- g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
+ g.setColor(slider.getForeground());
else
- g.setColor(MetalLookAndFeel.getControlDisabled());
- g.drawLine(x, TICK_BUFFER, x, TICK_BUFFER + tickLength);
+ g.setColor(MetalLookAndFeel.getControlShadow());
+ g.drawLine(x, TICK_BUFFER, x, TICK_BUFFER + tickLength - 1);
}
/**
@@ -444,10 +447,10 @@
// Note the incoming 'g' has a translation in place to get us to the
// start of the tick rect already...
if (slider.isEnabled())
- g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
+ g.setColor(slider.getForeground());
else
- g.setColor(MetalLookAndFeel.getControlDisabled());
- g.drawLine(TICK_BUFFER - 1, y, TICK_BUFFER - 1 + tickLength / 2, y);
+ g.setColor(MetalLookAndFeel.getControlShadow());
+ g.drawLine(TICK_BUFFER, y, TICK_BUFFER + tickLength / 2, y);
}
/**
@@ -463,10 +466,10 @@
// Note the incoming 'g' has a translation in place to get us to the
// start of the tick rect already...
if (slider.isEnabled())
- g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
+ g.setColor(slider.getForeground());
else
- g.setColor(MetalLookAndFeel.getControlDisabled());
- g.drawLine(TICK_BUFFER - 1, y, TICK_BUFFER - 1 + tickLength, y);
+ g.setColor(MetalLookAndFeel.getControlShadow());
+ g.drawLine(TICK_BUFFER, y, TICK_BUFFER + tickLength, y);
}
}
Modified: trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalUtils.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalUtils.java 2007-02-04 09:46:03 UTC (rev 3106)
+++ trunk/core/src/classpath/javax/javax/swing/plaf/metal/MetalUtils.java 2007-02-04 10:20:16 UTC (rev 3107)
@@ -41,6 +41,7 @@
import java.awt.Color;
import java.awt.Component;
+import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.TexturePaint;
@@ -108,7 +109,7 @@
for (int mX = x + xOff; mX < (x + w); mX += 4)
{
- g.drawLine(mX, mY, mX, mY);
+ g.fillRect(mX, mY, 1, 1);
}
// increase x offset
@@ -341,7 +342,7 @@
y0 = mask[xc - x0][0] + y;
y1 = mask[xc - x0][1] + y;
}
- g.drawLine(xc, y0, xc, y1);
+ g.fillRect(xc, y0, 1, y1 - y0);
}
// Paint solid c2 area.
g.setColor(c2);
@@ -355,7 +356,7 @@
{
y0 = mask[xc - x0][0] + y;
y1 = mask[xc - x0][1] + y;
- g.drawLine(xc, y0, xc, y1);
+ g.fillRect(xc, y0, 1, y1 - y0);
}
}
@@ -379,7 +380,7 @@
y0 = mask[xc - x0][0] + y;
y1 = mask[xc - x0][1] + y;
}
- g.drawLine(xc, y0, xc, y1);
+ g.fillRect(xc, y0, 1, y1 - y0);
}
// Paint third gradient area (c1->c3).
@@ -423,7 +424,7 @@
* described above
*/
static void paintVerticalGradient(Graphics g, int x, int y, int w, int h,
- double g1, double g2, Color c1, Color c2,
+ float g1, float g2, Color c1, Color c2,
Color c3, int[][] mask)
{
// Calculate the coordinates.
@@ -460,7 +461,7 @@
x0 = mask[yc - y0][0] + x;
x1 = mask[yc - y0][1] + x;
}
- g.drawLine(x0, yc, x1, yc);
+ g.fillRect(x0, yc, x1 - x0, 1);
}
// Paint solid c2 area.
g.setColor(c2);
@@ -474,7 +475,7 @@
{
x0 = mask[yc - y0][0] + x;
x1 = mask[yc - y0][1] + x;
- g.drawLine(x0, yc, x1, yc);
+ g.fillRect(x0, yc, x1 - x0, 1);
}
}
@@ -498,7 +499,7 @@
x0 = mask[yc - y0][0] + x;
x1 = mask[yc - y0][1] + x;
}
- g.drawLine(x0, yc, x1, yc);
+ g.fillRect(x0, yc, x1 - x0, 1);
}
// Paint third gradient area (c1->c3).
@@ -521,7 +522,61 @@
x0 = mask[yc - y0][0] + x;
x1 = mask[yc - y0][1] + x;
}
- g.drawLine(x0, yc, x1, yc);
+ g.fillRect(x0, yc, x1 - x0, 1);
}
}
+
+ /**
+ * Paints a horizontal gradient using Graphics2D functionality.
+ *
+ * @param g the Graphics2D instance
+ * @param x the X coordinate of the upper left corner of the rectangle
+ * @param y the Y coordinate of the upper left corner of the rectangle
+ * @param w the width of the rectangle
+ * @param h the height of the rectangle
+ * @param g1 the relative width of the c1->c2 gradients
+ * @param g2 the relative width of the c2 solid area
+ * @param c1 the color 1
+ * @param c2 the color 2
+ * @param c3 the color 3
+ * @param mask the mask that should be used when painting the gradient as
+ * described above
+ */
+ private static void paintHorizontalGradient2D(Graphics2D g, int x, int y,
+ int w, int h, float g1,
+ float g2, Color c1,
+ Color c2, Color c3,
+ int[][] mask)
+ {
+ // FIXME: Handle the mask somehow, or do Graphics2D clipping instead.
+ GradientPaint p1 = new GradientPaint(x, y, c1, x + w * g1, y, c2);
+ g.setPaint(p1);
+ // This fills the first gradient and the solid area in one go.
+ g.fillRect(x, y, (int) (w * (g1 + g2)), h);
+
+ GradientPaint p2 = new GradientPaint(x + (w * (g1 + g2)), y, c2, x + w, y,
+ c3);
+ g.setPaint(p2);
+ g.fillRect((int) (x + (w * (g1 + g2))), y,
+ (int) (w * (1. - (g1 + g2))), h);
}
+
+ private static void paintVerticalGradient2D(Graphics2D g, int x, int y,
+ int w, int h, float g1,
+ float g2, Color c1,
+ Color c2, Color c3,
+ int[][] mask)
+ {
+ // FIXME: Handle the mask somehow, or do Graphics2D clipping instead.
+ GradientPaint p1 = new GradientPaint(x, y, c1, x, y + h * g1, c2);
+ g.setPaint(p1);
+ // This fills the first gradient and the solid area in one go.
+ g.fillRect(x, y, w, (int) (h * (g1 + g2)));
+
+ GradientPaint p2 = new GradientPaint(x, y + (h * (g1 + g2)), c2, x, y + h,
+ c3);
+ g.setPaint(p2);
+ g.fillRect(x, (int) (y + (h * (g1 + g2))), w,
+ (int) (h * (1. - (g1 + g2))));
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-04 09:46:30
|
Revision: 3106
http://jnode.svn.sourceforge.net/jnode/?rev=3106&view=rev
Author: lsantha
Date: 2007-02-04 01:46:03 -0800 (Sun, 04 Feb 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/javax/javax/swing/JComponent.java
trunk/core/src/classpath/javax/javax/swing/JDialog.java
trunk/core/src/classpath/javax/javax/swing/JFrame.java
trunk/core/src/classpath/javax/javax/swing/JInternalFrame.java
trunk/core/src/classpath/javax/javax/swing/JLabel.java
trunk/core/src/classpath/javax/javax/swing/JLayeredPane.java
trunk/core/src/classpath/javax/javax/swing/JMenuItem.java
trunk/core/src/classpath/javax/javax/swing/JScrollBar.java
trunk/core/src/classpath/javax/javax/swing/JSlider.java
trunk/core/src/classpath/javax/javax/swing/JSplitPane.java
trunk/core/src/classpath/javax/javax/swing/JTable.java
trunk/core/src/classpath/javax/javax/swing/JTree.java
trunk/core/src/classpath/javax/javax/swing/JViewport.java
trunk/core/src/classpath/javax/javax/swing/RepaintManager.java
trunk/core/src/classpath/javax/javax/swing/UIManager.java
Modified: trunk/core/src/classpath/javax/javax/swing/JComponent.java
===================================================================
--- trunk/core/src/classpath/javax/javax/swing/JComponent.java 2007-02-03 20:57:41 UTC (rev 3105)
+++ trunk/core/src/classpath/javax/javax/swing/JComponent.java 2007-02-04 09:46:03 UTC (rev 3106)
@@ -48,12 +48,10 @@
import java.awt.FocusTraversalPolicy;
import java.awt.Font;
import java.awt.Graphics;
-import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
-import java.awt.Shape;
import java.awt.Window;
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
@@ -69,6 +67,7 @@
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
+import java.beans.VetoableChangeSupport;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.EventListener;
@@ -506,27 +505,6 @@
}
/**
- * An explicit value for the component's preferred size; if not set by a
- * user, this is calculated on the fly by delegating to the {@link
- * ComponentUI#getPreferredSize} method on the {@link #ui} property.
- */
- Dimension preferredSize;
-
- /**
- * An explicit value for the component's minimum size; if not set by a
- * user, this is calculated on the fly by delegating to the {@link
- * ComponentUI#getMinimumSize} method on the {@link #ui} property.
- */
- Dimension minimumSize;
-
- /**
- * An explicit value for the component's maximum size; if not set by a
- * user, this is calculated on the fly by delegating to the {@link
- * ComponentUI#getMaximumSize} method on the {@link #ui} property.
- */
- Dimension maximumSize;
-
- /**
* A value between 0.0 and 1.0 indicating the preferred horizontal
* alignment of the component, relative to its siblings. The values
* {@link #LEFT_ALIGNMENT}, {@link #CENTER_ALIGNMENT}, and {@link
@@ -564,12 +542,19 @@
Border border;
/**
- * The text to show in the tooltip associated with this component.
+ * The popup menu for the component.
*
- * @see #setToolTipText
- * @see #getToolTipText()
+ * @see #getComponentPopupMenu()
+ * @see #setComponentPopupMenu(JPopupMenu)
*/
- String toolTipText;
+ JPopupMenu componentPopupMenu;
+
+ /**
+ * A flag that controls whether the {@link #getComponentPopupMenu()} method
+ * looks to the component's parent when the <code>componentPopupMenu</code>
+ * field is <code>null</code>.
+ */
+ boolean inheritsPopupMenu;
/**
* <p>Whether to double buffer this component when painting. This flag
@@ -668,9 +653,15 @@
* Indicates whether the current paint call is already double buffered or
* not.
*/
- static boolean isPaintingDoubleBuffered = false;
+ static boolean paintingDoubleBuffered = false;
/**
+ * Indicates whether we are calling paintDoubleBuffered() from
+ * paintImmadiately (RepaintManager) or from paint() (AWT refresh).
+ */
+ static boolean isRepainting = false;
+
+ /**
* Listeners for events other than {@link PropertyChangeEvent} are
* handled by this listener list. PropertyChangeEvents are handled in
* {@link #changeSupport}.
@@ -678,6 +669,11 @@
protected EventListenerList listenerList = new EventListenerList();
/**
+ * Handles VetoableChangeEvents.
+ */
+ private VetoableChangeSupport vetoableChangeSupport;
+
+ /**
* Storage for "client properties", which are key/value pairs associated
* with this component by a "client", such as a user application or a
* layout manager. This is lazily constructed when the component gets its
@@ -690,7 +686,7 @@
private ComponentInputMap inputMap_whenInFocusedWindow;
private ActionMap actionMap;
/** @since 1.3 */
- private boolean verifyInputWhenFocusTarget;
+ private boolean verifyInputWhenFocusTarget = true;
private InputVerifier inputVerifier;
private TransferHandler transferHandler;
@@ -759,7 +755,14 @@
*/
public static final int WHEN_IN_FOCUSED_WINDOW = 2;
+
/**
+ * Used to optimize painting. This is set in paintImmediately2() to specify
+ * the exact component path to be painted by paintChildren.
+ */
+ Component paintChild;
+
+ /**
* Indicates if the opaque property has been set by a client program or by
* the UI.
*
@@ -784,7 +787,7 @@
{
super();
setDropTarget(new DropTarget());
- defaultLocale = Locale.getDefault();
+ setLocale(getDefaultLocale());
debugGraphicsOptions = DebugGraphics.NONE_OPTION;
setRequestFocusEnabled(true);
}
@@ -844,6 +847,11 @@
t.put(key, value);
else
t.remove(key);
+
+ // When both old and new value are null, no event is fired. This is
+ // different from what firePropertyChange() normally does, so we add this
+ // check here.
+ if (old != null || value != null)
firePropertyChange(key.toString(), old, value);
}
@@ -868,7 +876,8 @@
*/
public void removeVetoableChangeListener(VetoableChangeListener listener)
{
- listenerList.remove(VetoableChangeListener.class, listener);
+ if (vetoableChangeSupport != null)
+ vetoableChangeSupport.removeVetoableChangeListener(listener);
}
/**
@@ -884,23 +893,6 @@
}
/**
- * Register a <code>PropertyChangeListener</code> for a specific, named
- * property. To listen to all property changes, regardless of name, use
- * {@link #addPropertyChangeListener(PropertyChangeListener)} instead.
- *
- * @param propertyName The property name to listen to
- * @param listener The listener to register
- *
- * @see #removePropertyChangeListener(String, PropertyChangeListener)
- * @see #changeSupport
- */
- public void addPropertyChangeListener(String propertyName,
- PropertyChangeListener listener)
- {
- listenerList.add(PropertyChangeListener.class, listener);
- }
-
- /**
* Register a <code>VetoableChangeListener</code>.
*
* @param listener The listener to register
@@ -910,7 +902,10 @@
*/
public void addVetoableChangeListener(VetoableChangeListener listener)
{
- listenerList.add(VetoableChangeListener.class, listener);
+ // Lazily instantiate this, it's rarely needed.
+ if (vetoableChangeSupport == null)
+ vetoableChangeSupport = new VetoableChangeSupport(this);
+ vetoableChangeSupport.addVetoableChangeListener(listener);
}
/**
@@ -932,10 +927,12 @@
*
* @since 1.3
*/
- public EventListener[] getListeners(Class listenerType)
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
{
if (listenerType == PropertyChangeListener.class)
- return getPropertyChangeListeners();
+ return (T[]) getPropertyChangeListeners();
+ else if (listenerType == VetoableChangeListener.class)
+ return (T[]) getVetoableChangeListeners();
else
return listenerList.getListeners(listenerType);
}
@@ -954,60 +951,19 @@
/**
* Return all registered <code>VetoableChangeListener</code> objects.
*
- * @return The set of <code>VetoableChangeListener</code> objects in {@link
- * #listenerList}
+ * @return An array of the <code>VetoableChangeListener</code> objects
+ * registered with this component (possibly empty but never
+ * <code>null</code>).
+ *
+ * @since 1.4
*/
public VetoableChangeListener[] getVetoableChangeListeners()
{
- return (VetoableChangeListener[]) getListeners(VetoableChangeListener.class);
+ return vetoableChangeSupport == null ? new VetoableChangeListener[0]
+ : vetoableChangeSupport.getVetoableChangeListeners();
}
/**
- * A variant of {@link #firePropertyChange(String,Object,Object)}
- * for properties with <code>boolean</code> values.
- *
- * @specnote It seems that in JDK1.5 all property related methods have been
- * moved to java.awt.Component, except this and 2 others. We call
- * super here. I guess this will also be removed in one of the next
- * releases.
- */
- public void firePropertyChange(String propertyName, boolean oldValue,
- boolean newValue)
- {
- super.firePropertyChange(propertyName, oldValue, newValue);
- }
-
- /**
- * A variant of {@link #firePropertyChange(String,Object,Object)}
- * for properties with <code>char</code> values.
- *
- * @specnote It seems that in JDK1.5 all property related methods have been
- * moved to java.awt.Component, except this and 2 others. We call
- * super here. I guess this will also be removed in one of the next
- * releases.
- */
- public void firePropertyChange(String propertyName, char oldValue,
- char newValue)
- {
- super.firePropertyChange(propertyName, oldValue, newValue);
- }
-
- /**
- * A variant of {@link #firePropertyChange(String,Object,Object)}
- * for properties with <code>int</code> values.
- *
- * @specnote It seems that in JDK1.5 all property related methods have been
- * moved to java.awt.Component, except this and 2 others. We call
- * super here. I guess this will also be removed in one of the next
- * releases.
- */
- public void firePropertyChange(String propertyName, int oldValue,
- int newValue)
- {
- super.firePropertyChange(propertyName, oldValue, newValue);
- }
-
- /**
* Call {@link VetoableChangeListener#vetoableChange} on all listeners
* registered to listen to a given property. Any method which changes
* the specified property of this component should call this method.
@@ -1025,14 +981,45 @@
Object newValue)
throws PropertyVetoException
{
- VetoableChangeListener[] listeners = getVetoableChangeListeners();
+ if (vetoableChangeSupport != null)
+ vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue);
+ }
- PropertyChangeEvent evt =
- new PropertyChangeEvent(this, propertyName, oldValue, newValue);
- for (int i = 0; i < listeners.length; i++)
- listeners[i].vetoableChange(evt);
+ /**
+ * Fires a property change for a primitive integer property.
+ *
+ * @param property the name of the property
+ * @param oldValue the old value of the property
+ * @param newValue the new value of the property
+ *
+ * @specnote This method is implemented in
+ * {@link Component#firePropertyChange(String, int, int)}. It is
+ * only here because it is specified to be public, whereas the
+ * Component method is protected.
+ */
+ public void firePropertyChange(String property, int oldValue, int newValue)
+ {
+ super.firePropertyChange(property, oldValue, newValue);
}
+
+ /**
+ * Fires a property change for a primitive boolean property.
+ *
+ * @param property the name of the property
+ * @param oldValue the old value of the property
+ * @param newValue the new value of the property
+ *
+ * @specnote This method is implemented in
+ * {@link Component#firePropertyChange(String, boolean, boolean)}.
+ * It is only here because it is specified to be public, whereas
+ * the Component method is protected.
+ */
+ public void firePropertyChange(String property, boolean oldValue,
+ boolean newValue)
+ {
+ super.firePropertyChange(property, oldValue, newValue);
+ }
/**
* Get the value of the accessibleContext property for this component.
@@ -1252,37 +1239,38 @@
}
/**
- * Get the component's maximum size. If the {@link #maximumSize} property
- * has been explicitly set, it is returned. If the {@link #maximumSize}
+ * Get the component's maximum size. If the <code>maximumSize</code> property
+ * has been explicitly set, it is returned. If the <code>maximumSize</code>
* property has not been set but the {@link #ui} property has been, the
* result of {@link ComponentUI#getMaximumSize} is returned. If neither
* property has been set, the result of {@link Container#getMaximumSize}
* is returned.
*
- * @return The maximum size of the component
+ * @return the maximum size of the component
*
- * @see #maximumSize
- * @see #setMaximumSize
+ * @see Component#setMaximumSize
+ * @see Component#getMaximumSize()
+ * @see Component#isMaximumSizeSet()
+ * @see ComponentUI#getMaximumSize(JComponent)
*/
public Dimension getMaximumSize()
{
- if (maximumSize != null)
- return maximumSize;
-
- if (ui != null)
+ Dimension size = null;
+ if (isMaximumSizeSet())
+ size = super.getMaximumSize();
+ else
{
- Dimension s = ui.getMaximumSize(this);
- if (s != null)
- return s;
+ if (ui != null)
+ size = ui.getMaximumSize(this);
+ if (size == null)
+ size = super.getMaximumSize();
}
-
- Dimension p = super.getMaximumSize();
- return p;
+ return size;
}
/**
- * Get the component's minimum size. If the {@link #minimumSize} property
- * has been explicitly set, it is returned. If the {@link #minimumSize}
+ * Get the component's minimum size. If the <code>minimumSize</code> property
+ * has been explicitly set, it is returned. If the <code>minimumSize</code>
* property has not been set but the {@link #ui} property has been, the
* result of {@link ComponentUI#getMinimumSize} is returned. If neither
* property has been set, the result of {@link Container#getMinimumSize}
@@ -1290,95 +1278,55 @@
*
* @return The minimum size of the component
*
- * @see #minimumSize
- * @see #setMinimumSize
+ * @see Component#setMinimumSize
+ * @see Component#getMinimumSize()
+ * @see Component#isMinimumSizeSet()
+ * @see ComponentUI#getMinimumSize(JComponent)
*/
public Dimension getMinimumSize()
{
- if (minimumSize != null)
- return minimumSize;
-
- if (ui != null)
+ Dimension size = null;
+ if (isMinimumSizeSet())
+ size = super.getMinimumSize();
+ else
{
- Dimension s = ui.getMinimumSize(this);
- if (s != null)
- return s;
+ if (ui != null)
+ size = ui.getMinimumSize(this);
+ if (size == null)
+ size = super.getMinimumSize();
}
-
- Dimension p = super.getMinimumSize();
- return p;
+ return size;
}
/**
- * Get the component's preferred size. If the {@link #preferredSize}
- * property has been explicitly set, it is returned. If the {@link
- * #preferredSize} property has not been set but the {@link #ui} property
- * has been, the result of {@link ComponentUI#getPreferredSize} is
+ * Get the component's preferred size. If the <code>preferredSize</code>
+ * property has been explicitly set, it is returned. If the
+ * <code>preferredSize</code> property has not been set but the {@link #ui}
+ * property has been, the result of {@link ComponentUI#getPreferredSize} is
* returned. If neither property has been set, the result of {@link
* Container#getPreferredSize} is returned.
*
* @return The preferred size of the component
*
- * @see #preferredSize
- * @see #setPreferredSize
+ * @see Component#setPreferredSize
+ * @see Component#getPreferredSize()
+ * @see Component#isPreferredSizeSet()
+ * @see ComponentUI#getPreferredSize(JComponent)
*/
public Dimension getPreferredSize()
{
- Dimension prefSize = null;
- if (preferredSize != null)
- prefSize = new Dimension(preferredSize);
-
- else if (ui != null)
- {
- Dimension s = ui.getPreferredSize(this);
- if (s != null)
- prefSize = s;
- }
-
- if (prefSize == null)
- prefSize = super.getPreferredSize();
-
- return prefSize;
- }
-
- /**
- * Checks if a maximum size was explicitely set on the component.
- *
- * @return <code>true</code> if a maximum size was set,
- * <code>false</code> otherwise
- *
- * @since 1.3
- */
- public boolean isMaximumSizeSet()
+ Dimension size = null;
+ if (isPreferredSizeSet())
+ size = super.getPreferredSize();
+ else
{
- return maximumSize != null;
+ if (ui != null)
+ size = ui.getPreferredSize(this);
+ if (size == null)
+ size = super.getPreferredSize();
}
-
- /**
- * Checks if a minimum size was explicitely set on the component.
- *
- * @return <code>true</code> if a minimum size was set,
- * <code>false</code> otherwise
- *
- * @since 1.3
- */
- public boolean isMinimumSizeSet()
- {
- return minimumSize != null;
+ return size;
}
-
- /**
- * Checks if a preferred size was explicitely set on the component.
- *
- * @return <code>true</code> if a preferred size was set,
- * <code>false</code> otherwise
- *
- * @since 1.3
- */
- public boolean isPreferredSizeSet()
- {
- return preferredSize != null;
- }
/**
* Return the value of the <code>nextFocusableComponent</code> property.
@@ -1402,11 +1350,32 @@
* Return the set of {@link KeyStroke} objects which are registered
* to initiate actions on this component.
*
- * @return An array of the registered keystrokes
+ * @return An array of the registered keystrokes (possibly empty but never
+ * <code>null</code>).
*/
public KeyStroke[] getRegisteredKeyStrokes()
{
- return null;
+ KeyStroke[] ks0;
+ KeyStroke[] ks1;
+ KeyStroke[] ks2;
+ if (inputMap_whenFocused != null)
+ ks0 = inputMap_whenFocused.keys();
+ else
+ ks0 = new KeyStroke[0];
+ if (inputMap_whenAncestorOfFocused != null)
+ ks1 = inputMap_whenAncestorOfFocused.keys();
+ else
+ ks1 = new KeyStroke[0];
+ if (inputMap_whenInFocusedWindow != null)
+ ks2 = inputMap_whenInFocusedWindow.keys();
+ else
+ ks2 = new KeyStroke[0];
+ int count = ks0.length + ks1.length + ks2.length;
+ KeyStroke[] result = new KeyStroke[count];
+ System.arraycopy(ks0, 0, result, 0, ks0.length);
+ System.arraycopy(ks1, 0, result, ks0.length, ks1.length);
+ System.arraycopy(ks2, 0, result, ks0.length + ks1.length, ks2.length);
+ return result;
}
/**
@@ -1452,14 +1421,12 @@
{
JToolTip toolTip = new JToolTip();
toolTip.setComponent(this);
- toolTip.setTipText(toolTipText);
-
return toolTip;
}
/**
- * Return the location at which the {@link #toolTipText} property should be
- * displayed, when triggered by a particular mouse event.
+ * Return the location at which the <code>toolTipText</code> property should
+ * be displayed, when triggered by a particular mouse event.
*
* @param event The event the tooltip is being presented in response to
*
@@ -1472,53 +1439,56 @@
}
/**
- * Set the value of the {@link #toolTipText} property.
+ * Set the tooltip text for this component. If a non-<code>null</code>
+ * value is set, this component is registered in the
+ * <code>ToolTipManager</code> in order to turn on tooltips for this
+ * component. If a <code>null</code> value is set, tooltips are turne off
+ * for this component.
*
- * @param text The new property value
+ * @param text the tooltip text for this component
*
* @see #getToolTipText()
+ * @see #getToolTipText(MouseEvent)
*/
public void setToolTipText(String text)
{
+ String old = getToolTipText();
+ putClientProperty(TOOL_TIP_TEXT_KEY, text);
+ ToolTipManager ttm = ToolTipManager.sharedInstance();
if (text == null)
- {
- ToolTipManager.sharedInstance().unregisterComponent(this);
- toolTipText = null;
- return;
- }
-
- // XXX: The tip text doesn't get updated unless you set it to null
- // and then to something not-null. This is consistent with the behaviour
- // of Sun's ToolTipManager.
-
- String oldText = toolTipText;
- toolTipText = text;
-
- if (oldText == null)
- ToolTipManager.sharedInstance().registerComponent(this);
+ ttm.unregisterComponent(this);
+ else if (old == null)
+ ttm.registerComponent(this);
}
/**
- * Get the value of the {@link #toolTipText} property.
+ * Returns the current tooltip text for this component, or <code>null</code>
+ * if none has been set.
*
- * @return The current property value
+ * @return the current tooltip text for this component, or <code>null</code>
+ * if none has been set
*
* @see #setToolTipText
+ * @see #getToolTipText(MouseEvent)
*/
public String getToolTipText()
{
- return toolTipText;
+ return (String) getClientProperty(TOOL_TIP_TEXT_KEY);
}
/**
- * Get the value of the {@link #toolTipText} property, in response to a
- * particular mouse event.
+ * Returns the tooltip text for this component for a particular mouse
+ * event. This can be used to support context sensitive tooltips that can
+ * change with the mouse location. By default this returns the static
+ * tooltip text returned by {@link #getToolTipText()}.
*
- * @param event The mouse event which triggered the tooltip
+ * @param event the mouse event which triggered the tooltip
*
- * @return The current property value
+ * @return the tooltip text for this component for a particular mouse
+ * event
*
* @see #setToolTipText
+ * @see #getToolTipText()
*/
public String getToolTipText(MouseEvent event)
{
@@ -1526,6 +1496,88 @@
}
/**
+ * Returns the flag that controls whether or not the component inherits its
+ * parent's popup menu when no popup menu is specified for this component.
+ *
+ * @return A boolean.
+ *
+ * @since 1.5
+ *
+ * @see #setInheritsPopupMenu(boolean)
+ */
+ public boolean getInheritsPopupMenu()
+ {
+ return inheritsPopupMenu;
+ }
+
+ /**
+ * Sets the flag that controls whether or not the component inherits its
+ * parent's popup menu when no popup menu is specified for this component.
+ * This is a bound property with the property name 'inheritsPopupMenu'.
+ *
+ * @param inherit the new flag value.
+ *
+ * @since 1.5
+ *
+ * @see #getInheritsPopupMenu()
+ */
+ public void setInheritsPopupMenu(boolean inherit)
+ {
+ if (inheritsPopupMenu != inherit)
+ {
+ inheritsPopupMenu = inherit;
+ this.firePropertyChange("inheritsPopupMenu", ! inherit, inherit);
+ }
+ }
+
+ /**
+ * Returns the popup menu for this component. If the popup menu is
+ * <code>null</code> AND the {@link #getInheritsPopupMenu()} method returns
+ * <code>true</code>, this method will return the parent's popup menu (if it
+ * has one).
+ *
+ * @return The popup menu (possibly <code>null</code>.
+ *
+ * @since 1.5
+ *
+ * @see #setComponentPopupMenu(JPopupMenu)
+ * @see #getInheritsPopupMenu()
+ */
+ public JPopupMenu getComponentPopupMenu()
+ {
+ if (componentPopupMenu == null && getInheritsPopupMenu())
+ {
+ Container parent = getParent();
+ if (parent instanceof JComponent)
+ return ((JComponent) parent).getComponentPopupMenu();
+ else
+ return null;
+ }
+ else
+ return componentPopupMenu;
+ }
+
+ /**
+ * Sets the popup menu for this component (this is a bound property with
+ * the property name 'componentPopupMenu').
+ *
+ * @param popup the popup menu (<code>null</code> permitted).
+ *
+ * @since 1.5
+ *
+ * @see #getComponentPopupMenu()
+ */
+ public void setComponentPopupMenu(JPopupMenu popup)
+ {
+ if (componentPopupMenu != popup)
+ {
+ JPopupMenu old = componentPopupMenu;
+ componentPopupMenu = popup;
+ firePropertyChange("componentPopupMenu", old, popup);
+ }
+ }
+
+ /**
* Return the top level ancestral container (usually a {@link
* java.awt.Window} or {@link java.applet.Applet}) which this component is
* contained within, or <code>null</code> if no ancestors exist.
@@ -1725,11 +1777,11 @@
// buffer. When this method completes, the call stack unwinds back to
// paintDoubleBuffered, where the buffer contents is finally drawn to the
// screen.
- if (!isPaintingDoubleBuffered && isDoubleBuffered()
+ if (!paintingDoubleBuffered && isDoubleBuffered()
&& rm.isDoubleBufferingEnabled())
{
Rectangle clip = g.getClipBounds();
- paintDoubleBuffered(clip);
+ paintDoubleBuffered(clip.x, clip.y, clip.width, clip.height);
}
else
{
@@ -1744,8 +1796,22 @@
dragBuffer = null;
}
- if (g.getClip() == null)
- g.setClip(0, 0, getWidth(), getHeight());
+ Rectangle clip = g.getClipBounds();
+ int clipX, clipY, clipW, clipH;
+ if (clip == null)
+ {
+ clipX = 0;
+ clipY = 0;
+ clipW = getWidth();
+ clipH = getHeight();
+ }
+ else
+ {
+ clipX = clip.x;
+ clipY = clip.y;
+ clipW = clip.width;
+ clipH = clip.height;
+ }
if (dragBuffer != null && dragBufferInitialized)
{
g.drawImage(dragBuffer, 0, 0, this);
@@ -1753,14 +1819,51 @@
else
{
Graphics g2 = getComponentGraphics(g);
+ if (! isOccupiedByChild(clipX, clipY, clipW, clipH))
+ {
paintComponent(g2);
paintBorder(g2);
+ }
paintChildren(g2);
}
}
}
/**
+ * Determines if a region of this component is completely occupied by
+ * an opaque child component, in which case we don't need to bother
+ * painting this component at all.
+ *
+ * @param x the area, x coordinate
+ * @param y the area, y coordinate
+ * @param w the area, width
+ * @param h the area, height
+ *
+ * @return <code>true</code> if the specified area is completely covered
+ * by a child component, <code>false</code> otherwise
+ */
+ private boolean isOccupiedByChild(int x, int y, int w, int h)
+ {
+ boolean occupied = false;
+ int count = getComponentCount();
+ for (int i = 0; i < count; i++)
+ {
+ Component child = getComponent(i);
+ int cx = child.getX();
+ int cy = child.getY();
+ int cw = child.getWidth();
+ int ch = child.getHeight();
+ if (child.isVisible() && x >= cx && x + w <= cx + cw && y >= cy
+ && y + h <= cy + ch)
+ {
+ occupied = child.isOpaque();
+ break;
+ }
+ }
+ return occupied;
+ }
+
+ /**
* Initializes the drag buffer by creating a new image and painting this
* component into it.
*/
@@ -1816,235 +1919,122 @@
{
if (getComponentCount() > 0)
{
- if (isOptimizedDrawingEnabled())
- paintChildrenOptimized(g);
- else
- paintChildrenWithOverlap(g);
- }
- }
-
- /**
- * Paints the children of this JComponent in the case when the component
- * is not marked as optimizedDrawingEnabled, that means the container cannot
- * guarantee that it's children are tiled. For this case we must
- * perform a more complex optimization to determine the minimal rectangle
- * to be painted for each child component.
- *
- * @param g the graphics context to use
- */
- private void paintChildrenWithOverlap(Graphics g)
- {
- Shape originalClip = g.getClip();
- Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache);
- g.clipRect(inner.x, inner.y, inner.width, inner.height);
- Component[] children = getComponents();
-
- // Find the rectangles that need to be painted for each child component.
- // We push on this list arrays that have the Rectangles to be painted as
- // the first elements and the component to be painted as the last one.
- // Later we go through that list in reverse order and paint the rectangles.
- ArrayList paintRegions = new ArrayList(children.length);
- ArrayList paintRectangles = new ArrayList();
- ArrayList newPaintRects = new ArrayList();
- paintRectangles.add(g.getClipBounds());
- ArrayList componentRectangles = new ArrayList();
-
- // Go through children from top to bottom and find out their paint
- // rectangles.
- for (int index = 0; paintRectangles.size() > 0 &&
- index < children.length; index++)
- {
- Component comp = children[index];
- if (! comp.isVisible())
- continue;
-
- Rectangle compBounds = comp.getBounds();
- boolean isOpaque = comp instanceof JComponent
- && ((JComponent) comp).isOpaque();
-
- // Add all the current paint rectangles that intersect with the
- // component to the component's paint rectangle array.
- for (int i = paintRectangles.size() - 1; i >= 0; i--)
- {
- Rectangle r = (Rectangle) paintRectangles.get(i);
- if (r.intersects(compBounds))
+ // Need to lock the tree to avoid problems with AWT and concurrency.
+ synchronized (getTreeLock())
+ {
+ // Fast forward to the child to paint, if set by
+ // paintImmediately2()
+ int i = getComponentCount() - 1;
+ if (paintChild != null && paintChild.isOpaque())
{
- Rectangle compRect = r.intersection(compBounds);
- componentRectangles.add(compRect);
- // If the component is opaque, split up each paint rect and
- // add paintRect - compBounds to the newPaintRects array.
- if (isOpaque)
+ for (; i >= 0 && getComponent(i) != paintChild; i--)
+ ;
+ }
+ for (; i >= 0; i--)
+ {
+ Component child = getComponent(i);
+ if (child != null && child.isLightweight()
+ && child.isVisible())
{
- int x, y, w, h;
- Rectangle rect = new Rectangle();
-
- // The north retangle.
- x = Math.max(compBounds.x, r.x);
- y = r.y;
- w = Math.min(compBounds.width, r.width + r.x - x);
- h = compBounds.y - r.y;
- rect.setBounds(x, y, w, h);
- if (! rect.isEmpty())
+ int cx = child.getX();
+ int cy = child.getY();
+ int cw = child.getWidth();
+ int ch = child.getHeight();
+ if (g.hitClip(cx, cy, cw, ch))
{
- newPaintRects.add(rect);
- rect = new Rectangle();
- }
-
- // The south rectangle.
- x = Math.max(compBounds.x, r.x);
- y = compBounds.y + compBounds.height;
- w = Math.min(compBounds.width, r.width + r.x - x);
- h = r.height - (compBounds.y - r.y) - compBounds.height;
- rect.setBounds(x, y, w, h);
- if (! rect.isEmpty())
+ if ((! isOptimizedDrawingEnabled()) && i > 0)
+ {
+ // Check if the child is completely obscured.
+ Rectangle clip = g.getClipBounds(); // A copy.
+ SwingUtilities.computeIntersection(cx, cy, cw, ch,
+ clip);
+ if (isCompletelyObscured(i, clip.x, clip.y,
+ clip.width, clip.height))
+ continue; // Continues the for-loop.
+ }
+ Graphics cg = g.create(cx, cy, cw, ch);
+ cg.setColor(child.getForeground());
+ cg.setFont(child.getFont());
+ try
{
- newPaintRects.add(rect);
- rect = new Rectangle();
+ child.paint(cg);
}
-
- // The west rectangle.
- x = r.x;
- y = r.y;
- w = compBounds.x - r.x;
- h = r.height;
- rect.setBounds(x, y, w, h);
- if (! rect.isEmpty())
+ finally
{
- newPaintRects.add(rect);
- rect = new Rectangle();
+ cg.dispose();
}
-
- // The east rectangle.
- x = compBounds.x + compBounds.width;
- y = r.y;
- w = r.width - (compBounds.x - r.x) - compBounds.width;
- h = r.height;
- rect.setBounds(x, y, w, h);
- if (! rect.isEmpty())
- {
- newPaintRects.add(rect);
- }
}
- else
- {
- // Not opaque, need to reuse the current paint rectangles
- // for the next component.
- newPaintRects.add(r);
}
-
}
- else
- {
- newPaintRects.add(r);
- }
}
-
- // Replace the paintRectangles with the new split up
- // paintRectangles.
- paintRectangles.clear();
- paintRectangles.addAll(newPaintRects);
- newPaintRects.clear();
-
- // Store paint rectangles if there are any for the current component.
- int compRectsSize = componentRectangles.size();
- if (compRectsSize > 0)
- {
- componentRectangles.add(comp);
- paintRegions.add(componentRectangles);
- componentRectangles = new ArrayList();
}
}
- // paintingTile becomes true just before we start painting the component's
- // children.
- paintingTile = true;
-
- // We must go through the painting regions backwards, because the
- // topmost components have been added first, followed by the components
- // below.
- int prEndIndex = paintRegions.size() - 1;
- for (int i = prEndIndex; i >= 0; i--)
+ /**
+ * Determines if a region of a child component is completely obscured by one
+ * of its siblings.
+ *
+ * @param index the index of the child component
+ * @param x the region to check, x coordinate
+ * @param y the region to check, y coordinate
+ * @param w the region to check, width
+ * @param h the region to check, height
+ *
+ * @return <code>true</code> if the region is completely obscured by a
+ * sibling, <code>false</code> otherwise
+ */
+ private boolean isCompletelyObscured(int index, int x, int y, int w, int h)
{
- // paintingTile must be set to false before we begin to start painting
- // the last tile.
- if (i == 0)
- paintingTile = false;
-
- ArrayList paintingRects = (ArrayList) paintRegions.get(i);
- // The last element is always the component.
- Component c = (Component) paintingRects.get(paintingRects.size() - 1);
- int endIndex = paintingRects.size() - 2;
- for (int j = 0; j <= endIndex; j++)
+ boolean obscured = false;
+ for (int i = index - 1; i >= 0 && obscured == false; i--)
{
- Rectangle cBounds = c.getBounds();
- Rectangle bounds = (Rectangle) paintingRects.get(j);
- Rectangle oldClip = g.getClipBounds();
- if (oldClip == null)
- oldClip = bounds;
-
- boolean translated = false;
- try
+ Component sib = getComponent(i);
+ if (sib.isVisible())
{
- g.setClip(bounds);
- g.translate(cBounds.x, cBounds.y);
- translated = true;
- c.paint(g);
- }
- finally
+ Rectangle sibRect = sib.getBounds(rectCache);
+ if (sib.isOpaque() && x >= sibRect.x
+ && (x + w) <= (sibRect.x + sibRect.width)
+ && y >= sibRect.y
+ && (y + h) <= (sibRect.y + sibRect.height))
{
- if (translated)
- g.translate(-cBounds.x, -cBounds.y);
- g.setClip(oldClip);
+ obscured = true;
}
}
}
- g.setClip(originalClip);
+ return obscured;
}
/**
- * Paints the children of this container when it is marked as
- * optimizedDrawingEnabled. In this case the container can guarantee that
- * it's children are tiled, which allows for a much more efficient
- * algorithm to determine the minimum rectangles to be painted for
- * each child.
+ * Checks if a component/rectangle is partially obscured by one of its
+ * siblings.
+ * Note that this doesn't check for completely obscured, this is
+ * done by isCompletelyObscured() and should probably also be checked.
*
- * @param g the graphics context to use
+ * @param i the component index from which to start searching
+ * @param x the x coordinate of the rectangle to check
+ * @param y the y coordinate of the rectangle to check
+ * @param w the width of the rectangle to check
+ * @param h the height of the rectangle to check
+ *
+ * @return <code>true</code> if the rectangle is partially obscured
*/
- private void paintChildrenOptimized(Graphics g)
+ private boolean isPartiallyObscured(int i, int x, int y, int w, int h)
{
- Shape originalClip = g.getClip();
- Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache);
- g.clipRect(inner.x, inner.y, inner.width, inner.height);
- Component[] children = getComponents();
-
- // paintingTile becomes true just before we start painting the component's
- // children.
- paintingTile = true;
- for (int i = children.length - 1; i >= 0; i--) //children.length; i++)
+ boolean obscured = false;
+ for (int j = i - 1; j >= 0 && ! obscured; j--)
{
- // paintingTile must be set to false before we begin to start painting
- // the last tile.
- if (i == children.length - 1)
- paintingTile = false;
-
- if (!children[i].isVisible())
- continue;
-
- Rectangle bounds = children[i].getBounds(rectCache);
- Rectangle oldClip = g.getClipBounds();
- if (oldClip == null)
- oldClip = bounds;
-
- if (!g.hitClip(bounds.x, bounds.y, bounds.width, bounds.height))
- continue;
-
- boolean translated = false;
- Graphics g2 = g.create(bounds.x, bounds.y, bounds.width,
- bounds.height);
- children[i].paint(g2);
- g2.dispose();
+ Component sibl = getComponent(j);
+ if (sibl.isVisible())
+ {
+ Rectangle rect = sibl.getBounds(rectCache);
+ if (!(x + w <= rect.x)
+ || (y + h <= rect.y)
+ || (x >= rect.x + rect.width)
+ || (y >= rect.y + rect.height))
+ obscured = true;
+ }
}
- g.setClip(originalClip);
+ return obscured;
}
/**
@@ -2064,14 +2054,17 @@
{
if (ui != null)
{
- Graphics g2 = g;
- if (!(g instanceof Graphics2D))
- g2 = g.create();
+ Graphics g2 = g.create();
+ try
+ {
ui.update(g2, this);
- if (!(g instanceof Graphics2D))
+ }
+ finally
+ {
g2.dispose();
}
}
+ }
/**
* A variant of {@link #paintImmediately(Rectangle)} which takes
@@ -2084,7 +2077,26 @@
*/
public void paintImmediately(int x, int y, int w, int h)
{
- paintImmediately(new Rectangle(x, y, w, h));
+ // Find opaque parent and call paintImmediately2() on it.
+ if (isShowing())
+ {
+ Component c = this;
+ Component p;
+ while (c != null && ! c.isOpaque())
+ {
+ p = c.getParent();
+ if (p != null)
+ {
+ x += c.getX();
+ y += c.getY();
+ c = p;
+ }
+ }
+ if (c instanceof JComponent)
+ ((JComponent) c).paintImmediately2(x, y, w, h);
+ else
+ c.repaint(x, y, w, h);
+ }
}
/**
@@ -2107,102 +2119,267 @@
*/
public void paintImmediately(Rectangle r)
{
- // Try to find a root pane for this component.
- //Component root = findPaintRoot(r);
- Component root = findPaintRoot(r);
- // If no paint root is found, then this component is completely overlapped
- // by another component and we don't need repainting.
- if (root == null)
- return;
- if (root == null || !root.isShowing())
- return;
-
- Rectangle rootClip = SwingUtilities.convertRectangle(this, r, root);
- if (root instanceof JComponent)
- ((JComponent) root).paintImmediately2(rootClip);
- else
- root.repaint(rootClip.x, rootClip.y, rootClip.width, rootClip.height);
+ paintImmediately(r.x, r.y, r.width, r.height);
}
/**
* Performs the actual work of paintImmediatly on the repaint root.
*
- * @param r the area to be repainted
+ * @param x the area to be repainted, X coordinate
+ * @param y the area to be repainted, Y coordinate
*/
- void paintImmediately2(Rectangle r)
+ void paintImmediately2(int x, int y, int w, int h)
{
+ // Optimization for components that are always painted on top.
+ boolean onTop = onTop() && isOpaque();
+
+ // Fetch the RepaintManager.
RepaintManager rm = RepaintManager.currentManager(this);
- if (rm.isDoubleBufferingEnabled() && isDoubleBuffered())
- paintDoubleBuffered(r);
+
+ // The painting clip;
+ int paintX = x;
+ int paintY = y;
+ int paintW = w;
+ int paintH = h;
+
+ // If we should paint buffered or not.
+ boolean haveBuffer = false;
+
+ // The component that is finally triggered for painting.
+ JComponent paintRoot = this;
+
+ // Stores the component and all its parents. This will be used to limit
+ // the actually painted components in paintChildren by setting
+ // the field paintChild.
+ int pIndex = -1;
+ int pCount = 0;
+ ArrayList components = new ArrayList();
+
+ // Offset to subtract from the paintRoot rectangle when painting.
+ int offsX = 0;
+ int offsY = 0;
+
+ // The current component and its child.
+ Component child;
+ Container c;
+
+ // Find appropriate paint root.
+ for (c = this, child = null;
+ c != null && ! (c instanceof Window) && ! (c instanceof Applet);
+ child = c, c = c.getParent())
+ {
+ JComponent jc = c instanceof JComponent ? (JComponent) c : null;
+ components.add(c);
+ if (! onTop && jc != null && ! jc.isOptimizedDrawingEnabled())
+ {
+ // Indicates whether we reset the paint root to be the current
+ // component.
+ boolean updatePaintRoot = false;
+
+ // Check obscured state of the child.
+ // Generally, we have 3 cases here:
+ // 1. Not obscured. No need to paint from the parent.
+ // 2. Partially obscured. Paint from the parent.
+ // 3. Completely obscured. No need to paint anything.
+ if (c != this)
+ {
+ if (jc.isPaintRoot())
+ updatePaintRoot = true;
else
- paintSimple(r);
+ {
+ int count = c.getComponentCount();
+ int i = 0;
+ for (; i < count && c.getComponent(i) != child; i++)
+ ;
+
+ if (jc.isCompletelyObscured(i, paintX, paintY, paintW,
+ paintH))
+ return; // No need to paint anything.
+ else if (jc.isPartiallyObscured(i, paintX, paintY, paintW,
+ paintH))
+ updatePaintRoot = true;
+
+ }
+ }
+ if (updatePaintRoot)
+ {
+ // Paint from parent.
+ paintRoot = jc;
+ pIndex = pCount;
+ offsX = 0;
+ offsY = 0;
+ haveBuffer = false;
+ }
+ }
+ pCount++;
+ // Check if component is double buffered.
+ if (rm.isDoubleBufferingEnabled() && jc != null
+ && jc.isDoubleBuffered())
+ {
+ haveBuffer = true;
+ }
+
+ // Clip the paint region with the parent.
+ if (! onTop)
+ {
+ paintX = Math.max(0, paintX);
+ paintY = Math.max(0, paintY);
+ paintW = Math.min(c.getWidth(), paintW + paintX) - paintX;
+ paintH = Math.min(c.getHeight(), paintH + paintY) - paintY;
+ int dx = c.getX();
+ int dy = c.getY();
+ paintX += dx;
+ paintY += dy;
+ offsX += dx;
+ offsY += dy;
+ }
+ }
+ if (c != null && c.getPeer() != null && paintW > 0 && paintH > 0)
+ {
+ isRepainting = true;
+ paintX -= offsX;
+ paintY -= offsY;
+
+ // Set the painting path so that paintChildren paints only what we
+ // want.
+ if (paintRoot != this)
+ {
+ for (int i = pIndex; i > 0; i--)
+ {
+ Component paintParent = (Component) components.get(i);
+ if (paintParent instanceof JComponent)
+ ((JComponent) paintParent).paintChild =
+ (Component) components.get(i - 1);
+ }
+ }
+
+ // Actually trigger painting.
+ if (haveBuffer)
+ paintRoot.paintDoubleBuffered(paintX, paintY, paintW, paintH);
+ else
+ {
+ Graphics g = paintRoot.getGraphics();
+ try
+ {
+ g.setClip(paintX, paintY, paintW, paintH);
+ paintRoot.paint(g);
+ }
+ finally
+ {
+ g.dispose();
+ }
+ }
+
+ // Reset the painting path.
+ if (paintRoot != this)
+ {
+ for (int i = pIndex; i > 0; i--)
+ {
+ Component paintParent = (Component) components.get(i);
+ if (paintParent instanceof JComponent)
+ ((JComponent) paintParent).paintChild = null;
+ }
+ }
+
+ isRepainting = false;
+ }
}
/**
- * Gets the root of the component given. If a parent of the
- * component is an instance of Applet, then the applet is
- * returned. The applet is considered the root for painting
- * and adding/removing components. Otherwise, the root Window
- * is returned if it exists.
+ * Returns <code>true</code> if the component is guaranteed to be painted
+ * on top of others. This returns false by default and is overridden by
+ * components like JMenuItem, JPopupMenu and JToolTip to return true for
+ * added efficiency.
*
- * @param comp - The component to get the root for.
- * @return the parent root. An applet if it is a parent,
- * or the root window. If neither exist, null is returned.
+ * @return <code>true</code> if the component is guaranteed to be painted
+ * on top of others
*/
- private Component getRoot(Component comp)
+ boolean onTop()
{
- Applet app = null;
-
- while (comp != null)
- {
- if (app == null && comp instanceof Window)
- return comp;
- else if (comp instanceof Applet)
- app = (Applet) comp;
- comp = comp.getParent();
+ return false;
}
- return app;
+ /**
+ * This returns true when a component needs to force itself as a paint
+ * origin. This is used for example in JViewport to make sure that it
+ * gets to update its backbuffer.
+ *
+ * @return true when a component needs to force itself as a paint
+ * origin
+ */
+ boolean isPaintRoot()
+ {
+ return false;
}
/**
* Performs double buffered repainting.
*/
- private void paintDoubleBuffered(Rectangle r)
+ private void paintDoubleBuffered(int x, int y, int w, int h)
{
RepaintManager rm = RepaintManager.currentManager(this);
// Paint on the offscreen buffer.
- Component root = getRoot(this);
+ Component root = SwingUtilities.getRoot(this);
Image buffer = rm.getVolatileOffscreenBuffer(this, root.getWidth(),
root.getHeight());
+
// The volatile offscreen buffer may be null when that's not supported
// by the AWT backend. Fall back to normal backbuffer in this case.
if (buffer == null)
buffer = rm.getOffscreenBuffer(this, root.getWidth(), root.getHeight());
//Rectangle targetClip = SwingUtilities.convertRectangle(this, r, root);
- Point translation = SwingUtilities.convertPoint(this, 0, 0, root);
Graphics g2 = buffer.getGraphics();
- g2.translate(translation.x, translation.y);
- g2.setClip(r.x, r.y, r.width, r.height);
+ clipAndTranslateGraphics(root, this, g2);
+ g2.clipRect(x, y, w, h);
g2 = getComponentGraphics(g2);
- isPaintingDoubleBuffered = true;
+ paintingDoubleBuffered = true;
try
{
+ if (isRepainting) // Called from paintImmediately, go through paint().
paint(g2);
+ else // Called from paint() (AWT refresh), don't call it again.
+ {
+ paintComponent(g2);
+ paintBorder(g2);
+ paintChildren(g2);
+ }
}
finally
{
- isPaintingDoubleBuffered = false;
+ paintingDoubleBuffered = false;
g2.dispose();
}
// Paint the buffer contents on screen.
- rm.commitBuffer(root, new Rectangle(translation.x + r.x,
- translation.y + r.y, r.width,
- r.height));
+ rm.commitBuffer(this, x, y, w, h);
+ }
+
+ /**
+ * Clips and translates the Graphics instance for painting on the double
+ * buffer. This has to be done, so that it reflects the component clip of the
+ * target component.
+ *
+ * @param root the root component (top-level container usually)
+ * @param target the component to be painted
+ * @param g the Graphics instance
+ */
+ private void clipAndTranslateGraphics(Component root, Component target,
+ Graphics g)
+ {
+ Component parent = target;
+ int deltaX = 0;
+ int deltaY = 0;
+ while (parent != root)
+ {
+ deltaX += parent.getX();
+ deltaY += parent.getY();
+ parent = parent.getParent();
}
+ g.translate(deltaX, deltaY);
+ g.clipRect(0, 0, target.getWidth(), target.getHeight());
+ }
/**
* Performs normal painting without double buffering.
@@ -2251,6 +2428,12 @@
* A variant of {@link
* #registerKeyboardAction(ActionListener,String,KeyStroke,int)} which
* provides <code>null</code> for the command name.
+ *
+ * @param act the action listener to notify when the keystroke occurs.
+ * @param stroke the key stroke.
+ * @param cond the condition (one of {@link #WHEN_FOCUSED},
+ * {@link #WHEN_IN_FOCUSED_WINDOW} and
+ * {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}).
*/
public void registerKeyboardAction(ActionListener act,
KeyStroke stroke,
@@ -2327,9 +2510,22 @@
KeyStroke stroke,
int cond)
{
- getInputMap(cond).put(stroke, new ActionListenerProxy(act, cmd));
+ ActionListenerProxy proxy = new ActionListenerProxy(act, cmd);
+ getInputMap(cond).put(stroke, proxy);
+ getActionMap().put(proxy, proxy);
}
+ /**
+ * Sets the input map for the given condition.
+ *
+ * @param condition the condition (one of {@link #WHEN_FOCUSED},
+ * {@link #WHEN_IN_FOCUSED_WINDOW} and
+ * {@link #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}).
+ * @param map the map.
+ *
+ * @throws IllegalArgumentException if <code>condition</code> is not one of
+ * the specified values.
+ */
public final void setInputMap(int condition, InputMap map)
{
enableEvents(AWTEvent.KEY_EVENT_MASK);
@@ -2465,13 +2661,17 @@
*/
public ActionListener getActionForKeyStroke(KeyStroke ks)
{
- Object cmd = getInputMap().get(ks);
- if (cmd != null)
+ Object key = getInputMap(JComponent.WHEN_FOCUSED).get(ks);
+ if (key == null)
+ key = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).get(ks);
+ if (key == null)
+ key = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).get(ks);
+ if (key != null)
{
- if (cmd instanceof ActionListenerProxy)
- return (ActionListenerProxy) cmd;
- else if (cmd instanceof String)
- return getActionMap().get(cmd);
+ if (key instanceof ActionListenerProxy)
+ return ((ActionListenerProxy) key).target;
+ else
+ return getActionMap().get(key);
}
return null;
}
@@ -2570,20 +2770,37 @@
if (isEnabled())
{
Action act = null;
+ Object cmd = null;
InputMap map = getInputMap(condition);
if (map != null)
{
- Object cmd = map.get(ks);
+ cmd = map.get(ks);
if (cmd != null)
{
if (cmd instanceof ActionListenerProxy)
act = (Action) cmd;
else
- act = (Action) getActionMap().get(cmd);
+ act = getActionMap().get(cmd);
}
}
if (act != null && act.isEnabled())
- return SwingUtilities.notifyAction(act, ks, e, this, e.getModifiers());
+ {
+ // Need to synchronize here so we don't get in trouble with
+ // our __command__ hack.
+ synchronized (act)
+ {
+ // We add the command as value to the action, so that
+ // the action can later determine the command with which it
+ // was called. This is undocumented, but shouldn't affect
+ // compatibility. It allows us to use only one Action instance
+ // to do the work for all components of one type, instead of
+ // having loads of small Actions. This effectivly saves startup
+ // time of Swing.
+ act.putValue("__command__", cmd);
+ return SwingUtilities.notifyAction(act, ks, e, this,
+ e.getModifiers());
+ }
+ }
}
return false;
}
@@ -2685,6 +2902,11 @@
*/
public void revalidate()
{
+ // As long as we don't have a parent we don't need to do any layout, since
+ // this is done anyway as soon as we get connected to a parent.
+ if (getParent() == null)
+ return;
+
if (! EventQueue.isDispatchThread())
SwingUtilities.invokeLater(new Runnable()
{
@@ -2708,9 +2930,25 @@
*/
public void scrollRectToVisible(Rectangle r)
{
- Component p = getParent();
- if (p instanceof JComponent)
- ((JComponent) p).scrollRectToVisible(r);
+ // Search nearest JComponent.
+ int xOffs = getX();
+ int yOffs = getY();
+ Component p;
+ for (p = getParent(); p != null && ! (p instanceof JComponent);
+ p = p.getParent())
+ {
+ xOffs += p.getX();
+ yOffs += p.getY();
+ }
+ if (p != null)
+ {
+ r.x += xOffs;
+ r.y += yOffs;
+ JComponent jParent = (JComponent) p;
+ jParent.scrollRectToVisible(r);
+ r.x -= xOffs;
+ r.y -= yOffs;
+ }
}
/**
@@ -2829,57 +3067,6 @@
}
/**
- * Set the value of the {@link #maximumSize} property. The passed value is
- * copied, the later direct changes on the argument have no effect on the
- * property value.
- *
- * @param max The new value of the property
- */
- public void setMaximumSize(Dimension max)
- {
- Dimension oldMaximumSize = maximumSize;
- if (max != null)
- maximumSize = new Dimension(max);
- else
- maximumSize = null;
- firePropertyChange("maximumSize", oldMaximumSize, maximumSize);
- }
-
- /**
- * Set the value of the {@link #minimumSize} property. The passed value is
- * copied, the later direct changes on the argument have no effect on the
- * property value.
- *
- * @param min The new value of the property
- */
- public void setMinimumSize(Dimension min)
- {
- Dimension oldMinimumSize = minimumSize;
- if (min != null)
- minimumSize = new Dimension(min);
- else
- minimumSize = null;
- firePropertyChange("minimumSize", oldMinimumSize, minimumSize);
- }
-
- /**
- * Set the value of the {@link #preferredSize} property. The passed value is
- * copied, the later direct changes on the argument have no effect on the
- * property value.
- *
- * @param pref The new value of the property
- */
- public void setPreferredSize(Dimension pref)
- {
- Dimension oldPreferredSize = preferredSize;
- if (pref != null)
- preferredSize = new Dimension(pref);
- else
- preferredSize = null;
- firePropertyChange("preferredSize", oldPreferredSize, preferredSize);
- }
-
- /**
* Set the specified component to be the next component in the
* focus cycle, overriding the {@link FocusTraversalPolicy} for
* this component.
@@ -3068,11 +3255,29 @@
// Nothing to do here.
}
+ /**
+ * Returns the locale used as the default for all new components. The
+ * default value is {@link Locale#getDefault()} (that is, the platform
+ * default locale).
+ *
+ * @return The locale (never <code>null</code>).
+ *
+ * @see #setDefaultLocale(Locale)
+ */
public static Locale getDefaultLocale()
{
+ if (defaultLocale == null)
+ defaultLocale = Locale.getDefault();
return defaultLocale;
}
+ /**
+ * Sets the locale to be used as the default for all new components. If this
+ * is set to <code>null</code>, the {@link #getDefaultLocale()} method will
+ * return the platform default locale.
+ *
+ * @param l the locale (<code>null</code> permitted).
+ */
public static void setDefaultLocale(Locale l)
{
defaultLocale = l;
@@ -3510,141 +3715,18 @@
}
}
// Dispatch event to all children.
- Component[] children = getComponents();
- for (int i = 0; i < children.leng...
[truncated message content] |
|
From: <ls...@us...> - 2007-02-03 20:57:42
|
Revision: 3105
http://jnode.svn.sourceforge.net/jnode/?rev=3105&view=rev
Author: lsantha
Date: 2007-02-03 12:57:41 -0800 (Sat, 03 Feb 2007)
Log Message:
-----------
Added missing package.
Modified Paths:
--------------
trunk/core/descriptors/org.classpath.ext.core.xml
Modified: trunk/core/descriptors/org.classpath.ext.core.xml
===================================================================
--- trunk/core/descriptors/org.classpath.ext.core.xml 2007-02-03 20:51:24 UTC (rev 3104)
+++ trunk/core/descriptors/org.classpath.ext.core.xml 2007-02-03 20:57:41 UTC (rev 3105)
@@ -27,6 +27,7 @@
<export name="gnu.java.beans.encoder.*"/>
<export name="gnu.java.beans.encoder.elements.*"/>
<export name="gnu.java.lang.management.*"/>
+ <export name="gnu.java.lang.reflect.*"/>
<export name="gnu.java.net.protocol.*"/>
<export name="gnu.java.net.protocol.file.*"/>
<export name="gnu.java.net.protocol.ftp.*"/>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-03 20:51:25
|
Revision: 3104
http://jnode.svn.sourceforge.net/jnode/?rev=3104&view=rev
Author: lsantha
Date: 2007-02-03 12:51:24 -0800 (Sat, 03 Feb 2007)
Log Message:
-----------
Fixed Desktop resizing.
Modified Paths:
--------------
trunk/gui/src/awt/org/jnode/awt/swingpeers/DesktopFrame.java
Modified: trunk/gui/src/awt/org/jnode/awt/swingpeers/DesktopFrame.java
===================================================================
--- trunk/gui/src/awt/org/jnode/awt/swingpeers/DesktopFrame.java 2007-02-03 20:51:00 UTC (rev 3103)
+++ trunk/gui/src/awt/org/jnode/awt/swingpeers/DesktopFrame.java 2007-02-03 20:51:24 UTC (rev 3104)
@@ -21,12 +21,7 @@
package org.jnode.awt.swingpeers;
-import java.awt.AWTEvent;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.DefaultFocusTraversalPolicy;
-import java.awt.Dimension;
-import java.awt.Graphics;
+import java.awt.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyVetoException;
@@ -97,6 +92,8 @@
public void adjustDesktopSize(int width, int height) {
setSize(width, height);
+ VMAwtAPI.invalidateTree(this);
+ validateTree();
}
/**
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-03 20:51:03
|
Revision: 3103
http://jnode.svn.sourceforge.net/jnode/?rev=3103&view=rev
Author: lsantha
Date: 2007-02-03 12:51:00 -0800 (Sat, 03 Feb 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/awt/Component.java
trunk/core/src/classpath/java/java/awt/Container.java
trunk/core/src/classpath/java/java/awt/Window.java
Modified: trunk/core/src/classpath/java/java/awt/Component.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Component.java 2007-02-03 18:44:48 UTC (rev 3102)
+++ trunk/core/src/classpath/java/java/awt/Component.java 2007-02-03 20:51:00 UTC (rev 3103)
@@ -1180,14 +1180,7 @@
*/
public Font getFont()
{
- Font f = font;
- if (f != null)
- return f;
-
- Component p = parent;
- if (p != null)
- return p.getFont();
- return null;
+ return getFontImpl();
}
/**
@@ -1223,19 +1216,45 @@
*
* @see #getFont()
*/
- public void setFont(Font newFont)
+ public void setFont(Font f)
{
- if((newFont != null && (font == null || !font.equals(newFont)))
- || newFont == null)
+ Font oldFont;
+ Font newFont;
+ // Synchronize on the tree because getFontImpl() relies on the hierarchy
+ // not beeing changed.
+ synchronized (getTreeLock())
{
- Font oldFont = font;
- font = newFont;
- if (peer != null)
- peer.setFont(font);
+ // Synchronize on this here to guarantee thread safety wrt to the
+ // property values.
+ synchronized (this)
+ {
+ oldFont = font;
+ font = f;
+ newFont = f;
+ }
+ // Create local variable here for thread safety.
+ ComponentPeer p = peer;
+ if (p != null)
+ {
+ // The peer receives the real font setting, which can depend on
+ // the parent font when this component's font has been set to null.
+ f = getFont();
+ if (f != null)
+ {
+ p.setFont(f);
+ peerFont = f;
+ }
+ }
+ }
+
+ // Fire property change event.
firePropertyChange("font", oldFont, newFont);
+
+ // Invalidate when necessary as font changes can change the size of the
+ // component.
+ if (valid)
invalidate();
}
- }
/**
* Tests if the font was explicitly set, or just inherited from the parent.
@@ -1521,55 +1540,50 @@
*/
public void reshape(int x, int y, int width, int height)
{
+ // We need to lock the tree here, otherwise we risk races and
+ // inconsistencies.
+ synchronized (getTreeLock())
+ {
int oldx = this.x;
int oldy = this.y;
int oldwidth = this.width;
int oldheight = this.height;
- if (this.x == x && this.y == y && this.width == width
- && this.height == height)
- return;
+ boolean resized = oldwidth != width || oldheight != height;
+ boolean moved = oldx != x || oldy != y;
- invalidate();
-
+ if (resized || moved)
+ {
+ // Update the fields.
this.x = x;
this.y = y;
this.width = width;
this.height = height;
- if (peer != null)
- peer.setBounds (x, y, width, height);
- // Erase old bounds and repaint new bounds for lightweights.
- if (isLightweight() && isShowing())
+ if (peer != null)
{
- if (parent != null)
- {
- Rectangle oldBounds = new Rectangle(oldx, oldy, oldwidth,
- oldheight);
- Rectangle newBounds = new Rectangle(x, y, width, height);
- Rectangle destroyed = oldBounds.union(newBounds);
- if (!destroyed.isEmpty())
- parent.repaint(0, destroyed.x, destroyed.y, destroyed.width,
- destroyed.height);
+ peer.setBounds (x, y, width, height);
+ if (resized)
+ invalidate();
+ if (parent != null && parent.valid)
+ parent.invalidate();
}
- }
- // Only post event if this component is visible and has changed size.
- if (isShowing ()
- && (oldx != x || oldy != y))
+ // Send some events to interested listeners.
+ notifyReshape(resized, moved);
+
+ // Repaint this component and the parent if appropriate.
+ if (parent != null && peer instanceof LightweightPeer
+ && isShowing())
{
- ComponentEvent ce = new ComponentEvent(this,
- ComponentEvent.COMPONENT_MOVED);
- getToolkit().getSystemEventQueue().postEvent(ce);
+ // The parent repaints the area that we occupied before.
+ parent.repaint(oldx, oldy, oldwidth, oldheight);
+ // This component repaints the area that we occupy now.
+ repaint();
}
- if (isShowing ()
- && (oldwidth != width || oldheight != height))
- {
- ComponentEvent ce = new ComponentEvent(this,
- ComponentEvent.COMPONENT_RESIZED);
- getToolkit().getSystemEventQueue().postEvent(ce);
}
}
+ }
/**
* Sends notification to interested listeners about resizing and/or moving
@@ -1804,15 +1818,10 @@
*/
public Dimension preferredSize()
{
- if (prefSize == null)
- {
- if (peer == null)
- prefSize = minimumSize();
- else
- prefSize = peer.getPreferredSize();
+ // Create a new Dimension object, so that the application doesn't mess
+ // with the actual values.
+ return new Dimension(preferredSizeImpl());
}
- return prefSize;
- }
/**
* The actual calculation is pulled out of preferredSize() so that
@@ -1895,10 +1904,9 @@
*/
public Dimension minimumSize()
{
- if (minSize == null)
- minSize = (peer != null ? peer.getMinimumSize()
- : new Dimension(width, height));
- return minSize;
+ // Create a new Dimension object, so that the application doesn't mess
+ // with the actual values.
+ return new Dimension(minimumSizeImpl());
}
/**
@@ -1939,7 +1947,7 @@
*/
public Dimension getMaximumSize()
{
- return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
+ return new Dimension(maximumSizeImpl());
}
/**
@@ -2854,10 +2862,13 @@
*/
public synchronized void addComponentListener(ComponentListener listener)
{
- componentListener = AWTEventMulticaster.add(componentListener, listener);
- if (componentListener != null)
- enableEvents(AWTEvent.COMPONENT_EVENT_MASK);
+ if (listener != null)
+ {
+ componentListener = AWTEventMulticaster.add(componentListener,
+ listener);
+ newEventsOnly = true;
}
+ }
/**
* Removes the specified listener from the component. This is harmless if
@@ -2902,10 +2913,12 @@
*/
public synchronized void addFocusListener(FocusListener listener)
{
+ if (listener != null)
+ {
focusListener = AWTEventMulticaster.add(focusListener, listener);
- if (focusListener != null)
- enableEvents(AWTEvent.FOCUS_EVENT_MASK);
+ newEventsOnly = true;
}
+ }
/**
* Removes the specified listener from the component. This is harmless if
@@ -2949,10 +2962,21 @@
*/
public synchronized void addHierarchyListener(HierarchyListener listener)
{
- hierarchyListener = AWTEventMulticaster.add(hierarchyListener, listener);
- if (hierarchyListener != null)
- enableEvents(AWTEvent.HIERARCHY_EVENT_MASK);
+ if (listener != null)
+ {
+ hierarchyListener = AWTEventMulticaster.add(hierarchyListener,
+ listener);
+ newEventsOnly = true;
+ // Need to lock the tree, otherwise we might end up inconsistent.
+ synchronized (getTreeLock())
+ {
+ numHierarchyListeners++;
+ if (parent != null)
+ parent.updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
+ 1);
}
+ }
+ }
/**
* Removes the specified listener from the component. This is harmless if
@@ -2967,7 +2991,16 @@
public synchronized void removeHierarchyListener(HierarchyListener listener)
{
hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
+
+ // Need to lock the tree, otherwise we might end up inconsistent.
+ synchronized (getTreeLock())
+ {
+ numHierarchyListeners--;
+ if (parent != null)
+ parent.updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
+ -1);
}
+ }
/**
* Returns an array of all specified listeners registered on this component.
@@ -2998,11 +3031,22 @@
public synchronized void
addHierarchyBoundsListener(HierarchyBoundsListener listener)
{
+ if (listener != null)
+ {
hierarchyBoundsListener =
AWTEventMulticaster.add(hierarchyBoundsListener, listener);
- if (hierarchyBoundsListener != null)
- enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
+ newEventsOnly = true;
+
+ // Need to lock the tree, otherwise we might end up inconsistent.
+ synchronized (getTreeLock())
+ {
+ numHierarchyBoundsListeners++;
+ if (parent != null)
+ parent.updateHierarchyListenerCount
+ (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK, 1);
}
+ }
+ }
/**
* Removes the specified listener from the component. This is harmless if
@@ -3019,7 +3063,17 @@
{
hierarchyBoundsListener =
AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
+
+ // Need to lock the tree, otherwise we might end up inconsistent.
+ synchronized (getTreeLock())
+ {
+ numHierarchyBoundsListeners--;
+ if (parent != null)
+ parent.updateHierarchyListenerCount
+ (AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
+ -1);
}
+ }
/**
* Returns an array of all specified listeners registered on this component.
@@ -3083,10 +3137,12 @@
*/
public synchronized void addKeyListener(KeyListener listener)
{
+ if (listener != null)
+ {
keyListener = AWTEventMulticaster.add(keyListener, listener);
- if (keyListener != null)
- enableEvents(AWTEvent.KEY_EVENT_MASK);
+ newEventsOnly = true;
}
+ }
/**
* Removes the specified listener from the component. This is harmless if
@@ -3130,10 +3186,12 @@
*/
public synchronized void addMouseListener(MouseListener listener)
{
+ if (listener != null)
+ {
mouseListener = AWTEventMulticaster.add(mouseListener, listener);
- if (mouseListener != null)
- enableEvents(AWTEvent.MOUSE_EVENT_MASK);
+ newEventsOnly = true;
}
+ }
/**
* Removes the specified listener from the component. This is harmless if
@@ -3177,10 +3235,13 @@
*/
public synchronized void addMouseMotionListener(MouseMotionListener listener)
{
- mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener);
- if (mouseMotionListener != null)
- enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
+ if (listener != null)
+ {
+ mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener,
+ listener);
+ newEventsOnly = true;
}
+ }
/**
* Removes the specified listener from the component. This is harmless if
@@ -3226,10 +3287,13 @@
*/
public synchronized void addMouseWheelListener(MouseWheelListener listener)
{
- mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, listener);
- if (mouseWheelListener != null)
- enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
+ if (listener != null)
+ {
+ mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener,
+ listener);
+ newEventsOnly = true;
}
+ }
/**
* Removes the specified listener from the component. This is harmless if
@@ -3276,10 +3340,13 @@
*/
public synchronized void addInputMethodListener(InputMethodListener listener)
{
- inputMethodListener = AWTEventMulticaster.add(inputMethodListener, listener);
- if (inputMethodListener != null)
- enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
+ if (listener != null)
+ {
+ inputMethodListener = AWTEventMulticaster.add(inputMethodListener,
+ listener);
+ newEventsOnly = true;
}
+ }
/**
* Removes the specified listener from the component. This is harmless if
@@ -3445,19 +3512,42 @@
*/
protected AWTEvent coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
{
+ AWTEvent coalesced = null;
switch (existingEvent.id)
{
case MouseEvent.MOUSE_MOVED:
case MouseEvent.MOUSE_DRAGGED:
// Just drop the old (intermediate) event and return the new one.
- return newEvent;
+ MouseEvent me1 = (MouseEvent) existingEvent;
+ MouseEvent me2 = (MouseEvent) newEvent;
+ if (me1.getModifiers() == me2.getModifiers())
+ coalesced = newEvent;
+ break;
case PaintEvent.PAINT:
case PaintEvent.UPDATE:
- return coalescePaintEvents((PaintEvent) existingEvent,
- (PaintEvent) newEvent);
+ // For heavyweights the EventQueue should ask the peer.
+ if (peer == null || peer instanceof LightweightPeer)
+ {
+ PaintEvent pe1 = (PaintEvent) existingEvent;
+ PaintEvent pe2 = (PaintEvent) newEvent;
+ Rectangle r1 = pe1.getUpdateRect();
+ Rectangle r2 = pe2.getUpdateRect();
+ if (r1.contains(r2))
+ coalesced = existingEvent;
+ else if (r2.contains(r1))
+ coalesced = newEvent;
+ }
+ else
+ {
+ // Replace the event and let the heavyweight figure out the expanding
+ // of the repaint area.
+ coalesced = newEvent;
+ }
+ break;
default:
- return null;
+ coalesced = null;
}
+ return coalesced;
}
/**
Modified: trunk/core/src/classpath/java/java/awt/Container.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Container.java 2007-02-03 18:44:48 UTC (rev 3102)
+++ trunk/core/src/classpath/java/java/awt/Container.java 2007-02-03 20:51:00 UTC (rev 3103)
@@ -87,9 +87,7 @@
Component[] component;
LayoutManager layoutMgr;
- Dimension maxSize;
-
- /*
+ /**
* @since 1.4
*/
boolean focusCycleRoot;
@@ -1912,16 +1910,18 @@
*/
void dispatchEventImpl(AWTEvent e)
{
- boolean dispatched =
- LightweightDispatcher.getInstance().dispatchEvent(e);
- if (! dispatched)
+ LightweightDispatcher dispatcher = LightweightDispatcher.getInstance();
+ if (! isLightweight() && dispatcher.dispatchEvent(e))
{
- if ((e.id <= ContainerEvent.CONTAINER_LAST
- && e.id >= ContainerEvent.CONTAINER_FIRST)
- && (containerListener != null
- || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0))
- processEvent(e);
+ // Some lightweight descendent got this event dispatched. Consume
+ // it and let the peer handle it.
+ e.consume();
+ ComponentPeer p = peer;
+ if (p != null)
+ p.handleEvent(e);
+ }
else
+ {
super.dispatchEventImpl(e);
}
}
Modified: trunk/core/src/classpath/java/java/awt/Window.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Window.java 2007-02-03 18:44:48 UTC (rev 3102)
+++ trunk/core/src/classpath/java/java/awt/Window.java 2007-02-03 20:51:00 UTC (rev 3103)
@@ -286,8 +286,6 @@
{
synchronized (getTreeLock())
{
- if (parent != null && ! parent.isDisplayable())
- parent.addNotify();
if (peer == null)
addNotify();
@@ -529,8 +527,12 @@
*/
public synchronized void addWindowListener(WindowListener listener)
{
+ if (listener != null)
+ {
+ newEventsOnly = true;
windowListener = AWTEventMulticaster.add(windowListener, listener);
}
+ }
/**
* Removes the specified listener from the list of
@@ -586,9 +588,14 @@
*/
public void addWindowFocusListener (WindowFocusListener wfl)
{
- windowFocusListener = AWTEventMulticaster.add (windowFocusListener, wfl);
+ if (wfl != null)
+ {
+ newEventsOnly = true;
+ windowFocusListener = AWTEventMulticaster.add (windowFocusListener,
+ wfl);
}
-
+ }
+
/**
* Adds the specified listener to this window.
*
@@ -596,9 +603,14 @@
*/
public void addWindowStateListener (WindowStateListener wsl)
{
- windowStateListener = AWTEventMulticaster.add (windowStateListener, wsl);
+ if (wsl != null)
+ {
+ newEventsOnly = true;
+ windowStateListener = AWTEventMulticaster.add (windowStateListener,
+ wsl);
}
-
+ }
+
/**
* Removes the specified listener from this window.
*/
@@ -636,17 +648,11 @@
void dispatchEventImpl(AWTEvent e)
{
- // Make use of event id's in order to avoid multiple instanceof tests.
- if (e.id <= WindowEvent.WINDOW_LAST
- && e.id >= WindowEvent.WINDOW_FIRST
- && (windowListener != null
- || windowFocusListener != null
- || windowStateListener != null
- || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0))
- processEvent(e);
- else if (e.id == ComponentEvent.COMPONENT_RESIZED)
+ if (e.getID() == ComponentEvent.COMPONENT_RESIZED)
+ {
+ invalidate();
validate ();
- else
+ }
super.dispatchEventImpl(e);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-03 18:44:50
|
Revision: 3102
http://jnode.svn.sourceforge.net/jnode/?rev=3102&view=rev
Author: lsantha
Date: 2007-02-03 10:44:48 -0800 (Sat, 03 Feb 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/awt/Component.java
trunk/core/src/classpath/java/java/awt/Container.java
trunk/core/src/classpath/java/java/awt/Window.java
Modified: trunk/core/src/classpath/java/java/awt/Component.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Component.java 2007-02-03 15:05:27 UTC (rev 3101)
+++ trunk/core/src/classpath/java/java/awt/Component.java 2007-02-03 18:44:48 UTC (rev 3102)
@@ -971,18 +971,40 @@
// case lightweight components are not initially painted --
// Container.paint first calls isShowing () before painting itself
// and its children.
- if(!isVisible())
+ if(! visible)
{
- this.visible = true;
+ // Need to lock the tree here to avoid races and inconsistencies.
+ synchronized (getTreeLock())
+ {
+ visible = true;
// Avoid NullPointerExceptions by creating a local reference.
ComponentPeer currentPeer=peer;
if (currentPeer != null)
+ {
currentPeer.show();
+ // Fire HierarchyEvent.
+ fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
+ this, parent,
+ HierarchyEvent.SHOWING_CHANGED);
+
// The JDK repaints the component before invalidating the parent.
// So do we.
- if (isShowing() && isLightweight())
+ if (peer instanceof LightweightPeer)
repaint();
+ }
+
+ // Only post an event if this component actually has a listener
+ // or has this event explicitly enabled.
+ if (componentListener != null
+ || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
+ {
+ ComponentEvent ce =
+ new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+
// Invalidate the parent if we have one. The component itself must
// not be invalidated. We also avoid NullPointerException with
// a local reference here.
@@ -990,9 +1012,6 @@
if (currentParent != null)
currentParent.invalidate();
- ComponentEvent ce =
- new ComponentEvent(this,ComponentEvent.COMPONENT_SHOWN);
- getToolkit().getSystemEventQueue().postEvent(ce);
}
}
@@ -1018,29 +1037,47 @@
*/
public void hide()
{
- if (isVisible())
+ if (visible)
{
+ // Need to lock the tree here to avoid races and inconsistencies.
+ synchronized (getTreeLock())
+ {
+ visible = false;
+
// Avoid NullPointerExceptions by creating a local reference.
ComponentPeer currentPeer=peer;
if (currentPeer != null)
- currentPeer.setVisible(false);
- boolean wasShowing = isShowing();
- this.visible = false;
+ {
+ currentPeer.hide();
- // The JDK repaints the component before invalidating the parent.
- // So do we.
- if (wasShowing)
+ // Fire hierarchy event.
+ fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
+ this, parent,
+ HierarchyEvent.SHOWING_CHANGED);
+ // The JDK repaints the component before invalidating the
+ // parent. So do we. This only applies for lightweights.
+ if (peer instanceof LightweightPeer)
repaint();
- // Invalidate the parent if we have one. The component itself must
+ }
+
+ // Only post an event if this component actually has a listener
+ // or has this event explicitly enabled.
+ if (componentListener != null
+ || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
+ {
+ ComponentEvent ce =
+ new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+
+ // Invalidate the parent if we have one. The component itself need
// not be invalidated. We also avoid NullPointerException with
// a local reference here.
Container currentParent = parent;
if (currentParent != null)
currentParent.invalidate();
- ComponentEvent ce =
- new ComponentEvent(this,ComponentEvent.COMPONENT_HIDDEN);
- getToolkit().getSystemEventQueue().postEvent(ce);
}
}
@@ -3935,19 +3972,38 @@
*/
public void addNotify()
{
+ // We need to lock the tree here to avoid races and inconsistencies.
+ synchronized (getTreeLock())
+ {
if (peer == null)
peer = getToolkit().createComponent(this);
else if (parent != null && parent.isLightweight())
new HeavyweightInLightweightListener(parent);
- /* Now that all the children has gotten their peers, we should
- have the event mask needed for this component and its
- lightweight subcomponents. */
+ // Now that all the children has gotten their peers, we should
+ // have the event mask needed for this component and its
+ //lightweight subcomponents.
peer.setEventMask(eventMask);
- /* We do not invalidate here, but rather leave that job up to
- the peer. For efficiency, the peer can choose not to
- invalidate if it is happy with the current dimensions,
- etc. */
+
+ // We used to leave the invalidate() to the peer. However, I put it
+ // back here for 2 reasons: 1) The RI does call invalidate() from
+ // addNotify(); 2) The peer shouldn't be bother with validation too
+ // much.
+ invalidate();
+
+ if (dropTarget != null)
+ dropTarget.addNotify(peer);
+
+ // Fetch the peerFont for later installation in validate().
+ peerFont = getFont();
+
+ // Notify hierarchy listeners.
+ long flags = HierarchyEvent.DISPLAYABILITY_CHANGED;
+ if (isHierarchyVisible())
+ flags |= HierarchyEvent.SHOWING_CHANGED;
+ fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, this, parent,
+ flags);
}
+ }
/**
* Called to inform this component is has been removed from its
@@ -3960,6 +4016,9 @@
*/
public void removeNotify()
{
+ // We need to lock the tree here to avoid races and inconsistencies.
+ synchronized (getTreeLock())
+ {
// We null our peer field before disposing of it, such that if we're
// not the event dispatch thread and the dispatch thread is awoken by
// the dispose call, there will be no race checking the peer's null
@@ -3967,12 +4026,21 @@
ComponentPeer tmp = peer;
peer = null;
+ peerFont = null;
if (tmp != null)
{
tmp.hide();
tmp.dispose();
}
+
+ // Notify hierarchy listeners.
+ long flags = HierarchyEvent.DISPLAYABILITY_CHANGED;
+ if (isHierarchyVisible())
+ flags |= HierarchyEvent.SHOWING_CHANGED;
+ fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, this, parent,
+ flags);
}
+ }
/**
* AWT 1.0 GOT_FOCUS event handler. This method is meant to be
Modified: trunk/core/src/classpath/java/java/awt/Container.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Container.java 2007-02-03 15:05:27 UTC (rev 3101)
+++ trunk/core/src/classpath/java/java/awt/Container.java 2007-02-03 18:44:48 UTC (rev 3102)
@@ -39,7 +39,6 @@
package java.awt;
-import java.awt.event.ComponentListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.HierarchyEvent;
@@ -90,12 +89,7 @@
Dimension maxSize;
- /**
- * Keeps track if the Container was cleared during a paint/update.
- */
- private boolean backCleared;
-
- /**
+ /*
* @since 1.4
*/
boolean focusCycleRoot;
@@ -333,24 +327,7 @@
// we are.
if (comp.parent != null)
comp.parent.remove(comp);
- comp.parent = this;
- if (peer != null)
- {
- // Notify the component that it has a new parent.
- comp.addNotify();
-
- if (comp.isLightweight ())
- {
- enableEvents (comp.eventMask);
- if (!isLightweight ())
- enableEvents (AWTEvent.PAINT_EVENT_MASK);
- }
- }
-
- // Invalidate the layout of the added component and its ancestors.
- comp.invalidate();
-
if (component == null)
component = new Component[4]; // FIXME, better initial size?
@@ -374,6 +351,31 @@
++ncomponents;
}
+ // Give the new component a parent.
+ comp.parent = this;
+
+ // Update the counter for Hierarchy(Bounds)Listeners.
+ int childHierarchyListeners = comp.numHierarchyListeners;
+ if (childHierarchyListeners > 0)
+ updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
+ childHierarchyListeners);
+ int childHierarchyBoundsListeners = comp.numHierarchyBoundsListeners;
+ if (childHierarchyBoundsListeners > 0)
+ updateHierarchyListenerCount(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
+ childHierarchyListeners);
+
+ // Invalidate the layout of this container.
+ if (valid)
+ invalidate();
+
+ // Create the peer _after_ the component has been added, so that
+ // the peer gets to know about the component hierarchy.
+ if (peer != null)
+ {
+ // Notify the component that it has a new parent.
+ comp.addNotify();
+ }
+
// Notify the layout manager.
if (layoutMgr != null)
{
@@ -394,14 +396,20 @@
// Also, the event was posted to the event queue. A Mauve test shows
// that this event is not delivered using the event queue and it is
// also sent when the container is not showing.
+ if (containerListener != null
+ || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0)
+ {
ContainerEvent ce = new ContainerEvent(this,
ContainerEvent.COMPONENT_ADDED,
comp);
- ContainerListener[] listeners = getContainerListeners();
- for (int i = 0; i < listeners.length; i++)
- listeners[i].componentAdded(ce);
+ dispatchEvent(ce);
}
+
+ // Notify hierarchy listeners.
+ comp.fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, comp,
+ this, HierarchyEvent.PARENT_CHANGED);
}
+ }
/**
* Removes the component at the specified index from this container.
@@ -412,33 +420,48 @@
{
synchronized (getTreeLock ())
{
+ if (index < 0 || index >= ncomponents)
+ throw new ArrayIndexOutOfBoundsException();
+
Component r = component[index];
+ if (peer != null)
+ r.removeNotify();
- ComponentListener[] list = r.getComponentListeners();
- for (int j = 0; j < list.length; j++)
- r.removeComponentListener(list[j]);
+ if (layoutMgr != null)
+ layoutMgr.removeLayoutComponent(r);
- r.removeNotify();
+ // Update the counter for Hierarchy(Bounds)Listeners.
+ int childHierarchyListeners = r.numHierarchyListeners;
+ if (childHierarchyListeners > 0)
+ updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
+ -childHierarchyListeners);
+ int childHierarchyBoundsListeners = r.numHierarchyBoundsListeners;
+ if (childHierarchyBoundsListeners > 0)
+ updateHierarchyListenerCount(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
+ -childHierarchyListeners);
+ r.parent = null;
+
System.arraycopy(component, index + 1, component, index,
ncomponents - index - 1);
component[--ncomponents] = null;
+ if (valid)
invalidate();
- if (layoutMgr != null)
- layoutMgr.removeLayoutComponent(r);
-
- r.parent = null;
-
- if (isShowing ())
+ if (containerListener != null
+ || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0)
{
// Post event to notify of removing the component.
ContainerEvent ce = new ContainerEvent(this,
ContainerEvent.COMPONENT_REMOVED,
r);
- getToolkit().getSystemEventQueue().postEvent(ce);
+ dispatchEvent(ce);
}
+
+ // Notify hierarchy listeners.
+ r.fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, r,
+ this, HierarchyEvent.PARENT_CHANGED);
}
}
@@ -477,14 +500,13 @@
// super.removeAll() ).
// By doing it this way, user code cannot prevent the correct
// removal of components.
- for ( int index = 0; index < ncomponents; index++)
+ while (ncomponents > 0)
{
- Component r = component[index];
+ ncomponents--;
+ Component r = component[ncomponents];
+ component[ncomponents] = null;
- ComponentListener[] list = r.getComponentListeners();
- for (int j = 0; j < list.length; j++)
- r.removeComponentListener(list[j]);
-
+ if (peer != null)
r.removeNotify();
if (layoutMgr != null)
@@ -492,21 +514,37 @@
r.parent = null;
- if (isShowing ())
+ // Send ContainerEvent if necessary.
+ if (containerListener != null
+ || (eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0)
{
// Post event to notify of removing the component.
ContainerEvent ce
= new ContainerEvent(this,
ContainerEvent.COMPONENT_REMOVED,
r);
-
- getToolkit().getSystemEventQueue().postEvent(ce);
+ dispatchEvent(ce);
}
- }
-
+
+ // Update the counter for Hierarchy(Bounds)Listeners.
+ int childHierarchyListeners = r.numHierarchyListeners;
+ if (childHierarchyListeners > 0)
+ updateHierarchyListenerCount(AWTEvent.HIERARCHY_EVENT_MASK,
+ -childHierarchyListeners);
+ int childHierarchyBoundsListeners = r.numHierarchyBoundsListeners;
+ if (childHierarchyBoundsListeners > 0)
+ updateHierarchyListenerCount(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
+ -childHierarchyListeners);
+
+
+ // Send HierarchyEvent if necessary.
+ fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED, r, this,
+ HierarchyEvent.PARENT_CHANGED);
+
+ }
+
+ if (valid)
invalidate();
-
- ncomponents = 0;
}
}
@@ -571,11 +609,20 @@
*/
public void validate()
{
+ ComponentPeer p = peer;
+ if (! valid && p != null)
+ {
+ ContainerPeer cPeer = null;
+ if (p instanceof ContainerPeer)
+ cPeer = (ContainerPeer) peer;
synchronized (getTreeLock ())
{
- if (! isValid() && peer != null)
- {
+ if (cPeer != null)
+ cPeer.beginValidate();
validateTree();
+ valid = true;
+ if (cPeer != null)
+ cPeer.endValidate();
}
}
}
@@ -585,19 +632,18 @@
*/
void invalidateTree()
{
- super.invalidate(); // Clean cached layout state.
+ synchronized (getTreeLock())
+ {
for (int i = 0; i < ncomponents; i++)
{
Component comp = component[i];
- comp.invalidate();
if (comp instanceof Container)
((Container) comp).invalidateTree();
+ else if (comp.valid)
+ comp.invalidate();
}
-
- if (layoutMgr != null && layoutMgr instanceof LayoutManager2)
- {
- LayoutManager2 lm2 = (LayoutManager2) layoutMgr;
- lm2.invalidateLayout(this);
+ if (valid)
+ invalidate();
}
}
@@ -607,60 +653,52 @@
*/
protected void validateTree()
{
- if (valid)
- return;
-
+ if (!valid)
+ {
ContainerPeer cPeer = null;
- if (peer != null && ! (peer instanceof LightweightPeer))
+ if (peer instanceof ContainerPeer)
{
cPeer = (ContainerPeer) peer;
- cPeer.beginValidate();
+ cPeer.beginLayout();
}
- for (int i = 0; i < ncomponents; ++i)
- {
- Component comp = component[i];
-
- if (comp.getPeer () == null)
- comp.addNotify();
- }
-
doLayout ();
for (int i = 0; i < ncomponents; ++i)
{
Component comp = component[i];
- if (! comp.isValid())
+ if (comp instanceof Container && ! (comp instanceof Window)
+ && ! comp.valid)
{
- if (comp instanceof Container)
- {
((Container) comp).validateTree();
}
else
{
- component[i].validate();
+ comp.validate();
}
}
+
+ if (cPeer != null)
+ {
+ cPeer = (ContainerPeer) peer;
+ cPeer.endLayout();
}
+ }
/* children will call invalidate() when they are layed out. It
is therefore important that valid is not set to true
until after the children have been layed out. */
valid = true;
- if (cPeer != null)
- cPeer.endValidate();
}
public void setFont(Font f)
{
- if( (f != null && (font == null || !font.equals(f)))
- || f == null)
+ Font oldFont = getFont();
+ super.setFont(f);
+ Font newFont = getFont();
+ if (newFont != oldFont && (oldFont == null || ! oldFont.equals(newFont)))
{
- super.setFont(f);
- // FIXME: Although it might make more sense to invalidate only
- // those children whose font == null, Sun invalidates all children.
- // So we'll do the same.
invalidateTree();
}
}
@@ -922,8 +960,13 @@
*/
public synchronized void addContainerListener(ContainerListener listener)
{
- containerListener = AWTEventMulticaster.add(containerListener, listener);
+ if (listener != null)
+ {
+ containerListener = AWTEventMulticaster.add(containerListener,
+ listener);
+ newEventsOnly = true;
}
+ }
/**
* Removes the specified container listener from this object's list of
@@ -1853,6 +1896,7 @@
bounds.height);
try
{
+ g2.setFont(comp.getFont());
visitor.visit(comp, g2);
}
finally
@@ -2053,15 +2097,9 @@
for (int i = ncomponents; --i >= 0; )
{
component[i].addNotify();
- if (component[i].isLightweight ())
- {
- enableEvents(component[i].eventMask);
- if (peer != null && !isLightweight ())
- enableEvents (AWTEvent.PAINT_EVENT_MASK);
}
}
}
- }
/**
* Deserialize this Container:
Modified: trunk/core/src/classpath/java/java/awt/Window.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Window.java 2007-02-03 15:05:27 UTC (rev 3101)
+++ trunk/core/src/classpath/java/java/awt/Window.java 2007-02-03 18:44:48 UTC (rev 3102)
@@ -393,11 +393,17 @@
component[i].removeNotify();
this.removeNotify();
- // Post a WINDOW_CLOSED event.
- WindowEvent we = new WindowEvent(this, WindowEvent.WINDOW_CLOSED);
- getToolkit().getSystemEventQueue().postEvent(we);
+ // Post WINDOW_CLOSED from here.
+ if (windowListener != null
+ || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0)
+ {
+ WindowEvent ev = new WindowEvent(this,
+ WindowEvent.WINDOW_CLOSED);
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ tk.getSystemEventQueue().postEvent(ev);
}
}
+ }
/**
* Sends this window to the back so that all other windows display in
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-02-03 15:05:36
|
Revision: 3101
http://jnode.svn.sourceforge.net/jnode/?rev=3101&view=rev
Author: lsantha
Date: 2007-02-03 07:05:27 -0800 (Sat, 03 Feb 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/awt/Component.java
trunk/core/src/classpath/java/java/awt/Container.java
trunk/core/src/classpath/java/java/awt/Window.java
Modified: trunk/core/src/classpath/java/java/awt/Component.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Component.java 2007-01-31 21:51:44 UTC (rev 3100)
+++ trunk/core/src/classpath/java/java/awt/Component.java 2007-02-03 15:05:27 UTC (rev 3101)
@@ -581,7 +581,7 @@
transient ComponentPeer peer;
/** The preferred component orientation. */
- transient ComponentOrientation orientation = ComponentOrientation.UNKNOWN;
+ transient ComponentOrientation componentOrientation = ComponentOrientation.UNKNOWN;
/**
* The associated graphics configuration.
@@ -748,17 +748,24 @@
*/
public Toolkit getToolkit()
{
- if (peer != null)
+ // Only heavyweight peers can handle this.
+ ComponentPeer p = peer;
+ Component comp = this;
+ while (p instanceof LightweightPeer)
{
- Toolkit tk = peer.getToolkit();
- if (tk != null)
- return tk;
+ comp = comp.parent;
+ p = comp == null ? null : comp.peer;
}
- // Get toolkit for lightweight component.
- if (parent != null)
- return parent.getToolkit();
- return Toolkit.getDefaultToolkit();
+
+ Toolkit tk = null;
+ if (p != null)
+ {
+ tk = peer.getToolkit();
}
+ if (tk == null)
+ tk = Toolkit.getDefaultToolkit();
+ return tk;
+ }
/**
* Tests whether or not this component is valid. A invalid component needs
@@ -770,7 +777,9 @@
*/
public boolean isValid()
{
- return valid;
+ // Tests show that components are invalid as long as they are not showing, even after validate()
+ // has been called on them.
+ return peer != null && valid;
}
/**
@@ -814,10 +823,8 @@
*/
public boolean isShowing()
{
- if (! visible || peer == null)
- return false;
-
- return parent == null ? false : parent.isShowing();
+ Component par = parent;
+ return visible && peer != null && (par == null || par.isShowing());
}
/**
@@ -856,10 +863,18 @@
*/
public void enable()
{
- this.enabled = true;
- if (peer != null)
- peer.setEnabled (true);
+ if (! enabled)
+ {
+ // Need to lock the tree here, because the peers are involved.
+ synchronized (getTreeLock())
+ {
+ enabled = true;
+ ComponentPeer p = peer;
+ if (p != null)
+ p.enable();
}
+ }
+ }
/**
* Enables or disables this component.
@@ -883,10 +898,18 @@
*/
public void disable()
{
- this.enabled = false;
- if (peer != null)
- peer.setEnabled (false);
+ if (enabled)
+ {
+ // Need to lock the tree here, because the peers are involved.
+ synchronized (getTreeLock())
+ {
+ enabled = false;
+ ComponentPeer p = peer;
+ if (p != null)
+ p.disable();
}
+ }
+ }
/**
* Checks if this image is painted to an offscreen image buffer that is
@@ -1130,11 +1153,36 @@
return null;
}
- /**
+ /**
+ * Implementation of getFont(). This is pulled out of getFont() to prevent
+ * client programs from overriding this.
+ *
+ * @return the font of this component
+ */
+ private final Font getFontImpl()
+ {
+ Font f = font;
+ if (f == null)
+ {
+ Component p = parent;
+ if (p != null)
+ f = p.getFontImpl();
+ else
+ {
+ // It is important to return null here and not some kind of default
+ // font, otherwise the Swing UI would not install its fonts because
+ // it keeps non-UIResource fonts.
+ f = null;
+ }
+ }
+ return f;
+ }
+
+ /**
* Sets the font for this component to the specified font. This is a bound
* property.
*
- * @param newFont the new font for this component
+ * @param f the new font for this component
*
* @see #getFont()
*/
@@ -1729,11 +1777,39 @@
return prefSize;
}
+ /**
+ * The actual calculation is pulled out of preferredSize() so that
+ * we can call it from Container.preferredSize() and avoid creating a
+ * new intermediate Dimension object.
+ *
+ * @return the preferredSize of the component
+ */
+ Dimension preferredSizeImpl()
+ {
+ Dimension size = prefSize;
+ // Try to use a cached value.
+ if (size == null || !(valid || prefSizeSet))
+ {
+ // We need to lock here, because the calculation depends on the
+ // component structure not changing.
+ synchronized (getTreeLock())
+ {
+ ComponentPeer p = peer;
+ if (p != null)
+ size = peer.preferredSize();
+ else
+ size = minimumSizeImpl();
+ }
+ }
+ return size;
+ }
+
/**
* Returns the component's minimum size.
*
* @return the component's minimum size
* @see #getPreferredSize()
+ * @see #setMinimumSize(Dimension)
* @see LayoutManager
*/
public Dimension getMinimumSize()
@@ -1937,8 +2013,33 @@
*/
public void validate()
{
+ if (! valid)
+ {
+ // Synchronize on the tree here as this might change the layout
+ // of the hierarchy.
+ synchronized (getTreeLock())
+ {
+ // Create local variables for thread safety.
+ ComponentPeer p = peer;
+ if (p != null)
+ {
+ // Possibly update the peer's font.
+ Font newFont = getFont();
+ Font oldFont = peerFont;
+ // Only update when the font really changed.
+ if (newFont != oldFont
+ && (oldFont == null || ! oldFont.equals(newFont)))
+ {
+ p.setFont(newFont);
+ peerFont = newFont;
+ }
+ // Let the peer perform any layout.
+ p.layout();
+ }
+ }
valid = true;
}
+ }
/**
* Invalidates this component and all of its parent components. This will
@@ -1947,12 +2048,26 @@
*/
public void invalidate()
{
+ // Need to lock here, to avoid races and other ugly stuff when doing
+ // layout or structure changes in other threads.
+ synchronized (getTreeLock())
+ {
+ // Invalidate.
valid = false;
- prefSize = null;
+
+ // Throw away cached layout information.
+ if (! minSizeSet)
minSize = null;
+ if (! prefSizeSet)
+ prefSize = null;
+ if (! maxSizeSet)
+ maxSize = null;
+
+ // Also invalidate the parent, if it hasn't already been invalidated.
if (parent != null && parent.isValid())
parent.invalidate();
}
+ }
/**
* Returns a graphics object for this component. Returns <code>null</code>
@@ -1998,10 +2113,18 @@
*/
public FontMetrics getFontMetrics(Font font)
{
- return peer == null ? getToolkit().getFontMetrics(font)
- : peer.getFontMetrics(font);
+ ComponentPeer p = peer;
+ Component comp = this;
+ while (p instanceof LightweightPeer)
+ {
+ comp = comp.parent;
+ p = comp == null ? null : comp.peer;
}
+ return p == null ? getToolkit().getFontMetrics(font)
+ : p.getFontMetrics(font);
+ }
+
/**
* Sets the cursor for this component to the specified cursor. The cursor
* is displayed when the point is contained by the component, and the
@@ -2018,10 +2141,20 @@
public void setCursor(Cursor cursor)
{
this.cursor = cursor;
- if (peer != null)
- peer.setCursor(cursor);
+
+ // Only heavyweight peers handle this.
+ ComponentPeer p = peer;
+ Component comp = this;
+ while (p instanceof LightweightPeer)
+ {
+ comp = comp.parent;
+ p = comp == null ? null : comp.peer;
}
+ if (p != null)
+ p.setCursor(cursor);
+ }
+
/**
* Returns the cursor for this component. If not set, this is inherited
* from the parent, or from Cursor.getDefaultCursor().
@@ -2077,19 +2210,14 @@
*/
public void update(Graphics g)
{
- // Tests show that the clearing of the background is only done in
- // two cases:
- // - If the component is lightweight (yes this is in contrast to the spec).
- // or
- // - If the component is a toplevel container.
- if (isLightweight() || getParent() == null)
- {
- Rectangle clip = g.getClipBounds();
- if (clip == null)
- g.clearRect(0, 0, width, height);
- else
- g.clearRect(clip.x, clip.y, clip.width, clip.height);
- }
+ // Note 1: We used to clear the background here for lightweights and
+ // toplevel components. Tests show that this is not what the JDK does
+ // here. Note that there is some special handling and background
+ // clearing code in Container.update(Graphics).
+
+ // Note 2 (for peer implementors): The JDK doesn't seem call update() for
+ // toplevel components, even when an UPDATE event is sent (as a result
+ // of repaint).
paint(g);
}
@@ -2102,10 +2230,15 @@
*/
public void paintAll(Graphics g)
{
- if (! visible)
- return;
+ if (isShowing())
+ {
+ validate();
+ if (peer instanceof LightweightPeer)
paint(g);
+ else
+ peer.paint(g);
}
+ }
/**
* Repaint this entire component. The <code>update()</code> method
@@ -2165,13 +2298,44 @@
*/
public void repaint(long tm, int x, int y, int width, int height)
{
- if (isShowing())
+ // The repaint() call has previously been delegated to
+ // {@link ComponentPeer.repaint()}. Testing on the JDK using some
+ // dummy peers show that this methods is never called. I think it makes
+ // sense to actually perform the tasks below here, since it's pretty
+ // much peer independent anyway, and makes sure only heavyweights are
+ // bothered by this.
+ ComponentPeer p = peer;
+
+ // Let the nearest heavyweight parent handle repainting for lightweight
+ // components.
+ // We need to recursivly call repaint() on the parent here, since
+ // a (lightweight) parent component might have overridden repaint()
+ // to perform additional custom tasks.
+
+ if (p instanceof LightweightPeer)
{
- ComponentPeer p = peer;
- if (p != null)
- p.repaint(tm, x, y, width, height);
+ // We perform some boundary checking to restrict the paint
+ // region to this component.
+ if (parent != null)
+ {
+ int px = this.x + Math.max(0, x);
+ int py = this.y + Math.max(0, y);
+ int pw = Math.min(this.width, width);
+ int ph = Math.min(this.height, height);
+ parent.repaint(tm, px, py, pw, ph);
}
}
+ else
+ {
+ // Now send an UPDATE event to the heavyweight component that we've found.
+ if (isVisible() && p != null && width > 0 && height > 0)
+ {
+ PaintEvent pe = new PaintEvent(this, PaintEvent.UPDATE,
+ new Rectangle(x, y, width, height));
+ getToolkit().getSystemEventQueue().postEvent(pe);
+ }
+ }
+ }
/**
* Prints this component. This method is provided so that printing can be
@@ -2196,6 +2360,8 @@
*/
public void printAll(Graphics g)
{
+ if( peer != null )
+ peer.print( g );
paintAll(g);
}
@@ -2255,11 +2421,22 @@
*/
public Image createImage(ImageProducer producer)
{
+ // Only heavyweight peers can handle this.
+ ComponentPeer p = peer;
+ Component comp = this;
+ while (p instanceof LightweightPeer)
+ {
+ comp = comp.parent;
+ p = comp == null ? null : comp.peer;
+ }
+
// Sun allows producer to be null.
- if (peer != null)
- return peer.createImage(producer);
+ Image im;
+ if (p != null)
+ im = p.createImage(producer);
else
- return getToolkit().createImage(producer);
+ im = getToolkit().createImage(producer);
+ return im;
}
/**
@@ -2275,11 +2452,18 @@
Image returnValue = null;
if (!GraphicsEnvironment.isHeadless ())
{
- if (isLightweight () && parent != null)
- returnValue = parent.createImage (width, height);
- else if (peer != null)
- returnValue = peer.createImage (width, height);
+ // Only heavyweight peers can handle this.
+ ComponentPeer p = peer;
+ Component comp = this;
+ while (p instanceof LightweightPeer)
+ {
+ comp = comp.parent;
+ p = comp == null ? null : comp.peer;
}
+
+ if (p != null)
+ returnValue = p.createImage(width, height);
+ }
return returnValue;
}
@@ -2294,11 +2478,21 @@
*/
public VolatileImage createVolatileImage(int width, int height)
{
- if (peer != null)
- return peer.createVolatileImage(width, height);
- return null;
+ // Only heavyweight peers can handle this.
+ ComponentPeer p = peer;
+ Component comp = this;
+ while (p instanceof LightweightPeer)
+ {
+ comp = comp.parent;
+ p = comp == null ? null : comp.peer;
}
+ VolatileImage im = null;
+ if (p != null)
+ im = p.createVolatileImage(width, height);
+ return im;
+ }
+
/**
* Creates an image with the specified width and height for use in
* double buffering. Headless environments do not support images. The image
@@ -2315,11 +2509,21 @@
ImageCapabilities caps)
throws AWTException
{
- if (peer != null)
- return peer.createVolatileImage(width, height);
- return null;
+ // Only heavyweight peers can handle this.
+ ComponentPeer p = peer;
+ Component comp = this;
+ while (p instanceof LightweightPeer)
+ {
+ comp = comp.parent;
+ p = comp == null ? null : comp.peer;
}
+ VolatileImage im = null;
+ if (p != null)
+ im = peer.createVolatileImage(width, height);
+ return im;
+ }
+
/**
* Prepares the specified image for rendering on this component.
*
@@ -2347,10 +2551,21 @@
public boolean prepareImage(Image image, int width, int height,
ImageObserver observer)
{
- if (peer != null)
- return peer.prepareImage(image, width, height, observer);
+ // Only heavyweight peers handle this.
+ ComponentPeer p = peer;
+ Component comp = this;
+ while (p instanceof LightweightPeer)
+ {
+ comp = comp.parent;
+ p = comp == null ? null : comp.peer;
+ }
+
+ boolean retval;
+ if (p != null)
+ retval = p.prepareImage(image, width, height, observer);
else
- return getToolkit().prepareImage(image, width, height, observer);
+ retval = getToolkit().prepareImage(image, width, height, observer);
+ return retval;
}
/**
@@ -2384,11 +2599,23 @@
public int checkImage(Image image, int width, int height,
ImageObserver observer)
{
- if (peer != null)
- return peer.checkImage(image, width, height, observer);
- return getToolkit().checkImage(image, width, height, observer);
+ // Only heavyweight peers handle this.
+ ComponentPeer p = peer;
+ Component comp = this;
+ while (p instanceof LightweightPeer)
+ {
+ comp = comp.parent;
+ p = comp == null ? null : comp.peer;
}
+ int retval;
+ if (p != null)
+ retval = p.checkImage(image, width, height, observer);
+ else
+ retval = getToolkit().checkImage(image, width, height, observer);
+ return retval;
+ }
+
/**
* Sets whether paint messages delivered by the operating system should be
* ignored. This does not affect messages from AWT, except for those
@@ -4328,7 +4555,84 @@
return false;
}
- /**
+ /**
+ * Helper method for all 4 requestFocus variants.
+ *
+ * @param temporary indicates if the focus change is temporary
+ * @param focusWindow indicates if the window focus may be changed
+ *
+ * @return <code>false</code> if the request has been definitely denied,
+ * <code>true</code> otherwise
+ */
+ private boolean requestFocusImpl(boolean temporary, boolean focusWindow)
+ {
+ boolean retval = false;
+
+ // Don't try to focus non-focusable and non-visible components.
+ if (isFocusable() && isVisible())
+ {
+ ComponentPeer myPeer = peer;
+ if (peer != null)
+ {
+ // Find Window ancestor and find out if we're showing while
+ // doing this.
+ boolean showing = true;
+ Component window = this;
+ while (! (window instanceof Window))
+ {
+ if (! window.isVisible())
+ showing = false;
+ window = window.parent;
+ }
+ // Don't allow focus when there is no window or the window
+ // is not focusable.
+ if (window != null && ((Window) window).isFocusableWindow()
+ && showing)
+ {
+ // Search for nearest heavy ancestor (including this
+ // component).
+ Component heavyweightParent = this;
+ while (heavyweightParent.peer instanceof LightweightPeer)
+ heavyweightParent = heavyweightParent.parent;
+
+ // Don't allow focus on lightweight components without
+ // visible heavyweight ancestor
+ if (heavyweightParent != null && heavyweightParent.isVisible())
+ {
+ // Don't allow focus when heavyweightParent has no peer.
+ myPeer = heavyweightParent.peer;
+ if (myPeer != null)
+ {
+ // Register lightweight focus request.
+ if (heavyweightParent != this)
+ {
+ KeyboardFocusManager
+ .addLightweightFocusRequest(heavyweightParent,
+ this);
+ }
+
+ // Try to focus the component.
+ long time = EventQueue.getMostRecentEventTime();
+ boolean success = myPeer.requestFocus(this, temporary,
+ focusWindow,
+ time);
+ if (! success)
+ {
+ // Dequeue key events if focus request failed.
+ KeyboardFocusManager kfm =
+ KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ kfm.dequeueKeyEvents(time, this);
+ }
+ retval = success;
+ }
+ }
+ }
+ }
+ }
+ return retval;
+ }
+
+ /**
* Transfers focus to the next component in the focus traversal
* order, as though this were the current focus owner.
*
@@ -4972,10 +5276,9 @@
*/
public void setComponentOrientation(ComponentOrientation o)
{
- if (o == null)
- throw new NullPointerException();
- ComponentOrientation oldOrientation = orientation;
- orientation = o;
+
+ ComponentOrientation oldOrientation = componentOrientation;
+ componentOrientation = o;
firePropertyChange("componentOrientation", oldOrientation, o);
}
@@ -4987,7 +5290,7 @@
*/
public ComponentOrientation getComponentOrientation()
{
- return orientation;
+ return componentOrientation;
}
/**
@@ -5137,7 +5440,7 @@
if ((mods & InputEvent.ALT_DOWN_MASK) != 0)
oldMods |= Event.ALT_MASK;
- if (e instanceof MouseEvent)
+ if (e instanceof MouseEvent && !ignoreOldMouseEvents())
{
if (id == MouseEvent.MOUSE_PRESSED)
oldID = Event.MOUSE_DOWN;
@@ -5471,6 +5774,26 @@
}
/**
+ * Returns <code>true</code> when this component and all of its ancestors
+ * are visible, <code>false</code> otherwise.
+ *
+ * @return <code>true</code> when this component and all of its ancestors
+ * are visible, <code>false</code> otherwise
+ */
+ boolean isHierarchyVisible()
+ {
+ boolean visible = isVisible();
+ Component comp = parent;
+ while (comp != null && visible)
+ {
+ comp = comp.parent;
+ if (comp != null)
+ visible = visible && comp.isVisible();
+ }
+ return visible;
+ }
+
+ /**
* This method is used to implement transferFocus(). CHILD is the child
* making the request. This is overridden by Container; when called for an
* ordinary component there is no child and so we always return null.
Modified: trunk/core/src/classpath/java/java/awt/Container.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Container.java 2007-01-31 21:51:44 UTC (rev 3100)
+++ trunk/core/src/classpath/java/java/awt/Container.java 2007-02-03 15:05:27 UTC (rev 3101)
@@ -215,10 +215,12 @@
*/
public Insets insets()
{
- if (peer == null)
- return new Insets (0, 0, 0, 0);
-
- return ((ContainerPeer) peer).getInsets ();
+ Insets i;
+ if (peer == null || peer instanceof LightweightPeer)
+ i = new Insets (0, 0, 0, 0);
+ else
+ i = ((ContainerPeer) peer).getInsets ();
+ return i;
}
/**
@@ -527,6 +529,7 @@
public void setLayout(LayoutManager mgr)
{
layoutMgr = mgr;
+ if (valid)
invalidate();
}
@@ -681,22 +684,26 @@
*/
public Dimension preferredSize()
{
- synchronized(treeLock)
+ Dimension size = prefSize;
+ // Try to return cached value if possible.
+ if (size == null || !(prefSizeSet || valid))
{
- if(valid && prefSize != null)
- return new Dimension(prefSize);
- LayoutManager layout = getLayout();
- if (layout != null)
+ // Need to lock here.
+ synchronized (getTreeLock())
{
- Dimension layoutSize = layout.preferredLayoutSize(this);
- if(valid)
- prefSize = layoutSize;
- return new Dimension(layoutSize);
- }
+ LayoutManager l = layoutMgr;
+ if (l != null)
+ prefSize = l.preferredLayoutSize(this);
else
- return super.preferredSize ();
+ prefSize = super.preferredSizeImpl();
+ size = prefSize;
}
}
+ if (size != null)
+ return new Dimension(size);
+ else
+ return size;
+ }
/**
* Returns the minimum size of this container.
@@ -717,17 +724,25 @@
*/
public Dimension minimumSize()
{
- if(valid && minSize != null)
- return new Dimension(minSize);
-
- LayoutManager layout = getLayout();
- if (layout != null)
+ Dimension size = minSize;
+ // Try to return cached value if possible.
+ if (size == null || !(minSizeSet || valid))
{
- minSize = layout.minimumLayoutSize (this);
- return minSize;
+ // Need to lock here.
+ synchronized (getTreeLock())
+ {
+ LayoutManager l = layoutMgr;
+ if (l != null)
+ minSize = l.minimumLayoutSize(this);
+ else
+ minSize = super.minimumSizeImpl();
+ size = minSize;
}
+ }
+ if (size != null)
+ return new Dimension(size);
else
- return super.minimumSize ();
+ return size;
}
/**
@@ -737,18 +752,26 @@
*/
public Dimension getMaximumSize()
{
- if (valid && maxSize != null)
- return new Dimension(maxSize);
-
- LayoutManager layout = getLayout();
- if (layout != null && layout instanceof LayoutManager2)
+ Dimension size = maxSize;
+ // Try to return cached value if possible.
+ if (size == null || !(maxSizeSet || valid))
{
- LayoutManager2 lm2 = (LayoutManager2) layout;
- maxSize = lm2.maximumLayoutSize(this);
- return maxSize;
+ // Need to lock here.
+ synchronized (getTreeLock())
+ {
+ LayoutManager l = layoutMgr;
+ if (l instanceof LayoutManager2)
+ maxSize = ((LayoutManager2) l).maximumLayoutSize(this);
+ else {
+ maxSize = super.maximumSizeImpl();
}
+ size = maxSize;
+ }
+ }
+ if (size != null)
+ return new Dimension(size);
else
- return super.getMaximumSize();
+ return size;
}
/**
@@ -764,9 +787,12 @@
float alignmentX = 0.0F;
if (layout != null && layout instanceof LayoutManager2)
{
+ synchronized (getTreeLock())
+ {
LayoutManager2 lm2 = (LayoutManager2) layout;
alignmentX = lm2.getLayoutAlignmentX(this);
}
+ }
else
alignmentX = super.getAlignmentX();
return alignmentX;
@@ -785,9 +811,12 @@
float alignmentY = 0.0F;
if (layout != null && layout instanceof LayoutManager2)
{
+ synchronized (getTreeLock())
+ {
LayoutManager2 lm2 = (LayoutManager2) layout;
alignmentY = lm2.getLayoutAlignmentY(this);
}
+ }
else
alignmentY = super.getAlignmentY();
return alignmentY;
@@ -804,14 +833,11 @@
*/
public void paint(Graphics g)
{
- if (!isShowing())
- return;
-
- // Visit heavyweights if the background was cleared
- // for this container.
- visitChildren(g, GfxPaintVisitor.INSTANCE, !backCleared);
- backCleared = false;
+ if (isShowing())
+ {
+ visitChildren(g, GfxPaintVisitor.INSTANCE, true);
}
+ }
/**
* Updates this container. The implementation of this method in this
@@ -840,15 +866,16 @@
// that overrides isLightweight() to return false, the background is
// also not cleared. So we do a check on !(peer instanceof LightweightPeer)
// instead.
+ if (isShowing())
+ {
ComponentPeer p = peer;
- if (p != null && ! (p instanceof LightweightPeer))
+ if (! (p instanceof LightweightPeer))
{
g.clearRect(0, 0, getWidth(), getHeight());
- backCleared = true;
}
-
paint(g);
}
+ }
/**
* Prints this container. The implementation of this method in this
@@ -872,8 +899,8 @@
*/
public void paintComponents(Graphics g)
{
- paint(g);
- visitChildren(g, GfxPaintAllVisitor.INSTANCE, true);
+ if (isShowing())
+ visitChildren(g, GfxPaintAllVisitor.INSTANCE, false);
}
/**
@@ -1183,9 +1210,12 @@
*/
public void addNotify()
{
+ synchronized (getTreeLock())
+ {
super.addNotify();
addNotifyContainerChildren();
}
+ }
/**
* Called when this container is removed from its parent container to
@@ -1196,8 +1226,14 @@
{
synchronized (getTreeLock ())
{
- for (int i = 0; i < ncomponents; ++i)
- component[i].removeNotify();
+ int ncomps = ncomponents;
+ Component[] comps = component;
+ for (int i = ncomps - 1; i >= 0; --i)
+ {
+ Component comp = comps[i];
+ if (comp != null)
+ comp.removeNotify();
+ }
super.removeNotify();
}
}
@@ -1294,7 +1330,8 @@
*
* @since 1.4
*/
- public void setFocusTraversalKeys(int id, Set keystrokes)
+ public void setFocusTraversalKeys(int id,
+ Set<? extends AWTKeyStroke> keystrokes)
{
if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
@@ -1382,7 +1419,8 @@
if (focusTraversalKeys == null)
focusTraversalKeys = new Set[4];
- keystrokes = Collections.unmodifiableSet (new HashSet (keystrokes));
+ keystrokes =
+ Collections.unmodifiableSet(new HashSet<AWTKeyStroke>(keystrokes));
firePropertyChange (name, focusTraversalKeys[id], keystrokes);
focusTraversalKeys[id] = keystrokes;
@@ -1400,7 +1438,7 @@
*
* @since 1.4
*/
- public Set getFocusTraversalKeys (int id)
+ public Set<AWTKeyStroke> getFocusTraversalKeys (int id)
{
if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
@@ -1641,8 +1679,17 @@
{
if (orientation == null)
throw new NullPointerException ();
+
+ setComponentOrientation(orientation);
+ for (int i = 0; i < ncomponents; i++)
+ {
+ if (component[i] instanceof Container)
+ ((Container) component[i]).applyComponentOrientation(orientation);
+ else
+ component[i].setComponentOrientation(orientation);
}
-
+ }
+
public void addPropertyChangeListener (PropertyChangeListener listener)
{
// TODO: Why is this overridden?
@@ -1692,6 +1739,8 @@
if (comp == this)
throw new IllegalArgumentException("cannot add component to itself");
+ synchronized (getTreeLock())
+ {
// FIXME: Implement reparenting.
if ( comp.getParent() != this)
throw new AssertionError("Reparenting is not implemented yet");
@@ -1712,6 +1761,7 @@
component[index] = comp;
}
}
+ }
/**
* Returns the Z ordering index of <code>comp</code>. If <code>comp</code>
@@ -1728,10 +1778,12 @@
*/
public final int getComponentZOrder(Component comp)
{
+ synchronized (getTreeLock())
+ {
int index = -1;
if (component != null)
{
- for (int i = 0; i < component.length; i++)
+ for (int i = 0; i < ncomponents; i++)
{
if (component[i] == comp)
{
@@ -1742,6 +1794,7 @@
}
return index;
}
+ }
// Hidden helper methods.
Modified: trunk/core/src/classpath/java/java/awt/Window.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Window.java 2007-01-31 21:51:44 UTC (rev 3100)
+++ trunk/core/src/classpath/java/java/awt/Window.java 2007-02-03 15:05:27 UTC (rev 3101)
@@ -410,8 +410,9 @@
{
if (peer != null)
{
- WindowPeer wp = (WindowPeer) peer;
- wp.toBack();
+ if( alwaysOnTop )
+ setAlwaysOnTop( false );
+ ( (WindowPeer) peer ).toBack();
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-31 21:51:51
|
Revision: 3100
http://jnode.svn.sourceforge.net/jnode/?rev=3100&view=rev
Author: lsantha
Date: 2007-01-31 13:51:44 -0800 (Wed, 31 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/awt/DefaultKeyboardFocusManager.java
trunk/core/src/classpath/java/java/awt/KeyboardFocusManager.java
trunk/core/src/classpath/java/java/awt/TextArea.java
trunk/core/src/classpath/java/java/awt/TextComponent.java
trunk/core/src/classpath/java/java/awt/TextField.java
trunk/core/src/classpath/java/java/awt/Toolkit.java
Modified: trunk/core/src/classpath/java/java/awt/DefaultKeyboardFocusManager.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/DefaultKeyboardFocusManager.java 2007-01-31 20:25:09 UTC (rev 3099)
+++ trunk/core/src/classpath/java/java/awt/DefaultKeyboardFocusManager.java 2007-01-31 21:51:44 UTC (rev 3100)
@@ -256,6 +256,95 @@
return false;
}
+ /**
+ * Handles FOCUS_GAINED events in {@link #dispatchEvent(AWTEvent)}.
+ *
+ * @param fe the focus event
+ */
+ private boolean handleFocusGained(FocusEvent fe)
+ {
+ Component target = fe.getComponent ();
+
+ // If old focus owner != new focus owner, notify old focus
+ // owner that it has lost focus.
+ Component oldFocusOwner = getGlobalFocusOwner();
+ if (oldFocusOwner != null && oldFocusOwner != target)
+ {
+ FocusEvent lost = new FocusEvent(oldFocusOwner,
+ FocusEvent.FOCUS_LOST,
+ fe.isTemporary(), target);
+ oldFocusOwner.dispatchEvent(lost);
+ }
+
+ setGlobalFocusOwner (target);
+ if (target != getGlobalFocusOwner())
+ {
+ // Focus transfer was rejected, like when the target is not
+ // focusable.
+ dequeueKeyEvents(-1, target);
+ // FIXME: Restore focus somehow.
+ }
+ else
+ {
+ if (! fe.isTemporary())
+ {
+ setGlobalPermanentFocusOwner (target);
+ if (target != getGlobalPermanentFocusOwner())
+ {
+ // Focus transfer was rejected, like when the target is not
+ // focusable.
+ dequeueKeyEvents(-1, target);
+ // FIXME: Restore focus somehow.
+ }
+ else
+ {
+ redispatchEvent(target, fe);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Handles FOCUS_LOST events for {@link #dispatchEvent(AWTEvent)}.
+ *
+ * @param fe the focus event
+ *
+ * @return if the event has been handled
+ */
+ private boolean handleFocusLost(FocusEvent fe)
+ {
+ Component currentFocus = getGlobalFocusOwner();
+ if (currentFocus != fe.getOppositeComponent())
+ {
+ setGlobalFocusOwner(null);
+ if (getGlobalFocusOwner() != null)
+ {
+ // TODO: Is this possible? If so, then we should try to restore
+ // the focus.
+ }
+ else
+ {
+ if (! fe.isTemporary())
+ {
+ setGlobalPermanentFocusOwner(null);
+ if (getGlobalPermanentFocusOwner() != null)
+ {
+ // TODO: Is this possible? If so, then we should try to
+ // restore the focus.
+ }
+ else
+ {
+ fe.setSource(currentFocus);
+ redispatchEvent(currentFocus, fe);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
private boolean enqueueKeyEvent (KeyEvent e)
{
Iterator i = delayRequests.iterator ();
Modified: trunk/core/src/classpath/java/java/awt/KeyboardFocusManager.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/KeyboardFocusManager.java 2007-01-31 20:25:09 UTC (rev 3099)
+++ trunk/core/src/classpath/java/java/awt/KeyboardFocusManager.java 2007-01-31 21:51:44 UTC (rev 3100)
@@ -561,7 +561,9 @@
* @see #UP_CYCLE_TRAVERSAL_KEYS
* @see #DOWN_CYCLE_TRAVERSAL_KEYS
*/
- public void setDefaultFocusTraversalKeys (int id, Set keystrokes)
+ public void setDefaultFocusTraversalKeys (int id,
+ Set<? extends AWTKeyStroke>
+ keystrokes)
{
if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
@@ -633,7 +635,7 @@
* @see #UP_CYCLE_TRAVERSAL_KEYS
* @see #DOWN_CYCLE_TRAVERSAL_KEYS
*/
- public Set getDefaultFocusTraversalKeys (int id)
+ public Set<AWTKeyStroke> getDefaultFocusTraversalKeys (int id)
{
if (id < FORWARD_TRAVERSAL_KEYS || id > DOWN_CYCLE_TRAVERSAL_KEYS)
throw new IllegalArgumentException ();
@@ -995,9 +997,9 @@
* @return A list of explicitly registered key event dispatchers.
* @see KeyboardFocusManager#addKeyEventDispatcher(java.awt.KeyEventDispatcher)
*/
- protected List getKeyEventDispatchers ()
+ protected List<KeyEventDispatcher> getKeyEventDispatchers ()
{
- return (List) keyEventDispatchers.clone ();
+ return (List<KeyEventDispatcher>) keyEventDispatchers.clone ();
}
/**
@@ -1052,9 +1054,9 @@
* @return A list of explicitly registered key event post processors.
* @see KeyboardFocusManager#addKeyEventPostProcessor(java.awt.KeyEventPostProcessor)
*/
- protected List getKeyEventPostProcessors ()
+ protected List<KeyEventPostProcessor> getKeyEventPostProcessors ()
{
- return (List) keyEventPostProcessors.clone ();
+ return (List<KeyEventPostProcessor>) keyEventPostProcessors.clone ();
}
/**
@@ -1436,4 +1438,48 @@
}
}
}
+
+
+ /**
+ * Maps focus requests from heavyweight to lightweight components.
+ */
+ private static HashMap focusRequests = new HashMap();
+
+ /**
+ * Retargets focus events that come from the peer (which only know about
+ * heavyweight components) to go to the correct lightweight component
+ * if appropriate.
+ *
+ * @param ev the event to check
+ *
+ * @return the retargetted event
+ */
+ static AWTEvent retargetFocusEvent(AWTEvent ev)
+ {
+ if (ev instanceof FocusEvent)
+ {
+ FocusEvent fe = (FocusEvent) ev;
+ Component target = fe.getComponent();
+ if (focusRequests.containsKey(target))
+ {
+ Component lightweight = (Component) focusRequests.get(target);
+ ev = new FocusEvent(lightweight, fe.id, fe.isTemporary());
+ focusRequests.remove(target);
}
+ }
+ return ev;
+ }
+
+ /**
+ * Adds a lightweight focus request for a heavyweight component.
+ *
+ * @param heavyweight the heavyweight from which we will receive a focus
+ * event soon
+ * @param lightweight the lightweight that ultimately receives the request
+ */
+ static void addLightweightFocusRequest(Component heavyweight,
+ Component lightweight)
+ {
+ focusRequests.put(heavyweight, lightweight);
+ }
+}
Modified: trunk/core/src/classpath/java/java/awt/TextArea.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/TextArea.java 2007-01-31 20:25:09 UTC (rev 3099)
+++ trunk/core/src/classpath/java/java/awt/TextArea.java 2007-01-31 21:51:44 UTC (rev 3100)
@@ -125,9 +125,11 @@
* the specified text. Conceptually the <code>TextArea</code> has 0
* rows and 0 columns but its initial bounds are defined by its peer
* or by the container in which it is packed. Both horizontal and
- * veritcal scrollbars will be displayed.
+ * veritcal scrollbars will be displayed. The TextArea initially contains
+ * the specified text. If text specified as <code>null<code>, it will
+ * be set to "".
*
- * @param text The text to display in this text area.
+ * @param text The text to display in this text area (<code>null</code> permitted).
*
* @exception HeadlessException if GraphicsEnvironment.isHeadless () is true
*/
@@ -156,9 +158,10 @@
* Initialize a new instance of <code>TextArea</code> that can
* display the specified number of rows and columns of text, without
* the need to scroll. The TextArea initially contains the
- * specified text.
+ * specified text. If text specified as <code>null<code>, it will
+ * be set to "".
*
- * @param text The text to display in this text area.
+ * @param text The text to display in this text area (<code>null</code> permitted).
* @param rows The number of rows in this text area.
* @param columns The number of columns in this text area.
*
@@ -174,9 +177,10 @@
* contains the specified text. The TextArea can display the
* specified number of rows and columns of text, without the need to
* scroll. This constructor allows specification of the scroll bar
- * display policy.
+ * display policy. The TextArea initially contains the specified text.
+ * If text specified as <code>null<code>, it will be set to "".
*
- * @param text The text to display in this text area.
+ * @param text The text to display in this text area (<code>null</code> permitted).
* @param rows The number of rows in this text area.
* @param columns The number of columns in this text area.
* @param scrollbarVisibility The scroll bar display policy. One of
@@ -192,17 +196,19 @@
if (GraphicsEnvironment.isHeadless ())
throw new HeadlessException ();
- if (rows < 0 || columns < 0)
- throw new IllegalArgumentException ("Bad row or column value");
+ if (rows < 0)
+ this.rows = 0;
+ else
+ this.rows = rows;
- if (scrollbarVisibility != SCROLLBARS_BOTH
- && scrollbarVisibility != SCROLLBARS_VERTICAL_ONLY
- && scrollbarVisibility != SCROLLBARS_HORIZONTAL_ONLY
- && scrollbarVisibility != SCROLLBARS_NONE)
- throw new IllegalArgumentException ("Bad scrollbar visibility value");
+ if (columns < 0)
+ this.columns = 0;
+ else
+ this.columns = columns;
- this.rows = rows;
- this.columns = columns;
+ if (scrollbarVisibility < 0 || scrollbarVisibility > 4)
+ this.scrollbarVisibility = SCROLLBARS_BOTH;
+ else
this.scrollbarVisibility = scrollbarVisibility;
// TextAreas need to receive tab key events so we override the
@@ -278,11 +284,7 @@
}
/**
- * Retrieve the minimum size for this text area, considering the
- * text area's current row and column values. A text area's minimum
- * size depends on the number of rows and columns of text it would
- * prefer to display, and on the size of the font in which the text
- * would be displayed.
+ * Retrieve the minimum size for this text area.
*
* @return The minimum size for this text field.
*/
@@ -292,11 +294,8 @@
}
/**
- * Retrieve the minimum size that this text area would have if its
- * row and column values were equal to those specified. A text
- * area's minimum size depends on the number of rows and columns of
- * text it would prefer to display, and on the size of the font in
- * which the text would be displayed.
+ * Retrieve the minimum size for this text area. If the minimum
+ * size has been set, then rows and columns are used in the calculation.
*
* @param rows The number of rows to use in the minimum size
* calculation.
@@ -311,11 +310,7 @@
}
/**
- * Retrieve the minimum size for this text area, considering the
- * text area's current row and column values. A text area's minimum
- * size depends on the number of rows and columns of text it would
- * prefer to display, and on the size of the font in which the text
- * would be displayed.
+ * Retrieve the minimum size for this text area.
*
* @return The minimum size for this text area.
*
@@ -328,11 +323,8 @@
}
/**
- * Retrieve the minimum size that this text area would have if its
- * row and column values were equal to those specified. A text
- * area's minimum size depends on the number of rows and columns of
- * text it would prefer to display, and on the size of the font in
- * which the text would be displayed.
+ * Retrieve the minimum size for this text area. If the minimum
+ * size has been set, then rows and columns are used in the calculation.
*
* @param rows The number of rows to use in the minimum size
* calculation.
@@ -346,21 +338,18 @@
*/
public Dimension minimumSize (int rows, int columns)
{
+ if (isMinimumSizeSet())
+ return new Dimension(minSize);
+
TextAreaPeer peer = (TextAreaPeer) getPeer ();
-
- // Sun returns Dimension (0,0) in this case.
if (peer == null)
- return new Dimension (0, 0);
+ return new Dimension (getWidth(), getHeight());
return peer.getMinimumSize (rows, columns);
}
/**
- * Retrieve the preferred size for this text area, considering the
- * text area's current row and column values. A text area's preferred
- * size depends on the number of rows and columns of text it would
- * prefer to display, and on the size of the font in which the text
- * would be displayed.
+ * Retrieve the preferred size for this text area.
*
* @return The preferred size for this text field.
*/
@@ -370,11 +359,8 @@
}
/**
- * Retrieve the preferred size that this text area would have if its
- * row and column values were equal to those specified. A text
- * area's preferred size depends on the number of rows and columns
- * of text it would prefer to display, and on the size of the font
- * in which the text would be displayed.
+ * Retrieve the preferred size for this text area. If the preferred
+ * size has been set, then rows and columns are used in the calculation.
*
* @param rows The number of rows to use in the preferred size
* calculation.
@@ -389,11 +375,7 @@
}
/**
- * Retrieve the preferred size for this text area, considering the
- * text area's current row and column values. A text area's preferred
- * size depends on the number of rows and columns of text it would
- * prefer to display, and on the size of the font in which the text
- * would be displayed.
+ * Retrieve the preferred size for this text area.
*
* @return The preferred size for this text field.
*
@@ -406,11 +388,8 @@
}
/**
- * Retrieve the preferred size that this text area would have if its
- * row and column values were equal to those specified. A text
- * area's preferred size depends on the number of rows and columns
- * of text it would prefer to display, and on the size of the font
- * in which the text would be displayed.
+ * Retrieve the preferred size for this text area. If the preferred
+ * size has been set, then rows and columns are used in the calculation.
*
* @param rows The number of rows to use in the preferred size
* calculation.
@@ -424,11 +403,12 @@
*/
public Dimension preferredSize (int rows, int columns)
{
+ if (isPreferredSizeSet())
+ return new Dimension(prefSize);
+
TextAreaPeer peer = (TextAreaPeer) getPeer ();
-
- // Sun returns Dimension (0,0) in this case.
if (peer == null)
- return new Dimension (0, 0);
+ return new Dimension (getWidth(), getHeight());
return peer.getPreferredSize (rows, columns);
}
@@ -478,6 +458,8 @@
if (peer != null)
peer.insert (str, peer.getText().length ());
+ else
+ setText(getText() + str);
}
/**
@@ -504,11 +486,20 @@
*/
public void insertText (String str, int pos)
{
+ String tmp1 = null;
+ String tmp2 = null;
+
TextAreaPeer peer = (TextAreaPeer) getPeer ();
if (peer != null)
peer.insert (str, pos);
+ else
+ {
+ tmp1 = getText().substring(0, pos);
+ tmp2 = getText().substring(pos, getText().length());
+ setText(tmp1 + str + tmp2);
}
+ }
/**
* Replace a range of characters with the specified text. The
@@ -544,11 +535,20 @@
*/
public void replaceText (String str, int start, int end)
{
- TextAreaPeer peer = (TextAreaPeer) getPeer ();
+ String tmp1 = null;
+ String tmp2 = null;
+ TextAreaPeer peer = (TextAreaPeer) getPeer();
+
if (peer != null)
- peer.replaceRange (str, start, end);
+ peer.replaceRange(str, start, end);
+ else
+ {
+ tmp1 = getText().substring(0, start);
+ tmp2 = getText().substring(end, getText().length());
+ setText(tmp1 + str + tmp2);
}
+ }
/**
* Retrieve a debugging string for this text area.
Modified: trunk/core/src/classpath/java/java/awt/TextComponent.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/TextComponent.java 2007-01-31 20:25:09 UTC (rev 3099)
+++ trunk/core/src/classpath/java/java/awt/TextComponent.java 2007-01-31 21:51:44 UTC (rev 3100)
@@ -1,5 +1,5 @@
/* TextComponent.java -- Widgets for entering text
- Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -63,45 +63,36 @@
implements Serializable, Accessible
{
-/*
- * Static Variables
- */
+ private static final long serialVersionUID = -2214773872412987419L;
-// Constant for serialization
-private static final long serialVersionUID = -2214773872412987419L;
-
-/*
- * Instance Variables
- */
-
-/**
+ /**
* @serial Indicates whether or not this component is editable.
* This is package-private to avoid an accessor method.
*/
-boolean editable;
+ boolean editable;
-/**
+ /**
* @serial The starting position of the selected text region.
* This is package-private to avoid an accessor method.
*/
-int selectionStart;
+ int selectionStart;
-/**
+ /**
* @serial The ending position of the selected text region.
* This is package-private to avoid an accessor method.
*/
-int selectionEnd;
+ int selectionEnd;
-/**
+ /**
* @serial The text in the component
* This is package-private to avoid an accessor method.
*/
-String text;
+ String text;
-/**
+ /**
* A list of listeners that will receive events from this object.
*/
-protected transient TextListener textListener;
+ protected transient TextListener textListener;
protected class AccessibleAWTTextComponent
extends AccessibleAWTComponent
@@ -318,146 +309,121 @@
}
-/*************************************************************************/
-/*
- * Constructors
- */
-
-TextComponent(String text)
-{
+ TextComponent(String text)
+ {
+ if (text == null)
+ this.text = "";
+ else
this.text = text;
+
this.editable = true;
-}
+ }
-/*************************************************************************/
-/*
- * Instance Methods
- */
-
-/**
+ /**
* Returns the text in this component
*
* @return The text in this component.
*/
-public synchronized String
-getText()
-{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ public synchronized String getText()
+ {
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
text = tcp.getText();
return(text);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Sets the text in this component to the specified string.
*
* @param text The new text for this component.
*/
-public synchronized void
-setText(String text)
-{
+ public synchronized void setText(String text)
+ {
if (text == null)
text = "";
this.text = text;
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
tcp.setText(text);
setCaretPosition(0);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns a string that contains the text that is currently selected.
*
* @return The currently selected text region.
*/
-public synchronized String
-getSelectedText()
-{
+ public synchronized String getSelectedText()
+ {
String alltext = getText();
int start = getSelectionStart();
int end = getSelectionEnd();
return(alltext.substring(start, end));
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the starting position of the selected text region.
* If the text is not selected then caret position is returned.
*
* @return The starting position of the selected text region.
*/
-public synchronized int
-getSelectionStart()
-{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ public synchronized int getSelectionStart()
+ {
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
selectionStart = tcp.getSelectionStart();
return(selectionStart);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Sets the starting position of the selected region to the
* specified value. If the specified value is out of range, then it
* will be silently changed to the nearest legal value.
*
* @param selectionStart The new start position for selected text.
*/
-public synchronized void
-setSelectionStart(int selectionStart)
-{
- select(selectionStart, getSelectionEnd());
-}
+ public synchronized void setSelectionStart(int selectionStart)
+ {
+ select(selectionStart,
+ (getSelectionEnd() < selectionStart)
+ ? selectionStart : getSelectionEnd());
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the ending position of the selected text region.
* If the text is not selected, then caret position is returned
*
* @return The ending position of the selected text region.
*/
-public synchronized int
-getSelectionEnd()
-{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ public synchronized int getSelectionEnd()
+ {
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
selectionEnd = tcp.getSelectionEnd();
return(selectionEnd);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Sets the ending position of the selected region to the
* specified value. If the specified value is out of range, then it
* will be silently changed to the nearest legal value.
*
* @param selectionEnd The new start position for selected text.
*/
-public synchronized void
-setSelectionEnd(int selectionEnd)
-{
+ public synchronized void setSelectionEnd(int selectionEnd)
+ {
select(getSelectionStart(), selectionEnd);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* This method sets the selected text range to the text between the
* specified start and end positions. Illegal values for these
* positions are silently fixed.
@@ -465,9 +431,8 @@
* @param selectionStart The new start position for the selected text.
* @param selectionEnd The new end position for the selected text.
*/
-public synchronized void
-select(int selectionStart, int selectionEnd)
-{
+ public synchronized void select(int selectionStart, int selectionEnd)
+ {
if (selectionStart < 0)
selectionStart = 0;
@@ -483,42 +448,34 @@
this.selectionStart = selectionStart;
this.selectionEnd = selectionEnd;
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
tcp.select(selectionStart, selectionEnd);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Selects all of the text in the component.
*/
-public synchronized void
-selectAll()
-{
+ public synchronized void selectAll()
+ {
select(0, getText().length());
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the current caret position in the text.
*
* @return The caret position in the text.
*/
-public synchronized int
-getCaretPosition()
-{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ public synchronized int getCaretPosition()
+ {
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
return(tcp.getCaretPosition());
else
return(0);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Sets the caret position to the specified value.
*
* @param caretPosition The new caret position.
@@ -528,111 +485,90 @@
*
* @since 1.1
*/
-public synchronized void
-setCaretPosition(int caretPosition)
-{
+ public synchronized void setCaretPosition(int caretPosition)
+ {
if (caretPosition < 0)
- throw new IllegalArgumentException ();
+ throw new IllegalArgumentException();
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
tcp.setCaretPosition(caretPosition);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Tests whether or not this component's text can be edited.
*
* @return <code>true</code> if the text can be edited, <code>false</code>
* otherwise.
*/
-public boolean
-isEditable()
-{
+ public boolean isEditable()
+ {
return(editable);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Sets whether or not this component's text can be edited.
*
* @param editable <code>true</code> to enable editing of the text,
* <code>false</code> to disable it.
*/
-public synchronized void
-setEditable(boolean editable)
-{
+ public synchronized void setEditable(boolean editable)
+ {
this.editable = editable;
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
tcp.setEditable(editable);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Notifies the component that it should destroy its native peer.
*/
-public void
-removeNotify()
-{
+ public void removeNotify()
+ {
super.removeNotify();
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Adds a new listener to the list of text listeners for this
* component.
*
* @param listener The listener to be added.
*/
-public synchronized void
-addTextListener(TextListener listener)
-{
+ public synchronized void addTextListener(TextListener listener)
+ {
textListener = AWTEventMulticaster.add(textListener, listener);
enableEvents(AWTEvent.TEXT_EVENT_MASK);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Removes the specified listener from the list of listeners
* for this component.
*
* @param listener The listener to remove.
*/
-public synchronized void
-removeTextListener(TextListener listener)
-{
+ public synchronized void removeTextListener(TextListener listener)
+ {
textListener = AWTEventMulticaster.remove(textListener, listener);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Processes the specified event for this component. Text events are
* processed by calling the <code>processTextEvent()</code> method.
* All other events are passed to the superclass method.
*
* @param event The event to process.
*/
-protected void
-processEvent(AWTEvent event)
-{
+ protected void processEvent(AWTEvent event)
+ {
if (event instanceof TextEvent)
processTextEvent((TextEvent)event);
else
super.processEvent(event);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Processes the specified text event by dispatching it to any listeners
* that are registered. Note that this method will only be called
* if text event's are enabled. This will be true if there are any
@@ -641,16 +577,14 @@
*
* @param event The text event to process.
*/
-protected void
-processTextEvent(TextEvent event)
-{
+ protected void processTextEvent(TextEvent event)
+ {
if (textListener != null)
textListener.textValueChanged(event);
-}
+ }
-void
-dispatchEventImpl(AWTEvent e)
-{
+ void dispatchEventImpl(AWTEvent e)
+ {
if (e.id <= TextEvent.TEXT_LAST
&& e.id >= TextEvent.TEXT_FIRST
&& (textListener != null
@@ -658,20 +592,17 @@
processEvent(e);
else
super.dispatchEventImpl(e);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns a debugging string.
*
* @return A debugging string.
*/
-protected String
-paramString()
-{
+ protected String paramString()
+ {
return(getClass().getName() + "(text=" + getText() + ")");
-}
+ }
/**
* Returns an array of all the objects currently registered as FooListeners
@@ -681,20 +612,20 @@
* @exception ClassCastException If listenerType doesn't specify a class or
* interface that implements java.util.EventListener.
*/
- public EventListener[] getListeners (Class listenerType)
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
{
if (listenerType == TextListener.class)
- return AWTEventMulticaster.getListeners (textListener, listenerType);
+ return AWTEventMulticaster.getListeners(textListener, listenerType);
- return super.getListeners (listenerType);
+ return super.getListeners(listenerType);
}
/**
* Returns all text listeners registered to this object.
*/
- public TextListener[] getTextListeners ()
+ public TextListener[] getTextListeners()
{
- return (TextListener[]) getListeners (TextListener.class);
+ return (TextListener[]) getListeners(TextListener.class);
}
/**
@@ -712,30 +643,35 @@
}
- /*******************************/
// Provide AccessibleAWTTextComponent access to several peer functions that
// aren't publicly exposed. This is package-private to avoid an accessor
// method.
- synchronized int
- getIndexAtPoint(Point p)
+ synchronized int getIndexAtPoint(Point p)
{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
return tcp.getIndexAtPoint(p.x, p.y);
return -1;
}
- synchronized Rectangle
- getCharacterBounds(int i)
+ synchronized Rectangle getCharacterBounds(int i)
{
- TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ TextComponentPeer tcp = (TextComponentPeer) getPeer();
if (tcp != null)
return tcp.getCharacterBounds(i);
return null;
}
-
+ /**
+ * All old mouse events for this component should
+ * be ignored.
+ *
+ * @return true to ignore all old mouse events.
+ */
+ static boolean ignoreOldMouseEvents()
+ {
+ return true;
+ }
-
} // class TextComponent
Modified: trunk/core/src/classpath/java/java/awt/TextField.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/TextField.java 2007-01-31 20:25:09 UTC (rev 3099)
+++ trunk/core/src/classpath/java/java/awt/TextField.java 2007-01-31 21:51:44 UTC (rev 3100)
@@ -1,5 +1,5 @@
/* TextField.java -- A one line text entry field
- Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -55,53 +55,40 @@
public class TextField extends TextComponent
{
-/*
- * Static Variables
+ /**
+ * The number used to generate the name returned by getName.
*/
+ private static transient long next_textfield_number;
-// Serialization constant
-private static final long serialVersionUID = -2966288784432217853L;
-/*************************************************************************/
+ private static final long serialVersionUID = -2966288784432217853L;
-/*
- * Instance Variables
- */
-/**
+ /**
* @serial The number of columns in the text entry field.
*/
-private int columns;
+ private int columns;
-/**
+ /**
* @serial The character that is echoed when doing protected input
*/
-private char echoChar;
+ private char echoChar;
-// List of registered ActionListener's for this object.
-private ActionListener action_listeners;
+ // List of registered ActionListener's for this object.
+ private ActionListener action_listeners;
-/*************************************************************************/
-
-/*
- * Constructors
- */
-
-/**
+ /**
* Initializes a new instance of <code>TextField</code> that is empty
* and has one column.
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
*/
-public
-TextField()
-{
- this("", 1);
-}
+ public TextField()
+ {
+ this("", 0);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Initializes a new instance of <code>TextField</code> containing
* the specified text. The number of columns will be equal to the
* length of the text string.
@@ -110,15 +97,12 @@
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
*/
-public
-TextField(String text)
-{
- this(text, text.length());
-}
+ public TextField(String text)
+ {
+ this(text, (text == null) ? 0 : text.length());
+ }
-/*************************************************************************/
-
-/**
+ /**
* Initializes a new instance of <code>TextField</code> that is empty
* and has the specified number of columns.
*
@@ -126,15 +110,12 @@
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
*/
-public
-TextField(int columns)
-{
+ public TextField(int columns)
+ {
this("", columns);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Initializes a new instance of <code>TextField</code> with the
* specified text and number of columns.
*
@@ -143,84 +124,69 @@
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true,
*/
-public
-TextField(String text, int columns)
-{
+ public TextField(String text, int columns)
+ {
super(text);
+
+ if (columns < 0)
+ this.columns = 0;
+ else
this.columns = columns;
if (GraphicsEnvironment.isHeadless())
throw new HeadlessException ();
-}
+ }
-/*************************************************************************/
-
-/*
- * Instance Methods
- */
-
-/**
+ /**
* Returns the number of columns in the field.
*
* @return The number of columns in the field.
*/
-public int
-getColumns()
-{
+ public int getColumns()
+ {
return(columns);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Sets the number of columns in this field to the specified value.
*
* @param columns The new number of columns in the field.
*
* @exception IllegalArgumentException If columns is less than zero.
*/
-public synchronized void
-setColumns(int columns)
-{
+ public synchronized void setColumns(int columns)
+ {
if (columns < 0)
throw new IllegalArgumentException("Value is less than zero: " +
columns);
this.columns = columns;
// FIXME: How to we communicate this to our peer?
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the character that is echoed to the screen when a text
* field is protected (such as when a password is being entered).
*
* @return The echo character for this text field.
*/
-public char
-getEchoChar()
-{
+ public char getEchoChar()
+ {
return(echoChar);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Sets the character that is echoed when protected input such as
* a password is displayed.
*
* @param echoChar The new echo character.
*/
-public void
-setEchoChar(char echoChar)
-{
- setEchoCharacter (echoChar);
-}
+ public void setEchoChar(char echoChar)
+ {
+ setEchoCharacter(echoChar);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Sets the character that is echoed when protected input such as
* a password is displayed.
*
@@ -229,64 +195,52 @@
* @deprecated This method is deprecated in favor of
* <code>setEchoChar()</code>
*/
-public void
-setEchoCharacter(char echoChar)
-{
+ public void setEchoCharacter(char echoChar)
+ {
this.echoChar = echoChar;
TextFieldPeer peer = (TextFieldPeer) getPeer ();
if (peer != null)
peer.setEchoChar (echoChar);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Tests whether or not this text field has an echo character set
* so that characters the user type are not echoed to the screen.
*
* @return <code>true</code> if an echo character is set,
* <code>false</code> otherwise.
*/
-public boolean
-echoCharIsSet()
-{
+ public boolean echoCharIsSet()
+ {
if (echoChar == '\u0000')
return(false);
else
return(true);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the minimum size for this text field.
*
* @return The minimum size for this text field.
*/
-public Dimension
-getMinimumSize()
-{
+ public Dimension getMinimumSize()
+ {
return getMinimumSize (getColumns ());
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the minimum size of a text field with the specified number
* of columns.
*
* @param columns The number of columns to get the minimum size for.
*/
-public Dimension
-getMinimumSize(int columns)
-{
- return minimumSize (columns);
-}
+ public Dimension getMinimumSize(int columns)
+ {
+ return minimumSize(columns);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the minimum size for this text field.
*
* @return The minimum size for this text field.
@@ -294,15 +248,12 @@
* @deprecated This method is deprecated in favor of
* <code>getMinimumSize()</code>.
*/
-public Dimension
-minimumSize()
-{
- return minimumSize (getColumns ());
-}
+ public Dimension minimumSize()
+ {
+ return minimumSize(getColumns ());
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the minimum size of a text field with the specified number
* of columns.
*
@@ -311,46 +262,40 @@
* @deprecated This method is deprecated in favor of
* <code>getMinimumSize(int)</code>.
*/
-public Dimension
-minimumSize(int columns)
-{
+ public Dimension minimumSize(int columns)
+ {
+ if (isMinimumSizeSet())
+ return new Dimension(minSize);
+
TextFieldPeer peer = (TextFieldPeer) getPeer ();
if (peer == null)
- return null; // FIXME: What do we do if there is no peer?
+ return new Dimension(getWidth(), getHeight());
return peer.getMinimumSize (columns);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the preferred size for this text field.
*
* @return The preferred size for this text field.
*/
-public Dimension
-getPreferredSize()
-{
- return getPreferredSize (getColumns ());
-}
+ public Dimension getPreferredSize()
+ {
+ return getPreferredSize(getColumns ());
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the preferred size of a text field with the specified number
* of columns.
*
* @param columns The number of columns to get the preferred size for.
*/
-public Dimension
-getPreferredSize(int columns)
-{
- return preferredSize (columns);
-}
+ public Dimension getPreferredSize(int columns)
+ {
+ return preferredSize(columns);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the preferred size for this text field.
*
* @return The preferred size for this text field.
@@ -358,15 +303,12 @@
* @deprecated This method is deprecated in favor of
* <code>getPreferredSize()</code>.
*/
-public Dimension
-preferredSize()
-{
- return preferredSize (getColumns ());
-}
+ public Dimension preferredSize()
+ {
+ return preferredSize(getColumns ());
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the preferred size of a text field with the specified number
* of columns.
*
@@ -375,63 +317,55 @@
* @deprecated This method is deprecated in favor of
* <code>getPreferredSize(int)</code>.
*/
-public Dimension
-preferredSize(int columns)
-{
+ public Dimension preferredSize(int columns)
+ {
+ if (isPreferredSizeSet())
+ return new Dimension(prefSize);
+
TextFieldPeer peer = (TextFieldPeer) getPeer ();
if (peer == null)
- return new Dimension (0, 0);
+ return new Dimension (getWidth(), getHeight());
return peer.getPreferredSize (columns);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Notifies this object that it should create its native peer.
*/
-public void
-addNotify()
-{
+ public void addNotify()
+ {
if (getPeer() != null)
return;
setPeer((ComponentPeer)getToolkit().createTextField(this));
-}
+ super.addNotify();
+ }
-/*************************************************************************/
-
-/**
+ /**
* Addes a new listener to the list of action listeners for this
* object.
*
* @param listener The listener to add to the list.
*/
-public synchronized void
-addActionListener(ActionListener listener)
-{
+ public synchronized void addActionListener(ActionListener listener)
+ {
action_listeners = AWTEventMulticaster.add(action_listeners, listener);
enableEvents(AWTEvent.ACTION_EVENT_MASK);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Removes the specified listener from the list of action listeners
* for this object.
*
* @param listener The listener to remove from the list.
*/
-public synchronized void
-removeActionListener(ActionListener listener)
-{
+ public synchronized void removeActionListener(ActionListener listener)
+ {
action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Processes the specified event. If the event is an instance of
* <code>ActionEvent</code> then <code>processActionEvent()</code> is
* called to process it, otherwise the event is sent to the
@@ -439,18 +373,15 @@
*
* @param event The event to process.
*/
-protected void
-processEvent(AWTEvent event)
-{
+ protected void processEvent(AWTEvent event)
+ {
if (event instanceof ActionEvent)
processActionEvent((ActionEvent)event);
else
super.processEvent(event);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Processes an action event by calling any registered listeners.
* Note to subclasses: This method is not called unless action events
* are enabled on this object. This will be true if any listeners
@@ -459,16 +390,14 @@
*
* @param event The event to process.
*/
-protected void
-processActionEvent(ActionEvent event)
-{
+ protected void processActionEvent(ActionEvent event)
+ {
if (action_listeners != null)
action_listeners.actionPerformed(event);
-}
+ }
-void
-dispatchEventImpl(AWTEvent e)
-{
+ void dispatchEventImpl(AWTEvent e)
+ {
if (e.id <= ActionEvent.ACTION_LAST
&& e.id >= ActionEvent.ACTION_FIRST
&& (action_listeners != null
@@ -476,21 +405,18 @@
processEvent(e);
else
super.dispatchEventImpl(e);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns a debug string for this object.
*
* @return A debug string for this object.
*/
-protected String
-paramString()
-{
+ protected String paramString()
+ {
return(getClass().getName() + "(columns=" + getColumns() + ",echoChar=" +
getEchoChar());
-}
+ }
/**
* Returns an array of all the objects currently registered as FooListeners
@@ -502,7 +428,7 @@
*
* @since 1.3
*/
- public EventListener[] getListeners (Class listenerType)
+ public <T extends EventListener> T[] getListeners (Class<T> listenerType)
{
if (listenerType == ActionListener.class)
return AWTEventMulticaster.getListeners (action_listeners, listenerType);
@@ -521,6 +447,21 @@
return (ActionListener[]) getListeners (ActionListener.class);
}
+ /**
+ * Generate a unique name for this <code>TextField</code>.
+ *
+ * @return A unique name for this <code>TextField</code>.
+ */
+ String generateName()
+ {
+ return "textfield" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_textfield_number++;
+ }
+
protected class AccessibleAWTTextField extends AccessibleAWTTextComponent
{
private static final long serialVersionUID = 6219164359235943158L;
@@ -540,4 +481,4 @@
return new AccessibleAWTTextField();
}
-} // class TextField
+}
Modified: trunk/core/src/classpath/java/java/awt/Toolkit.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Toolkit.java 2007-01-31 20:25:09 UTC (rev 3099)
+++ trunk/core/src/classpath/java/java/awt/Toolkit.java 2007-01-31 21:51:44 UTC (rev 3100)
@@ -1,5 +1,5 @@
/* Toolkit.java -- AWT Toolkit superclass
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,7 +39,10 @@
package java.awt;
+import gnu.classpath.SystemProperties;
+import gnu.java.awt.AWTUtilities;
import gnu.java.awt.peer.GLightweightPeer;
+import gnu.java.awt.peer.headless.HeadlessToolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.dnd.DragGestureEvent;
@@ -50,6 +53,7 @@
import java.awt.event.AWTEventListener;
import java.awt.event.AWTEventListenerProxy;
import java.awt.event.KeyEvent;
+import java.awt.font.TextAttribute;
import java.awt.im.InputMethodHighlight;
import java.awt.image.ColorModel;
import java.awt.image.ImageObserver;
@@ -69,6 +73,7 @@
import java.awt.peer.MenuBarPeer;
import java.awt.peer.MenuItemPeer;
import java.awt.peer.MenuPeer;
+import java.awt.peer.MouseInfoPeer;
import java.awt.peer.PanelPeer;
import java.awt.peer.PopupMenuPeer;
import java.awt.peer.ScrollPanePeer;
@@ -76,13 +81,18 @@
import java.awt.peer.TextAreaPeer;
import java.awt.peer.TextFieldPeer;
import java.awt.peer.WindowPeer;
-import java.awt.peer.MouseInfoPeer;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
+import java.io.File;
+import java.io.FileInputStream;
import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
+import java.util.StringTokenizer;
/**
* The AWT system uses a set of native peer objects to implement its
@@ -113,7 +123,8 @@
/** The toolkit properties. */
private static Properties props = new Properties();
- protected final Map desktopProperties = new Properties();
+ protected final Map<String,Object> desktopProperties =
+ new Hashtable<String,Object>();
protected final PropertyChangeSupport desktopPropsSupport
= new PropertyChangeSupport(this);
@@ -541,11 +552,12 @@
*
* @throws AWTError If the toolkit cannot be loaded.
*/
- public static Toolkit getDefaultToolkit()
+ public static synchronized Toolkit getDefaultToolkit()
{
if (toolkit != null)
return toolkit;
- String toolkit_name = System.getProperty("awt.toolkit",
+
+ String toolkit_name = SystemProperties.getProperty("awt.toolkit",
default_toolkit_name);
try
{
@@ -559,6 +571,8 @@
throw new AWTError(toolkit_name + " is not a subclass of " +
"java.awt.Toolkit");
toolkit = (Toolkit) obj;
+
+ initAccessibility();
return toolkit;
}
catch (ThreadDeath death)
@@ -567,9 +581,19 @@
}
catch (Throwable t)
{
- AWTError e = new AWTError("Cannot load AWT toolkit: " + toolkit_name);
+ // Check for the headless property.
+ if (GraphicsEnvironment.isHeadless())
+ {
+ toolkit = new HeadlessToolkit();
+ return toolkit;
+ }
+ else
+ {
+ AWTError e = new AWTError("Cannot load AWT toolkit: "
+ + toolkit_name);
throw (AWTError) e.initCause(t);
- }
+ }
+ }
}
// @classpath-bugfix
@@ -711,6 +735,14 @@
public PrintJob getPrintJob(Frame frame, String title,
JobAttributes jobAttr, PageAttributes pageAttr)
{
+ // FIXME: it is possible this check may be removed
+ // if this method, when written, always delegates to
+ // getPrintJob(Frame, String, Properties).
+ SecurityManager sm;
+ sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPrintJobAccess();
+
return null;
}
@@ -775,12 +807,11 @@
*/
public boolean getLockingKeyState(int keyCode)
{
- if (keyCode != KeyEvent.VK_CAPS_LOCK
- && keyCode != KeyEvent.VK_NUM_LOCK
- && keyCode != KeyEvent.VK_SCROLL_LOCK)
- throw new IllegalArgumentException();
+ if (AWTUtilities.isValidKey(keyCode))
+ throw new UnsupportedOperationException
+ ("cannot get locking state of key code " + keyCode);
- throw new UnsupportedOperationException();
+ throw new IllegalArgumentException("invalid key code " + keyCode);
}
/**
@@ -959,8 +990,8 @@
/**
* @since 1.3
*/
- public DragGestureRecognizer
- createDragGestureRecognizer(Class recognizer, DragSource ds,
+ public <T extends DragGestureRecognizer> T
+ createDragGestureRecognizer(Class<T> recognizer, DragSource ds,
Component comp, int actions,
DragGestureListener l)
{
@@ -1247,5 +1278,140 @@
/**
* @since 1.3
*/
- public abstract Map mapInputMethodHighlight(InputMethodHighlight highlight);
+ public abstract Map<TextAttribute,?>
+ mapInputMethodHighlight(InputMethodHighlight highlight);
+
+ /**
+ * Initializes the accessibility framework. In particular, this loads the
+ * properties javax.accessibility.screen_magnifier_present and
+ * javax.accessibility.screen_reader_present and loads
+ * the classes specified in javax.accessibility.assistive_technologies.
+ */
+ private static void initAccessibility()
+ {
+ AccessController.doPrivileged
+ (new PrivilegedAction()
+ {
+ public Object run()
+ {
+ Properties props = new Properties();
+ String sep = File.separator;
+
+ // Try the user configuration.
+ try
+ {
+ File propsFile = new File(System.getProperty("user.home") + sep
+ + ".accessibility.properties");
+ FileInputStream in = new FileInputStream(propsFile);
+ props.load(in);
+ in.close();
+ }
+ catch (Exception ex)
+ {
+ // User configuration not present, ignore.
+ }
+
+ // Try the system configuration if there was no user configuration.
+ if (props.size() == 0)
+ {
+ try
+ {
+ File propsFile =
+ new File(System.getProperty("gnu.classpath.home.url")
+ + sep + "accessibility.properties");
+ FileInputStream in = new FileInputStream(propsFile);
+ props.load(in);
+ in.close();
+ }
+ catch (Exception ex)
+ {
+ // System configuration not present, ignore.
+ }
+ }
+
+ // Fetch the screen_magnifier_present property. Check systen properties
+ // first, then fallback to the configuration file.
+ String magPresent = SystemProperties.getProperty
+ ("javax.accessibility.screen_magnifier_present");
+ if (magPresent == null)
+ {
+ magPresent = props.getProperty("screen_magnifier_present");
+ if (magPresent != null)
+ {
+ SystemProperties.setProperty
+ ("javax.accessibility.screen_magnifier_present", magPresent);
+ }
+ }
+
+ // Fetch the screen_reader_present property. Check systen properties
+ // first, then fallback to the configuration file.
+ String readerPresent = SystemProperties.getProperty
+ ("javax.accessibility.screen_reader_present");
+ if (readerPresent == null)
+ {
+ readerPresent = props.getProperty("screen_reader_present");
+ if (readerPresent != null)
+ {
+ SystemProperties.setProperty
+ ("javax.accessibility.screen_reader_present", readerPresent);
+ }
+ }
+
+ // Fetch the list of classes to be loaded.
+ String classes = SystemProperties.getProperty
+ ("javax.accessibility.assistive_technologies");
+ if (classes == null)
+ {
+ classes = props.getProperty("assistive_technologies");
+ if (classes != null)
+ {
+ SystemProperties.setProperty
+ ("javax.accessibility.assistive_technologies", classes);
+ }
+ }
+
+ // Try to load the assisitive_technologies classes.
+ if (classes != null)
+ {
+ ClassLoader cl = ClassLoader.getSystemClassLoader();
+ StringTokenizer tokenizer = new StringTokenizer(classes, ",");
+ while (tokenizer.hasMoreTokens())
+ {
+ String className = tokenizer.nextToken();
+ try
+ {
+ Class atClass = cl.loadClass(className);
+ atClass.newInstance();
+ }
+ catch (ClassNotFoundException ex)
+ {
+ AWTError err = new AWTError("Assistive Technology class not"
+ + " found: " + className);
+ err.initCause(ex);
+ throw err;
+ }
+ catch (InstantiationException ex)
+ {
+ AWTError err =
+ new AWTError("Assistive Technology class cannot be "
+ + "instantiated: " + className);
+ err.initCause(ex);
+ throw err;
+ }
+ catch (IllegalAccessException ex)
+ {
+ AWTError err =
+ new AWTError("Assistive Technology class cannot be "
+ + "accessed: " + className);
+ err.initCause(err);
+ throw err;
+ }
+ }
+ }
+ return null;
+ }
+ });
+
+ }
+
} // class Toolkit
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-31 20:25:36
|
Revision: 3099
http://jnode.svn.sourceforge.net/jnode/?rev=3099&view=rev
Author: lsantha
Date: 2007-01-31 12:25:09 -0800 (Wed, 31 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/awt/Component.java
trunk/core/src/classpath/java/java/awt/Container.java
trunk/core/src/classpath/java/java/awt/ContainerOrderFocusTraversalPolicy.java
trunk/core/src/classpath/java/java/awt/EventDispatchThread.java
trunk/core/src/classpath/java/java/awt/EventQueue.java
trunk/core/src/classpath/java/java/awt/LightweightDispatcher.java
trunk/core/src/classpath/java/java/awt/Window.java
Modified: trunk/core/src/classpath/java/java/awt/Component.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Component.java 2007-01-31 19:02:43 UTC (rev 3098)
+++ trunk/core/src/classpath/java/java/awt/Component.java 2007-01-31 20:25:09 UTC (rev 3099)
@@ -1486,7 +1486,40 @@
}
}
- /**
+ /**
+ * Sends notification to interested listeners about resizing and/or moving
+ * the component. If this component has interested
+ * component listeners or the corresponding event mask enabled, then
+ * COMPONENT_MOVED and/or COMPONENT_RESIZED events are posted to the event
+ * queue.
+ *
+ * @param resized true if the component has been resized, false otherwise
+ * @param moved true if the component has been moved, false otherwise
+ */
+ void notifyReshape(boolean resized, boolean moved)
+ {
+ // Only post an event if this component actually has a listener
+ // or has this event explicitly enabled.
+ if (componentListener != null
+ || (eventMask & AWTEvent.COMPONENT_EVENT_MASK) != 0)
+ {
+ // Fire component event on this component.
+ if (moved)
+ {
+ ComponentEvent ce = new ComponentEvent(this,
+ ComponentEvent.COMPONENT_MOVED);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ if (resized)
+ {
+ ComponentEvent ce = new ComponentEvent(this,
+ ComponentEvent.COMPONENT_RESIZED);
+ getToolkit().getSystemEventQueue().postEvent(ce);
+ }
+ }
+ }
+
+ /**
* Sets the bounding rectangle for this component to the specified
* rectangle. Note that these coordinates are relative to the parent, not
* to the screen.
Modified: trunk/core/src/classpath/java/java/awt/Container.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Container.java 2007-01-31 19:02:43 UTC (rev 3098)
+++ trunk/core/src/classpath/java/java/awt/Container.java 2007-01-31 20:25:09 UTC (rev 3099)
@@ -1808,6 +1808,11 @@
}
}
+ /**
+ * Overridden to dispatch events to lightweight descendents.
+ *
+ * @param e the event to dispatch.
+ */
void dispatchEventImpl(AWTEvent e)
{
boolean dispatched =
@@ -1825,6 +1830,19 @@
}
/**
+ * This is called by the lightweight dispatcher to avoid recursivly
+ * calling into the lightweight dispatcher.
+ *
+ * @param e the event to dispatch
+ *
+ * @see LightweightDispatcher#redispatch(MouseEvent, Component, int)
+ */
+ void dispatchNoLightweight(AWTEvent e)
+ {
+ super.dispatchEventImpl(e);
+ }
+
+ /**
* Tests if this container has an interest in the given event id.
*
* @param eventId The event id to check.
@@ -1938,6 +1956,43 @@
parent.updateHierarchyListenerCount(type, delta);
}
+ /**
+ * Notifies interested listeners about resizing or moving the container.
+ * This performs the super behaviour (sending component events) and
+ * additionally notifies any hierarchy bounds listeners on child components.
+ *
+ * @param resized true if the component has been resized, false otherwise
+ * @param moved true if the component has been moved, false otherwise
+ */
+ void notifyReshape(boolean resized, boolean moved)
+ {
+ // Notify component listeners.
+ super.notifyReshape(resized, moved);
+
+ if (ncomponents > 0)
+ {
+ // Notify hierarchy bounds listeners.
+ if (resized)
+ {
+ for (int i = 0; i < getComponentCount(); i++)
+ {
+ Component child = getComponent(i);
+ child.fireHierarchyEvent(HierarchyEvent.ANCESTOR_RESIZED,
+ this, parent, 0);
+ }
+ }
+ if (moved)
+ {
+ for (int i = 0; i < getComponentCount(); i++)
+ {
+ Component child = getComponent(i);
+ child.fireHierarchyEvent(HierarchyEvent.ANCESTOR_MOVED,
+ this, parent, 0);
+ }
+ }
+ }
+ }
+
private void addNotifyContainerChildren()
{
synchronized (getTreeLock ())
Modified: trunk/core/src/classpath/java/java/awt/ContainerOrderFocusTraversalPolicy.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/ContainerOrderFocusTraversalPolicy.java 2007-01-31 19:02:43 UTC (rev 3098)
+++ trunk/core/src/classpath/java/java/awt/ContainerOrderFocusTraversalPolicy.java 2007-01-31 20:25:09 UTC (rev 3099)
@@ -346,29 +346,31 @@
|| !root.isDisplayable ())
return null;
- if (root.visible && root.isDisplayable() && root.enabled
- && root.focusable)
+ if (accept(root))
return root;
- Component[] componentArray = root.getComponents ();
-
- for (int i = 0; i < componentArray.length; i++)
+ int ncomponents = root.getComponentCount();
+ for (int i = 0; i < ncomponents; i++)
{
- Component component = componentArray [i];
-
- if (component.visible && component.isDisplayable() && component.enabled
- && component.focusable)
- return component;
-
- if (component instanceof Container)
+ Component component = root.getComponent(i);
+ if (component instanceof Container
+ && !((Container) component).isFocusCycleRoot())
{
- Component result = getFirstComponent ((Container) component);
-
- if (result != null
- && (result.visible && result.isDisplayable() && result.enabled && result.focusable))
- return result;
+ Component first = null;
+ Container cont = (Container) component;
+ if (cont.isFocusTraversalPolicyProvider())
+ {
+ FocusTraversalPolicy childPol = cont.getFocusTraversalPolicy();
+ first = childPol.getFirstComponent(cont);
}
+ else
+ first = getFirstComponent(cont);
+ if (first != null)
+ return first;
}
+ else if (accept(component))
+ return component;
+ }
return null;
}
Modified: trunk/core/src/classpath/java/java/awt/EventDispatchThread.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/EventDispatchThread.java 2007-01-31 19:02:43 UTC (rev 3098)
+++ trunk/core/src/classpath/java/java/awt/EventDispatchThread.java 2007-01-31 20:25:09 UTC (rev 3099)
@@ -73,6 +73,9 @@
// Ignore and use default.
}
setPriority(priority);
+
+ // Make sure that an event dispatch thread is never a daemon thread.
+ setDaemon(false);
}
public void run()
Modified: trunk/core/src/classpath/java/java/awt/EventQueue.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/EventQueue.java 2007-01-31 19:02:43 UTC (rev 3098)
+++ trunk/core/src/classpath/java/java/awt/EventQueue.java 2007-01-31 20:25:09 UTC (rev 3099)
@@ -39,6 +39,7 @@
package java.awt;
import gnu.java.awt.LowPriorityEvent;
+import gnu.java.awt.peer.NativeEventLoopRunningEvent;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
@@ -114,6 +115,7 @@
private long lastWhen = System.currentTimeMillis();
private EventDispatchThread dispatchThread = new EventDispatchThread(this);
+ private boolean nativeLoopRunning = false;
private boolean shutdown = false;
// @vm-specific allow JNode access from VMAwtAPI
@@ -130,17 +132,19 @@
// This is the exact self-shutdown condition specified in J2SE:
// http://java.sun.com/j2se/1.4.2/docs/api/java/awt/doc-files/AWTThreadIssues.html
-
- // FIXME: check somewhere that the native queue is empty
- if (peekEvent() == null)
- {
- Frame[] frames = Frame.getFrames();
- for (int i = 0; i < frames.length; ++i)
- if (frames[i].isDisplayable())
- return false;
- return true;
- }
+
+ if (nativeLoopRunning)
return false;
+
+ if (peekEvent() != null)
+ return false;
+
+ Frame[] frames = Frame.getFrames();
+ for (int i = 0; i < frames.length; ++i)
+ if (frames[i].isDisplayable())
+ return false;
+
+ return true;
}
/**
@@ -169,22 +173,26 @@
return next.getNextEvent();
AWTEvent res = getNextEventImpl(true);
+
while (res == null)
{
- // We are not allowed to return null from this method, yet it
- // is possible that we actually have run out of native events
- // in the enclosing while() loop, and none of the native events
- // happened to cause AWT events. We therefore ought to check
- // the isShutdown() condition here, before risking a "native
- // wait". If we check it before entering this function we may
- // wait forever for events after the shutdown condition has
- // arisen.
+ if (isShutdown())
+ {
+ // Explicitly set dispathThread to null. If we don't do
+ // this, there is a race condition where dispatchThread
+ // can be != null even after the event dispatch thread has
+ // stopped running. If that happens, then the
+ // dispatchThread == null check in postEventImpl will
+ // fail, and a new event dispatch thread will not be
+ // created, leaving invokeAndWaits waiting indefinitely.
+ dispatchThread = null;
- if (isShutdown())
+ // Interrupt the event dispatch thread.
throw new InterruptedException();
+ }
wait();
- res = getNextEventImpl(true);
+ res = getNextEventImpl(true);
}
return res;
@@ -298,6 +306,12 @@
priority = LOW_PRIORITY;
// TODO: Maybe let Swing RepaintManager events also be processed with
// low priority.
+ if (evt instanceof NativeEventLoopRunningEvent)
+ {
+ nativeLoopRunning = ((NativeEventLoopRunningEvent) evt).isRunning();
+ notify();
+ return;
+ }
postEventImpl(evt, priority);
}
Modified: trunk/core/src/classpath/java/java/awt/LightweightDispatcher.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/LightweightDispatcher.java 2007-01-31 19:02:43 UTC (rev 3098)
+++ trunk/core/src/classpath/java/java/awt/LightweightDispatcher.java 2007-01-31 20:25:09 UTC (rev 3099)
@@ -38,7 +38,10 @@
package java.awt;
+import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
+import java.awt.event.MouseWheelEvent;
+import java.awt.peer.LightweightPeer;
import java.util.WeakHashMap;
/**
@@ -49,7 +52,7 @@
*
* @author Roman Kennke (ke...@ai...)
*/
-class LightweightDispatcher
+final class LightweightDispatcher
{
/**
@@ -80,6 +83,11 @@
private Component lastTarget;
/**
+ * The current mouseEventTarget.
+ */
+ private Component mouseEventTarget;
+
+ /**
* Returns an instance of LightweightDispatcher for the current thread's
* thread group.
*
@@ -113,7 +121,7 @@
*
* @param event the event
*/
- public boolean dispatchEvent(AWTEvent event)
+ public boolean dispatchEvent(final AWTEvent event)
{
if (event instanceof MouseEvent && event.getSource() instanceof Window)
{
@@ -336,4 +344,138 @@
p.y -= offY;
return p;
}
+
+ /**
+ * Checks if the specified component would be interested in a mouse event.
+ *
+ * @param c the component to check
+ *
+ * @return <code>true</code> if the component has mouse listeners installed,
+ * <code>false</code> otherwise
+ */
+ private boolean isMouseListening(final Component c)
+ {
+ // Note: It is important to NOT check if the component is listening
+ // for a specific event (for instance, mouse motion events). The event
+ // gets dispatched to the component if the component is listening
+ // for ANY mouse event, even when the component is not listening for the
+ // specific type of event. There are applications that depend on this
+ // (sadly).
+ return c.mouseListener != null
+ || c.mouseMotionListener != null
+ || c.mouseWheelListener != null
+ || (c.eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0
+ || (c.eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0
+ || (c.eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0;
+ }
+
+ /**
+ * Tracks MOUSE_ENTERED and MOUSE_EXIT as well as MOUSE_MOVED and
+ * MOUSE_DRAGGED and creates synthetic MOUSE_ENTERED and MOUSE_EXITED for
+ * lightweight component.s
+ *
+ * @param target the current mouse event target
+ * @param ev the mouse event
+ */
+ private void trackEnterExit(final Component target, final MouseEvent ev)
+ {
+ int id = ev.getID();
+ if (target != lastTarget)
+ {
+ if (lastTarget != null)
+ redispatch(ev, lastTarget, MouseEvent.MOUSE_EXITED);
+ if (id == MouseEvent.MOUSE_EXITED)
+ ev.consume();
+ if (target != null)
+ redispatch(ev, target, MouseEvent.MOUSE_ENTERED);
+ if (id == MouseEvent.MOUSE_ENTERED)
+ ev.consume();
+ lastTarget = target;
+ }
+
+ }
+
+ /**
+ * Redispatches the specified mouse event to the specified target with the
+ * specified id.
+ *
+ * @param ev the mouse event
+ * @param target the new target
+ * @param id the new id
+ */
+ private void redispatch(MouseEvent ev, Component target, int id)
+ {
+ Component source = ev.getComponent();
+ if (target != null)
+ {
+ // Translate coordinates.
+ int x = ev.getX();
+ int y = ev.getY();
+ for (Component c = target; c != null && c != source; c = c.getParent())
+ {
+ x -= c.x;
+ y -= c.y;
+ }
+
+ // Retarget event.
+ MouseEvent retargeted;
+ if (id == MouseEvent.MOUSE_WHEEL)
+ {
+ MouseWheelEvent mwe = (MouseWheelEvent) ev;
+ retargeted = new MouseWheelEvent(target, id, ev.getWhen(),
+ ev.getModifiers()
+ | ev.getModifiersEx(), x, y,
+ ev.getClickCount(),
+ ev.isPopupTrigger(),
+ mwe.getScrollType(),
+ mwe.getScrollAmount(),
+ mwe.getWheelRotation());
+ }
+ else
+ {
+ retargeted = new MouseEvent(target, id, ev.getWhen(),
+ ev.getModifiers() | ev.getModifiersEx(),
+ x, y, ev.getClickCount(),
+ ev.isPopupTrigger(), ev.getButton());
+ }
+
+ if (target == source)
+ ((Container) target).dispatchNoLightweight(retargeted);
+ else
+ target.dispatchEvent(retargeted);
+ }
+ }
+
+ /**
+ * Determines if we are in the middle of a drag operation, that is, if
+ * any of the buttons is held down.
+ *
+ * @param ev the mouse event to check
+ *
+ * @return <code>true</code> if we are in the middle of a drag operation,
+ * <code>false</code> otherwise
+ */
+ private boolean isDragging(MouseEvent ev)
+ {
+ int mods = ev.getModifiersEx();
+ int id = ev.getID();
+ if (id == MouseEvent.MOUSE_PRESSED || id == MouseEvent.MOUSE_RELEASED)
+ {
+ switch (ev.getButton())
+ {
+ case MouseEvent.BUTTON1:
+ mods ^= InputEvent.BUTTON1_DOWN_MASK;
+ break;
+ case MouseEvent.BUTTON2:
+ mods ^= InputEvent.BUTTON2_DOWN_MASK;
+ break;
+ case MouseEvent.BUTTON3:
+ mods ^= InputEvent.BUTTON3_DOWN_MASK;
+ break;
+ }
+ }
+ return (mods & (InputEvent.BUTTON1_DOWN_MASK
+ | InputEvent.BUTTON2_DOWN_MASK
+ | InputEvent.BUTTON3_DOWN_MASK)) != 0;
+ }
}
Modified: trunk/core/src/classpath/java/java/awt/Window.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Window.java 2007-01-31 19:02:43 UTC (rev 3098)
+++ trunk/core/src/classpath/java/java/awt/Window.java 2007-01-31 20:25:09 UTC (rev 3099)
@@ -329,6 +329,15 @@
if (initialFocusOwner != null)
initialFocusOwner.requestFocusInWindow();
+ // Post WINDOW_OPENED from here.
+ if (windowListener != null
+ || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0)
+ {
+ WindowEvent ev = new WindowEvent(this,
+ WindowEvent.WINDOW_OPENED);
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ tk.getSystemEventQueue().postEvent(ev);
+ }
shown = true;
}
}
@@ -413,11 +422,8 @@
public void toFront()
{
if (peer != null)
- {
- WindowPeer wp = (WindowPeer) peer;
- wp.toFront();
+ ( (WindowPeer) peer ).toFront();
}
- }
/**
* Returns the toolkit used to create this window.
@@ -1146,6 +1152,47 @@
this.focusableWindowState = focusableWindowState;
}
+ /**
+ * Check whether this Container is a focus cycle root.
+ * Returns always <code>true</code> as Windows are the
+ * root of the focus cycle.
+ *
+ * @return Always <code>true</code>.
+ *
+ * @since 1.4
+ */
+ public final boolean isFocusCycleRoot()
+ {
+ return true;
+ }
+
+ /**
+ * Set whether or not this Container is the root of a focus
+ * traversal cycle. Windows are the root of the focus cycle
+ * and therefore this method does nothing.
+ *
+ * @param focusCycleRoot ignored.
+ *
+ * @since 1.4
+ */
+ public final void setFocusCycleRoot(boolean focusCycleRoot)
+ {
+ // calls to the method are ignored
+ }
+
+ /**
+ * Returns the root container that owns the focus cycle where this
+ * component resides. Windows have no ancestors and this method
+ * returns always <code>null</code>.
+ *
+ * @return Always <code>null</code>.
+ * @since 1.4
+ */
+ public final Container getFocusCycleRootAncestor()
+ {
+ return null;
+ }
+
// setBoundsCallback is needed so that when a user moves a window,
// the Window's location can be updated without calling the peer's
// setBounds method. When a user moves a window the peer window's
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-31 19:02:54
|
Revision: 3098
http://jnode.svn.sourceforge.net/jnode/?rev=3098&view=rev
Author: lsantha
Date: 2007-01-31 11:02:43 -0800 (Wed, 31 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/awt/Choice.java
trunk/core/src/classpath/java/java/awt/Component.java
trunk/core/src/classpath/java/java/awt/Container.java
trunk/core/src/classpath/java/java/awt/Frame.java
trunk/core/src/classpath/java/java/awt/Label.java
trunk/core/src/classpath/java/java/awt/List.java
trunk/core/src/classpath/java/java/awt/Menu.java
trunk/core/src/classpath/java/java/awt/ScrollPane.java
trunk/core/src/classpath/java/java/awt/ScrollPaneAdjustable.java
trunk/core/src/classpath/java/java/awt/Scrollbar.java
trunk/core/src/classpath/java/java/awt/Window.java
Modified: trunk/core/src/classpath/java/java/awt/Choice.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Choice.java 2007-01-28 21:36:49 UTC (rev 3097)
+++ trunk/core/src/classpath/java/java/awt/Choice.java 2007-01-31 19:02:43 UTC (rev 3098)
@@ -1,5 +1,5 @@
/* Choice.java -- Java choice button widget.
- Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -58,35 +58,31 @@
public class Choice extends Component
implements ItemSelectable, Serializable, Accessible
{
-
-/*
- * Static Variables
+ /**
+ * The number used to generate the name returned by getName.
*/
+ private static transient long next_choice_number;
-// Serialization constant
-private static final long serialVersionUID = -4075310674757313071L;
+ // Serialization constant
+ private static final long serialVersionUID = -4075310674757313071L;
-/*************************************************************************/
-
-/*
- * Instance Variables
- */
-
-/**
+ /**
* @serial A list of items for the choice box, which can be <code>null</code>.
* This is package-private to avoid an accessor method.
*/
-Vector pItems = new Vector();
+ Vector pItems = new Vector();
-/**
+ /**
* @serial The index of the selected item in the choice box.
*/
-private int selectedIndex = -1;
+ private int selectedIndex = -1;
-// Listener chain
-private ItemListener item_listeners;
+ /**
+ * ItemListener chain
+ */
+ private ItemListener item_listeners;
-/**
+ /**
* This class provides accessibility support for the
* combo box.
*
@@ -181,19 +177,12 @@
if (i < 0 || i >= pItems.size())
return false;
- Choice.this.processItemEvent(new ItemEvent(Choice.this,
- ItemEvent.ITEM_STATE_CHANGED,
- this, ItemEvent.SELECTED));
+ Choice.this.select( i );
+
return true;
}
}
-/*************************************************************************/
-
-/*
- * Constructors
- */
-
/**
* Initializes a new instance of <code>Choice</code>.
*
@@ -206,56 +195,41 @@
throw new HeadlessException ();
}
-/*************************************************************************/
-
-/*
- * Instance Methods
- */
-
-/**
+ /**
* Returns the number of items in the list.
*
* @return The number of items in the list.
*/
-public int
-getItemCount()
-{
+ public int getItemCount()
+ {
return countItems ();
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the number of items in the list.
*
* @return The number of items in the list.
*
* @deprecated This method is deprecated in favor of <code>getItemCount</code>.
*/
-public int
-countItems()
-{
- return(pItems.size());
-}
+ public int countItems()
+ {
+ return pItems.size();
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the item at the specified index in the list.
*
* @param index The index into the list to return the item from.
*
* @exception ArrayIndexOutOfBoundsException If the index is invalid.
*/
-public String
-getItem(int index)
-{
- return((String)pItems.elementAt(index));
-}
+ public String getItem(int index)
+ {
+ return (String)pItems.elementAt(index);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Adds the specified item to this choice box.
*
* @param item The item to add.
@@ -264,45 +238,36 @@
*
* @since 1.1
*/
-public synchronized void
-add(String item)
-{
+ public synchronized void add(String item)
+ {
if (item == null)
throw new NullPointerException ("item must be non-null");
pItems.addElement(item);
- int i = pItems.size () - 1;
if (peer != null)
- {
- ChoicePeer cp = (ChoicePeer) peer;
- cp.add (item, i);
- }
- else if (selectedIndex == -1)
- select(0);
-}
+ ((ChoicePeer) peer).add(item, getItemCount() - 1);
-/*************************************************************************/
+ if (selectedIndex == -1)
+ select( 0 );
+ }
-/**
+ /**
* Adds the specified item to this choice box.
*
- * This method is oboslete since Java 2 platform 1.1. Please use @see add
- * instead.
+ * This method is oboslete since Java 2 platform 1.1. Please use
+ * {@link #add(String)} instead.
*
* @param item The item to add.
*
* @exception NullPointerException If the item's value is equal to null
*/
-public synchronized void
-addItem(String item)
-{
+ public synchronized void addItem(String item)
+ {
add(item);
-}
+ }
-/*************************************************************************/
-
-/** Inserts an item into this Choice. Existing items are shifted
+ /** Inserts an item into this Choice. Existing items are shifted
* upwards. If the new item is the only item, then it is selected.
* If the currently selected item is shifted, then the first item is
* selected. If the currently selected item is not shifted, then it
@@ -313,9 +278,8 @@
*
* @exception IllegalArgumentException If index is less than 0
*/
-public synchronized void
-insert(String item, int index)
-{
+ public synchronized void insert(String item, int index)
+ {
if (index < 0)
throw new IllegalArgumentException ("index may not be less then 0");
@@ -325,75 +289,61 @@
pItems.insertElementAt(item, index);
if (peer != null)
- {
- ChoicePeer cp = (ChoicePeer) peer;
- cp.add (item, index);
- }
- else if (selectedIndex == -1 || selectedIndex >= index)
+ ((ChoicePeer) peer).add (item, index);
+
+ if (selectedIndex == -1 || selectedIndex >= index)
select(0);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Removes the specified item from the choice box.
*
* @param item The item to remove.
*
* @exception IllegalArgumentException If the specified item doesn't exist.
*/
-public synchronized void
-remove(String item)
-{
+ public synchronized void remove(String item)
+ {
int index = pItems.indexOf(item);
if (index == -1)
throw new IllegalArgumentException ("item \""
+ item + "\" not found in Choice");
remove(index);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Removes the item at the specified index from the choice box.
*
* @param index The index of the item to remove.
*
* @exception IndexOutOfBoundsException If the index is not valid.
*/
-public synchronized void
-remove(int index)
-{
- if ((index < 0) || (index > getItemCount()))
- throw new IllegalArgumentException("Bad index: " + index);
-
+ public synchronized void remove(int index)
+ {
pItems.removeElementAt(index);
if (peer != null)
- {
- ChoicePeer cp = (ChoicePeer) peer;
- cp.remove (index);
- }
- else
- {
- if (getItemCount() == 0)
+ ((ChoicePeer) peer).remove( index );
+
+ if( getItemCount() == 0 )
selectedIndex = -1;
- else if (index == selectedIndex)
- select(0);
- }
+ else
+ {
+ if( selectedIndex > index )
+ selectedIndex--;
+ else if( selectedIndex == index )
+ selectedIndex = 0;
- if (selectedIndex > index)
- --selectedIndex;
-}
+ if( peer != null )
+ ((ChoicePeer)peer).select( selectedIndex );
+ }
+ }
-/*************************************************************************/
-
-/**
+ /**
* Removes all of the objects from this choice box.
*/
-public synchronized void
-removeAll()
-{
+ public synchronized void removeAll()
+ {
if (getItemCount() <= 0)
return;
@@ -406,197 +356,159 @@
}
selectedIndex = -1;
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the currently selected item, or null if no item is
* selected.
*
* @return The currently selected item.
*/
-public synchronized String
-getSelectedItem()
-{
+ public synchronized String getSelectedItem()
+ {
return (selectedIndex == -1
? null
: ((String)pItems.elementAt(selectedIndex)));
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns an array with one row containing the selected item.
*
* @return An array containing the selected item.
*/
-public synchronized Object[]
-getSelectedObjects()
-{
+ public synchronized Object[] getSelectedObjects()
+ {
if (selectedIndex == -1)
return null;
Object[] objs = new Object[1];
objs[0] = pItems.elementAt(selectedIndex);
- return(objs);
-}
+ return objs;
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the index of the selected item.
*
* @return The index of the selected item.
*/
-public int
-getSelectedIndex()
-{
- return(selectedIndex);
-}
+ public int getSelectedIndex()
+ {
+ return selectedIndex;
+ }
-/*************************************************************************/
-
-/**
+ /**
* Forces the item at the specified index to be selected.
*
* @param index The index of the row to make selected.
*
* @exception IllegalArgumentException If the specified index is invalid.
*/
-public synchronized void
-select(int index)
-{
+ public synchronized void select(int index)
+ {
if ((index < 0) || (index >= getItemCount()))
throw new IllegalArgumentException("Bad index: " + index);
- if (pItems.size() > 0) {
+ if( selectedIndex == index )
+ return;
+
selectedIndex = index;
- ChoicePeer cp = (ChoicePeer) peer;
- if (cp != null) {
- cp.select(index);
+ if( peer != null )
+ ((ChoicePeer)peer).select( index );
}
- }
-}
-/*************************************************************************/
-
-/**
+ /**
* Forces the named item to be selected.
*
* @param item The item to be selected.
*
* @exception IllegalArgumentException If the specified item does not exist.
*/
-public synchronized void
-select(String item)
-{
+ public synchronized void select(String item)
+ {
int index = pItems.indexOf(item);
- if (index >= 0)
- select(index);
-}
+ if( index >= 0 )
+ select( index );
+ }
-/*************************************************************************/
-
-/**
+ /**
* Creates the native peer for this object.
*/
-public void
-addNotify()
-{
+ public void addNotify()
+ {
if (peer == null)
peer = getToolkit ().createChoice (this);
super.addNotify ();
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Adds the specified listener to the list of registered listeners for
* this object.
*
* @param listener The listener to add.
*/
-public synchronized void
-addItemListener(ItemListener listener)
-{
+ public synchronized void addItemListener(ItemListener listener)
+ {
item_listeners = AWTEventMulticaster.add(item_listeners, listener);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Removes the specified listener from the list of registered listeners for
* this object.
*
* @param listener The listener to remove.
*/
-public synchronized void
-removeItemListener(ItemListener listener)
-{
+ public synchronized void removeItemListener(ItemListener listener)
+ {
item_listeners = AWTEventMulticaster.remove(item_listeners, listener);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Processes this event by invoking <code>processItemEvent()</code> if the
* event is an instance of <code>ItemEvent</code>, otherwise the event
* is passed to the superclass.
*
* @param event The event to process.
*/
-protected void
-processEvent(AWTEvent event)
-{
+ protected void processEvent(AWTEvent event)
+ {
if (event instanceof ItemEvent)
processItemEvent((ItemEvent)event);
else
super.processEvent(event);
-}
+ }
-void
-dispatchEventImpl(AWTEvent e)
-{
- if (e.id <= ItemEvent.ITEM_LAST
- && e.id >= ItemEvent.ITEM_FIRST
- && (item_listeners != null || (eventMask & AWTEvent.ITEM_EVENT_MASK) != 0))
- processEvent(e);
- else
+ void dispatchEventImpl(AWTEvent e)
+ {
super.dispatchEventImpl(e);
-}
-/*************************************************************************/
+ if( e.id <= ItemEvent.ITEM_LAST && e.id >= ItemEvent.ITEM_FIRST &&
+ ( item_listeners != null ||
+ ( eventMask & AWTEvent.ITEM_EVENT_MASK ) != 0 ) )
+ processEvent(e);
+ }
-/**
+ /**
* Processes item event by dispatching to any registered listeners.
*
* @param event The event to process.
*/
-protected void
-processItemEvent(ItemEvent event)
-{
+ protected void processItemEvent(ItemEvent event)
+ {
int index = pItems.indexOf((String) event.getItem());
- // Don't call back into the peers when selecting index here
- if (event.getStateChange() == ItemEvent.SELECTED)
- this.selectedIndex = index;
if (item_listeners != null)
item_listeners.itemStateChanged(event);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns a debugging string for this object.
*
* @return A debugging string for this object.
*/
-protected String
-paramString()
-{
- return ("selectedIndex=" + selectedIndex + "," + super.paramString());
-}
+ protected String paramString()
+ {
+ return "selectedIndex=" + selectedIndex + "," + super.paramString();
+ }
/**
* Returns an array of all the objects currently registered as FooListeners
@@ -608,7 +520,7 @@
*
* @since 1.3
*/
- public EventListener[] getListeners (Class listenerType)
+ public <T extends EventListener> T[] getListeners (Class<T> listenerType)
{
if (listenerType == ItemListener.class)
return AWTEventMulticaster.getListeners (item_listeners, listenerType);
@@ -639,4 +551,19 @@
accessibleContext = new AccessibleAWTChoice();
return accessibleContext;
}
-} // class Choice
+
+ /**
+ * Generate a unique name for this <code>Choice</code>.
+ *
+ * @return A unique name for this <code>Choice</code>.
+ */
+ String generateName()
+ {
+ return "choice" + getUniqueLong();
+ }
+
+ private static synchronized long getUniqueLong()
+ {
+ return next_choice_number++;
+ }
+} // class Choice
Modified: trunk/core/src/classpath/java/java/awt/Component.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Component.java 2007-01-28 21:36:49 UTC (rev 3097)
+++ trunk/core/src/classpath/java/java/awt/Component.java 2007-01-31 19:02:43 UTC (rev 3098)
@@ -39,6 +39,10 @@
package java.awt;
+//import gnu.java.awt.dnd.peer.gtk.GtkDropTargetContextPeer;
+
+import gnu.java.awt.ComponentReshapeEvent;
+
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
import java.awt.event.AdjustmentEvent;
@@ -70,6 +74,7 @@
import java.awt.image.VolatileImage;
import java.awt.peer.ComponentPeer;
import java.awt.peer.LightweightPeer;
+import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
@@ -213,6 +218,12 @@
*/
static final Object treeLock = new String("AWT_TREE_LOCK");
+ /**
+ * The default maximum size.
+ */
+ private static final Dimension DEFAULT_MAX_SIZE
+ = new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
+
// Serialized fields from the serialization spec.
/**
@@ -427,6 +438,24 @@
Dimension minSize;
/**
+ * Flag indicating whether the minimum size for the component has been set
+ * by a call to {@link #setMinimumSize(Dimension)} with a non-null value.
+ */
+ boolean minSizeSet;
+
+ /**
+ * The maximum size for the component.
+ * @see #setMaximumSize(Dimension)
+ */
+ Dimension maxSize;
+
+ /**
+ * A flag indicating whether the maximum size for the component has been set
+ * by a call to {@link #setMaximumSize(Dimension)} with a non-null value.
+ */
+ boolean maxSizeSet;
+
+ /**
* Cached information on the preferred size. Should have been transient.
*
* @serial ignore
@@ -569,6 +598,17 @@
transient BufferStrategy bufferStrategy;
/**
+ * The number of hierarchy listeners of this container plus all of its
+ * children. This is needed for efficient handling of HierarchyEvents.
+ * These must be propagated to all child components with HierarchyListeners
+ * attached. To avoid traversal of the whole subtree, we keep track of
+ * the number of HierarchyListeners here and only walk the paths that
+ * actually have listeners.
+ */
+ int numHierarchyListeners;
+ int numHierarchyBoundsListeners;
+
+ /**
* true if requestFocus was called on this component when its
* top-level ancestor was not focusable.
*/
@@ -613,16 +653,19 @@
}
/**
- * Sets the name of this component to the specified name.
+ * Sets the name of this component to the specified name (this is a bound
+ * property with the name 'name').
*
- * @param name the new name of this component
+ * @param name the new name (<code>null</code> permitted).
* @see #getName()
* @since 1.1
*/
public void setName(String name)
{
nameExplicitlySet = true;
+ String old = this.name;
this.name = name;
+ firePropertyChange("name", old, name);
}
/**
@@ -659,6 +702,9 @@
public void setDropTarget(DropTarget dt)
{
this.dropTarget = dt;
+
+ if (peer != null)
+ dropTarget.addNotify(peer);
}
/**
@@ -1590,6 +1636,7 @@
*
* @return the component's preferred size
* @see #getMinimumSize()
+ * @see #setPreferredSize(Dimension)
* @see LayoutManager
*/
public Dimension getPreferredSize()
@@ -1600,7 +1647,7 @@
/**
* Sets the preferred size that will be returned by
* {@link #getPreferredSize()} always, and sends a
- * {@link java.beans.PropertyChangeEvent} (with the property name 'preferredSize') to
+ * {@link PropertyChangeEvent} (with the property name 'preferredSize') to
* all registered listeners.
*
* @param size the preferred size (<code>null</code> permitted).
@@ -1662,6 +1709,39 @@
}
/**
+ * Sets the minimum size that will be returned by {@link #getMinimumSize()}
+ * always, and sends a {@link PropertyChangeEvent} (with the property name
+ * 'minimumSize') to all registered listeners.
+ *
+ * @param size the minimum size (<code>null</code> permitted).
+ *
+ * @since 1.5
+ *
+ * @see #getMinimumSize()
+ */
+ public void setMinimumSize(Dimension size)
+ {
+ Dimension old = minSizeSet ? minSize : null;
+ minSize = size;
+ minSizeSet = (size != null);
+ firePropertyChange("minimumSize", old, size);
+ }
+
+ /**
+ * Returns <code>true</code> if the current minimum size is not
+ * <code>null</code> and was set by a call to
+ * {@link #setMinimumSize(Dimension)}, otherwise returns <code>false</code>.
+ *
+ * @return A boolean.
+ *
+ * @since 1.5
+ */
+ public boolean isMinimumSizeSet()
+ {
+ return minSizeSet;
+ }
+
+ /**
* Returns the component's minimum size.
*
* @return the component's minimum size
@@ -1676,10 +1756,38 @@
}
/**
+ * The actual calculation is pulled out of minimumSize() so that
+ * we can call it from Container.preferredSize() and
+ * Component.preferredSizeImpl and avoid creating a
+ * new intermediate Dimension object.
+ *
+ * @return the minimum size of the component
+ */
+ Dimension minimumSizeImpl()
+ {
+ Dimension size = minSize;
+ if (size == null || !(valid || minSizeSet))
+ {
+ // We need to lock here, because the calculation depends on the
+ // component structure not changing.
+ synchronized (getTreeLock())
+ {
+ ComponentPeer p = peer;
+ if (p != null)
+ size = peer.minimumSize();
+ else
+ size = size();
+ }
+ }
+ return size;
+ }
+
+ /**
* Returns the component's maximum size.
*
* @return the component's maximum size
* @see #getMinimumSize()
+ * @see #setMaximumSize(Dimension)
* @see #getPreferredSize()
* @see LayoutManager
*/
@@ -1689,6 +1797,56 @@
}
/**
+ * This is pulled out from getMaximumSize(), so that we can access it
+ * from Container.getMaximumSize() without creating an additional
+ * intermediate Dimension object.
+ *
+ * @return the maximum size of the component
+ */
+ Dimension maximumSizeImpl()
+ {
+ Dimension size;
+ if (maxSizeSet)
+ size = maxSize;
+ else
+ size = DEFAULT_MAX_SIZE;
+ return size;
+ }
+
+ /**
+ * Sets the maximum size that will be returned by {@link #getMaximumSize()}
+ * always, and sends a {@link PropertyChangeEvent} (with the property name
+ * 'maximumSize') to all registered listeners.
+ *
+ * @param size the maximum size (<code>null</code> permitted).
+ *
+ * @since 1.5
+ *
+ * @see #getMaximumSize()
+ */
+ public void setMaximumSize(Dimension size)
+ {
+ Dimension old = maxSizeSet ? maxSize : null;
+ maxSize = size;
+ maxSizeSet = (size != null);
+ firePropertyChange("maximumSize", old, size);
+ }
+
+ /**
+ * Returns <code>true</code> if the current maximum size is not
+ * <code>null</code> and was set by a call to
+ * {@link #setMaximumSize(Dimension)}, otherwise returns <code>false</code>.
+ *
+ * @return A boolean.
+ *
+ * @since 1.5
+ */
+ public boolean isMaximumSizeSet()
+ {
+ return maxSizeSet;
+ }
+
+ /**
* Returns the preferred horizontal alignment of this component. The value
* returned will be between {@link #LEFT_ALIGNMENT} and
* {@link #RIGHT_ALIGNMENT}, inclusive.
@@ -1873,11 +2031,9 @@
}
/**
- * Updates this component. This is called in response to
- * <code>repaint</code>. This method fills the component with the
- * background color, then sets the foreground color of the specified
- * graphics context to the foreground color of this component and calls
- * the <code>paint()</code> method. The coordinates of the graphics are
+ * Updates this component. This is called for heavyweight components in
+ * response to {@link #repaint()}. The default implementation simply forwards
+ * to {@link #paint(Graphics)}. The coordinates of the graphics are
* relative to this component. Subclasses should call either
* <code>super.update(g)</code> or <code>paint(g)</code>.
*
@@ -1885,11 +2041,6 @@
*
* @see #paint(Graphics)
* @see #repaint()
- *
- * @specnote In contrast to what the spec says, tests show that the exact
- * behaviour is to clear the background on lightweight and
- * top-level components only. Heavyweight components are not
- * affected by this method and only call paint().
*/
public void update(Graphics g)
{
@@ -2004,10 +2155,7 @@
}
/**
- * Prints this component, including all sub-components. This method is
- * provided so that printing can be done in a different manner from
- * painting. However, the implementation in this class simply calls the
- * <code>paintAll()</code> method.
+ * Prints this component, including all sub-components.
*
* @param g the graphics context of the print device
*
@@ -2365,6 +2513,17 @@
}
/**
+ * By default, no old mouse events should be ignored.
+ * This can be overridden by subclasses.
+ *
+ * @return false, no mouse events are ignored.
+ */
+ static boolean ignoreOldMouseEvents()
+ {
+ return false;
+ }
+
+ /**
* AWT 1.0 event handler.
*
* This method simply calls handleEvent and returns the result.
@@ -2581,6 +2740,40 @@
}
/**
+ * Fires a HierarchyEvent or HierarchyChangeEvent on this component.
+ *
+ * @param id the event id
+ * @param changed the changed component
+ * @param parent the parent
+ * @param flags the event flags
+ */
+ void fireHierarchyEvent(int id, Component changed, Container parent,
+ long flags)
+ {
+ boolean enabled = false;
+ switch (id)
+ {
+ case HierarchyEvent.HIERARCHY_CHANGED:
+ enabled = hierarchyListener != null
+ || (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0;
+ break;
+ case HierarchyEvent.ANCESTOR_MOVED:
+ case HierarchyEvent.ANCESTOR_RESIZED:
+ enabled = hierarchyBoundsListener != null
+ || (eventMask & AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK) != 0;
+ break;
+ default:
+ assert false : "Should not reach here";
+ }
+ if (enabled)
+ {
+ HierarchyEvent ev = new HierarchyEvent(this, id, changed, parent,
+ flags);
+ dispatchEvent(ev);
+ }
+ }
+
+ /**
* Adds the specified listener to this component. This is harmless if the
* listener is null, but if the listener has already been registered, it
* will now be registered twice.
@@ -3636,7 +3829,8 @@
* @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
* @since 1.4
*/
- public void setFocusTraversalKeys(int id, Set keystrokes)
+ public void setFocusTraversalKeys(int id,
+ Set<? extends AWTKeyStroke> keystrokes)
{
if (keystrokes == null)
{
@@ -3728,14 +3922,14 @@
*
* @since 1.4
*/
- public Set getFocusTraversalKeys (int id)
+ public Set<AWTKeyStroke> getFocusTraversalKeys (int id)
{
if (id != KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS &&
id != KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS &&
id != KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS)
throw new IllegalArgumentException();
- Set s = null;
+ Set<AWTKeyStroke> s = null;
if (focusTraversalKeys != null)
s = focusTraversalKeys[id];
@@ -4740,8 +4934,7 @@
* {@link #applyComponentOrientation(ComponentOrientation)} affects the
* entire hierarchy.
*
- * @param o the new orientation
- * @throws NullPointerException if o is null
+ * @param o the new orientation (<code>null</code> is accepted)
* @see #getComponentOrientation()
*/
public void setComponentOrientation(ComponentOrientation o)
@@ -4756,7 +4949,7 @@
/**
* Determines the text layout orientation used by this component.
*
- * @return the component orientation
+ * @return the component orientation (this can be <code>null</code>)
* @see #setComponentOrientation(ComponentOrientation)
*/
public ComponentOrientation getComponentOrientation()
@@ -5046,7 +5239,7 @@
oldKey = Event.UP;
break;
default:
- oldKey = (int) ((KeyEvent) e).getKeyChar();
+ oldKey = ((KeyEvent) e).getKeyChar();
}
translated = new Event (target, when, oldID,
@@ -5089,11 +5282,10 @@
*
* @param e the event to dispatch
*/
-
void dispatchEventImpl(AWTEvent e)
{
- // This boolean tells us not to process focus events when the focus
- // opposite component is the same as the focus component.
+ // Update the component's knowledge about the size.
+ // Important: Please look at the big comment in ComponentReshapeEvent
boolean ignoreFocus =
(e instanceof FocusEvent &&
((FocusEvent)e).getComponent() == ((FocusEvent)e).getOppositeComponent());
@@ -5385,7 +5577,7 @@
*/
public void componentHidden(ComponentEvent event)
{
- if (!isShowing())
+ if (isShowing())
peer.hide();
}
}
Modified: trunk/core/src/classpath/java/java/awt/Container.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Container.java 2007-01-28 21:36:49 UTC (rev 3097)
+++ trunk/core/src/classpath/java/java/awt/Container.java 2007-01-31 19:02:43 UTC (rev 3098)
@@ -42,7 +42,9 @@
import java.awt.event.ComponentListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
+import java.awt.event.HierarchyEvent;
import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
import java.awt.peer.ComponentPeer;
import java.awt.peer.ContainerPeer;
import java.awt.peer.LightweightPeer;
@@ -68,10 +70,11 @@
*
* @author original author unknown
* @author Eric Blake (eb...@em...)
+ * @author Andrew John Hughes (gnu...@me...)
*
* @since 1.0
*
- * @status still missing 1.4 support
+ * @status still missing 1.4 support, some generics from 1.5
*/
public class Container extends Component
{
@@ -97,6 +100,13 @@
*/
boolean focusCycleRoot;
+ /**
+ * Indicates if this container provides a focus traversal policy.
+ *
+ * @since 1.5
+ */
+ private boolean focusTraversalPolicyProvider;
+
int containerSerializedDataVersion;
/* Anything else is non-serializable, and should be declared "transient". */
@@ -927,10 +937,10 @@
*
* @since 1.3
*/
- public EventListener[] getListeners(Class listenerType)
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
{
if (listenerType == ContainerListener.class)
- return getContainerListeners();
+ return (T[]) getContainerListeners();
return super.getListeners(listenerType);
}
@@ -1549,6 +1559,42 @@
}
/**
+ * Set to <code>true</code> if this container provides a focus traversal
+ * policy, <code>false</code> when the root container's focus
+ * traversal policy should be used.
+ *
+ * @return <code>true</code> if this container provides a focus traversal
+ * policy, <code>false</code> when the root container's focus
+ * traversal policy should be used
+ *
+ * @see #setFocusTraversalPolicyProvider(boolean)
+ *
+ * @since 1.5
+ */
+ public final boolean isFocusTraversalPolicyProvider()
+ {
+ return focusTraversalPolicyProvider;
+ }
+
+ /**
+ * Set to <code>true</code> if this container provides a focus traversal
+ * policy, <code>false</code> when the root container's focus
+ * traversal policy should be used.
+ *
+ * @param b <code>true</code> if this container provides a focus traversal
+ * policy, <code>false</code> when the root container's focus
+ * traversal policy should be used
+ *
+ * @see #isFocusTraversalPolicyProvider()
+ *
+ * @since 1.5
+ */
+ public final void setFocusTraversalPolicyProvider(boolean b)
+ {
+ focusTraversalPolicyProvider = b;
+ }
+
+ /**
* Check whether this Container is a focus cycle root.
*
* @return true if this is a focus cycle root, false otherwise
@@ -1850,6 +1896,48 @@
}
}
+ /**
+ * Fires hierarchy events to the children of this container and this
+ * container itself. This overrides {@link Component#fireHierarchyEvent}
+ * in order to forward this event to all children.
+ */
+ void fireHierarchyEvent(int id, Component changed, Container parent,
+ long flags)
+ {
+ // Only propagate event if there is actually a listener waiting for it.
+ if ((id == HierarchyEvent.HIERARCHY_CHANGED && numHierarchyListeners > 0)
+ || ((id == HierarchyEvent.ANCESTOR_MOVED
+ || id == HierarchyEvent.ANCESTOR_RESIZED)
+ && numHierarchyBoundsListeners > 0))
+ {
+ for (int i = 0; i < ncomponents; i++)
+ component[i].fireHierarchyEvent(id, changed, parent, flags);
+ super.fireHierarchyEvent(id, changed, parent, flags);
+ }
+ }
+
+ /**
+ * Adjusts the number of hierarchy listeners of this container and all of
+ * its parents. This is called by the add/remove listener methods and
+ * structure changing methods in Container.
+ *
+ * @param type the type, either {@link AWTEvent#HIERARCHY_BOUNDS_EVENT_MASK}
+ * or {@link AWTEvent#HIERARCHY_EVENT_MASK}
+ * @param delta the number of listeners added or removed
+ */
+ void updateHierarchyListenerCount(long type, int delta)
+ {
+ if (type == AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK)
+ numHierarchyBoundsListeners += delta;
+ else if (type == AWTEvent.HIERARCHY_EVENT_MASK)
+ numHierarchyListeners += delta;
+ else
+ assert false : "Should not reach here";
+
+ if (parent != null)
+ parent.updateHierarchyListenerCount(type, delta);
+ }
+
private void addNotifyContainerChildren()
{
synchronized (getTreeLock ())
Modified: trunk/core/src/classpath/java/java/awt/Frame.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Frame.java 2007-01-28 21:36:49 UTC (rev 3097)
+++ trunk/core/src/classpath/java/java/awt/Frame.java 2007-01-31 19:02:43 UTC (rev 3098)
@@ -340,12 +340,15 @@
parent.remove(menuBar);
menuBar.setParent(this);
- if (peer != null)
+ // Create local copy for thread safety.
+ FramePeer p = (FramePeer) peer;
+ if (p != null)
{
if (menuBar != null)
menuBar.addNotify();
- invalidateTree();
- ((FramePeer) peer).setMenuBar(menuBar);
+ if (valid)
+ invalidate();
+ p.setMenuBar(menuBar);
}
}
}
@@ -485,8 +488,11 @@
private static void noteFrame(Frame f)
{
+ synchronized (weakFrames)
+ {
weakFrames.add(new WeakReference(f));
}
+ }
public static Frame[] getFrames()
{
@@ -533,8 +539,7 @@
public int getState()
{
- // FIXME: State might have changed in the peer... Must check.
- return (state & ICONIFIED) != 0 ? ICONIFIED : NORMAL;
+ return (getExtendedState() & ICONIFIED) != 0 ? ICONIFIED : NORMAL;
}
/**
@@ -542,14 +547,23 @@
*/
public void setExtendedState(int state)
{
+ if (getToolkit().isFrameStateSupported(state))
+ {
this.state = state;
+ FramePeer p = (FramePeer) peer;
+ if (p != null)
+ p.setState(state);
}
+ }
/**
* @since 1.4
*/
public int getExtendedState()
{
+ FramePeer p = (FramePeer) peer;
+ if (p != null)
+ state = p.getState();
return state;
}
Modified: trunk/core/src/classpath/java/java/awt/Label.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Label.java 2007-01-28 21:36:49 UTC (rev 3097)
+++ trunk/core/src/classpath/java/java/awt/Label.java 2007-01-31 19:02:43 UTC (rev 3098)
@@ -1,5 +1,6 @@
/* Label.java -- Java label widget
- Copyright (C) 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2004, 2005, 2006, Free Software
+ Foundation, Inc.
This file is part of GNU Classpath.
@@ -55,66 +56,47 @@
public class Label extends Component implements Accessible
{
-/*
- * Static Variables
- */
-
-/**
+ /**
* Alignment constant aligning the text to the left of its window.
*/
-public static final int LEFT = 0;
+ public static final int LEFT = 0;
-/**
+ /**
* Alignment constant aligning the text in the center of its window.
*/
-public static final int CENTER = 1;
+ public static final int CENTER = 1;
-/**
+ /**
* Alignment constant aligning the text to the right of its window.
*/
-public static final int RIGHT = 2;
+ public static final int RIGHT = 2;
-// Serialization version constant:
-private static final long serialVersionUID = 3094126758329070636L;
+ // Serialization version constant:
+ private static final long serialVersionUID = 3094126758329070636L;
-/*************************************************************************/
-
-/*
- * Instance Variables
- */
-
-/**
+ /**
* @serial Indicates the alignment of the text within this label's window.
* This is one of the constants in this class. The default value is
* <code>LEFT</code>.
*/
-private int alignment;
+ private int alignment;
-/**
+ /**
* @serial The text displayed in the label
*/
-private String text;
+ private String text;
-/*************************************************************************/
-
-/*
- * Constructors
- */
-
-/**
+ /**
* Initializes a new instance of <code>Label</code> with no text.
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
*/
-public
-Label()
-{
+ public Label()
+ {
this("", LEFT);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Initializes a new instance of <code>Label</code> with the specified
* text that is aligned to the left.
*
@@ -122,15 +104,12 @@
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
*/
-public
-Label(String text)
-{
+ public Label(String text)
+ {
this(text, LEFT);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Initializes a new instance of <code>Label</code> with the specified
* text and alignment.
*
@@ -141,80 +120,63 @@
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
*/
-public
-Label(String text, int alignment)
-{
- setAlignment (alignment);
- setText (text);
+ public Label(String text, int alignment)
+ {
+ setAlignment(alignment);
+ setText(text);
if (GraphicsEnvironment.isHeadless())
- throw new HeadlessException ();
-}
+ throw new HeadlessException();
+ }
-/*************************************************************************/
-
-/*
- * Instance Variables
- */
-
-/**
+ /**
* Returns the constant indicating the alignment of the text in this
* label. The value returned will be one of the alignment constants
* from this class.
*
* @return The alignment of the text in the label.
*/
-public int
-getAlignment()
-{
+ public int getAlignment()
+ {
return(alignment);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Sets the text alignment of this label to the specified value.
*
* @param alignment The desired alignment for the text in this label,
* which must be one of <code>LEFT</code>, <code>CENTER</code>, or
* <code>RIGHT</code>.
*/
-public synchronized void
-setAlignment(int alignment)
-{
+ public synchronized void setAlignment(int alignment)
+ {
if (alignment != CENTER && alignment != LEFT && alignment != RIGHT)
- throw new IllegalArgumentException ("invalid alignment: " + alignment);
+ throw new IllegalArgumentException("invalid alignment: " + alignment);
this.alignment = alignment;
if (peer != null)
{
LabelPeer lp = (LabelPeer) peer;
- lp.setAlignment (alignment);
+ lp.setAlignment(alignment);
+ }
}
-}
-/*************************************************************************/
-
-/**
+ /**
* Returns the text displayed in this label.
*
* @return The text for this label.
*/
-public String
-getText()
-{
- return(text);
-}
+ public String getText()
+ {
+ return text;
+ }
-/*************************************************************************/
-
-/**
+ /**
* Sets the text in this label to the specified value.
*
* @param text The new text for this label.
*/
-public synchronized void
-setText(String text)
-{
+ public synchronized void setText(String text)
+ {
if ((this.text == null && text != null)
|| (this.text != null && ! this.text.equals(text)))
{
@@ -223,47 +185,41 @@
if (peer != null)
{
LabelPeer lp = (LabelPeer) peer;
- lp.setText (text);
+ lp.setText(text);
}
invalidate();
}
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Notifies this label that it has been added to a container, causing
* the peer to be created. This method is called internally by the AWT
* system.
*/
-public void
-addNotify()
-{
+ public void addNotify()
+ {
if (peer == null)
- peer = getToolkit ().createLabel (this);
- super.addNotify ();
-}
+ peer = getToolkit().createLabel(this);
+ super.addNotify();
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns a parameter string useful for debugging.
*
* @return A debugging string.
*/
-protected String
-paramString()
-{
+ protected String paramString()
+ {
return ("text=" + getText() + ",alignment=" +
getAlignment() + "," + super.paramString());
-}
+ }
-/**
+ /**
* This class provides accessibility support for the label.
*/
-protected class AccessibleAWTLabel
+ protected class AccessibleAWTLabel
extends AccessibleAWTComponent
-{
+ {
/**
* For compatability with Sun's JDK 1.4.2 rev. 5
*/
@@ -299,21 +255,41 @@
return AccessibleRole.LABEL;
}
-}
+ }
-/**
+ /**
* Gets the AccessibleContext associated with this <code>Label</code>.
* The context is created, if necessary.
*
* @return the associated context
*/
-public AccessibleContext getAccessibleContext()
-{
+ public AccessibleContext getAccessibleContext()
+ {
/* Create the context if this is the first request */
if (accessibleContext == null)
accessibleContext = new AccessibleAWTLabel();
return accessibleContext;
-}
+ }
-} // class Label
+ /**
+ * Generate a unique name for this button.
+ *
+ * @return A unique name for this button.
+ */
+ String generateName()
+ {
+ return "label" + getUniqueLong();
+ }
+ /**
+ * The number used to generate the name returned by getName.
+ */
+ private static transient long nextLabelNumber;
+
+ private static synchronized long getUniqueLong()
+ {
+ return nextLabelNumber++;
+ }
+
+}
+
Modified: trunk/core/src/classpath/java/java/awt/List.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/List.java 2007-01-28 21:36:49 UTC (rev 3097)
+++ trunk/core/src/classpath/java/java/awt/List.java 2007-01-31 19:02:43 UTC (rev 3098)
@@ -1,5 +1,5 @@
/* List.java -- A listbox widget
- Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004, 2006, Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -62,77 +62,63 @@
implements ItemSelectable, Accessible
{
-/*
- * Static Variables
+ /**
+ * The number used to generate the name returned by getName.
*/
+ private static transient long next_list_number;
-// Serialization constant
-private static final long serialVersionUID = -3304312411574666869L;
+ // Serialization constant
+ private static final long serialVersionUID = -3304312411574666869L;
-/*************************************************************************/
+ // FIXME: Need read/writeObject
-/*
- * Instance Variables
- */
-
-// FIXME: Need read/writeObject
-
-/**
+ /**
* @serial The items in the list.
*/
-private Vector items = new Vector();
+ private Vector items = new Vector();
-/**
+ /**
* @serial Indicates whether or not multiple items can be selected
* simultaneously.
*/
-private boolean multipleMode;
+ private boolean multipleMode;
-/**
+ /**
* @serial The number of rows in the list. This is set on creation
* only and cannot be modified.
*/
-private int rows;
+ private int rows;
-/**
+ /**
* @serial An array of the item indices that are selected.
*/
-private int[] selected;
+ private int[] selected;
-/**
+ /**
* @serial An index value used by <code>makeVisible()</code> and
* <code>getVisibleIndex</code>.
*/
-private int visibleIndex;
+ private int visibleIndex = -1;
-// The list of ItemListeners for this object.
-private ItemListener item_listeners;
+ // The list of ItemListeners for this object.
+ private ItemListener item_listeners;
-// The list of ActionListeners for this object.
-private ActionListener action_listeners;
+ // The list of ActionListeners for this object.
+ private ActionListener action_listeners;
-
-/*************************************************************************/
-
-/*
- * Constructors
- */
-
-/**
+ /**
* Initializes a new instance of <code>List</code> with no visible lines
* and multi-select disabled.
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
+ * @since 1.1
*/
-public
-List()
-{
+ public List()
+ {
this(4, false);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Initializes a new instance of <code>List</code> with the specified
* number of visible lines and multi-select disabled.
*
@@ -140,15 +126,12 @@
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
*/
-public
-List(int rows)
-{
+ public List(int rows)
+ {
this(rows, false);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Initializes a new instance of <code>List</code> with the specified
* number of lines and the specified multi-select setting.
*
@@ -158,37 +141,34 @@
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
*/
-public
-List(int rows, boolean multipleMode)
-{
+ public List(int rows, boolean multipleMode)
+ {
+ if (rows == 0)
+ this.rows = 4;
+ else
this.rows = rows;
+
this.multipleMode = multipleMode;
selected = new int[0];
if (GraphicsEnvironment.isHeadless())
- throw new HeadlessException ();
-}
+ throw new HeadlessException();
-/*************************************************************************/
+ }
-/*
- * Instance Variables
- */
-
-/**
+ /**
* Returns the number of items in this list.
*
* @return The number of items in this list.
+ *
+ * @since 1.1
*/
-public int
-getItemCount()
-{
- return countItems ();
-}
+ public int getItemCount()
+ {
+ return countItems();
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the number of items in this list.
*
* @return The number of items in this list.
@@ -196,73 +176,62 @@
* @deprecated This method is deprecated in favor of
* <code>getItemCount()</code>
*/
-public int
-countItems()
-{
- return items.size ();
-}
+ public int countItems()
+ {
+ return items.size();
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the complete list of items.
*
* @return The complete list of items in the list.
+ *
+ * @since 1.1
*/
-public synchronized String[]
-getItems()
-{
+ public synchronized String[] getItems()
+ {
String[] l_items = new String[getItemCount()];
items.copyInto(l_items);
return(l_items);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the item at the specified index.
*
* @param index The index of the item to retrieve.
*
* @exception IndexOutOfBoundsException If the index value is not valid.
*/
-public String
-getItem(int index)
-{
- return((String)items.elementAt(index));
-}
+ public String getItem(int index)
+ {
+ return((String) items.elementAt(index));
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the number of visible rows in the list.
*
* @return The number of visible rows in the list.
*/
-public int
-getRows()
-{
+ public int getRows()
+ {
return(rows);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Tests whether or not multi-select mode is enabled.
*
* @return <code>true</code> if multi-select mode is enabled,
* <code>false</code> otherwise.
+ *
+ * @since 1.1
*/
-public boolean
-isMultipleMode()
-{
+ public boolean isMultipleMode()
+ {
return allowsMultipleSelections ();
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Tests whether or not multi-select mode is enabled.
*
* @return <code>true</code> if multi-select mode is enabled,
@@ -271,30 +240,26 @@
* @deprecated This method is deprecated in favor of
* <code>isMultipleMode()</code>.
*/
-public boolean
-allowsMultipleSelections()
-{
+ public boolean allowsMultipleSelections()
+ {
return multipleMode;
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* This method enables or disables multiple selection mode for this
* list.
*
* @param multipleMode <code>true</code> to enable multiple mode,
* <code>false</code> otherwise.
+ *
+ * @since 1.1
*/
-public void
-setMultipleMode(boolean multipleMode)
-{
+ public void setMultipleMode(boolean multipleMode)
+ {
setMultipleSelections (multipleMode);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* This method enables or disables multiple selection mode for this
* list.
*
@@ -303,32 +268,29 @@
*
* @deprecated
*/
-public void
-setMultipleSelections(boolean multipleMode)
-{
+ public void setMultipleSelections(boolean multipleMode)
+ {
this.multipleMode = multipleMode;
- ListPeer peer = (ListPeer) getPeer ();
+ ListPeer peer = (ListPeer) getPeer();
if (peer != null)
- peer.setMultipleMode (multipleMode);
-}
+ peer.setMultipleMode(multipleMode);
-/*************************************************************************/
+ }
-/**
+ /**
* Returns the minimum size of this component.
*
* @return The minimum size of this component.
+ *
+ * @since 1.1
*/
-public Dimension
-getMinimumSize()
-{
- return getMinimumSize (getRows ());
-}
+ public Dimension getMinimumSize()
+ {
+ return getMinimumSize(getRows());
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the minimum size of this component.
*
* @return The minimum size of this component.
@@ -336,31 +298,27 @@
* @deprecated This method is deprecated in favor of
* <code>getMinimumSize</code>.
*/
-public Dimension
-minimumSize()
-{
- return minimumSize (getRows ());
-}
+ public Dimension minimumSize()
+ {
+ return minimumSize(getRows());
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the minimum size of this component assuming it had the specified
* number of rows.
*
* @param rows The number of rows to size for.
*
* @return The minimum size of this component.
+ *
+ * @since 1.1
*/
-public Dimension
-getMinimumSize(int rows)
-{
- return minimumSize (rows);
-}
+ public Dimension getMinimumSize(int rows)
+ {
+ return minimumSize(rows);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the minimum size of this component assuming it had the specified
* number of rows.
*
@@ -371,32 +329,28 @@
* @deprecated This method is deprecated in favor of
* <code>getMinimumSize(int)</code>>
*/
-public Dimension
-minimumSize(int rows)
-{
- ListPeer peer = (ListPeer) getPeer ();
+ public Dimension minimumSize(int rows)
+ {
+ ListPeer peer = (ListPeer) getPeer();
if (peer != null)
- return peer.minimumSize (rows);
+ return peer.minimumSize(rows);
else
- return new Dimension (0, 0);
-}
+ return new Dimension(0, 0);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the preferred size of this component.
*
* @return The preferred size of this component.
+ *
+ * @since 1.1
*/
-public Dimension
-getPreferredSize()
-{
- return getPreferredSize (getRows ());
-}
+ public Dimension getPreferredSize()
+ {
+ return getPreferredSize(getRows());
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the preferred size of this component.
*
* @return The preferred size of this component.
@@ -404,31 +358,27 @@
* @deprecated This method is deprecated in favor of
* <code>getPreferredSize</code>.
*/
-public Dimension
-preferredSize()
-{
- return preferredSize (getRows ());
-}
+ public Dimension preferredSize()
+ {
+ return preferredSize(getRows());
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the preferred size of this component assuming it had the specified
* number of rows.
*
* @param rows The number of rows to size for.
*
* @return The preferred size of this component.
+ *
+ * @since 1.1
*/
-public Dimension
-getPreferredSize(int rows)
-{
- return preferredSize (rows);
-}
+ public Dimension getPreferredSize(int rows)
+ {
+ return preferredSize(rows);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Returns the preferred size of this component assuming it had the specified
* number of rows.
*
@@ -439,47 +389,40 @@
* @deprecated This method is deprecated in favor of
* <code>getPreferredSize(int)</code>>
*/
-public Dimension
-preferredSize(int rows)
-{
- ListPeer peer = (ListPeer) getPeer ();
+ public Dimension preferredSize(int rows)
+ {
+ ListPeer peer = (ListPeer)getPeer();
if (peer != null)
- return peer.preferredSize (rows);
+ return peer.preferredSize(rows);
else
return getSize();
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* This method adds the specified item to the end of the list.
*
* @param item The item to add to the list.
+ *
+ * @since 1.1
*/
-public void
-add(String item)
-{
+ public void add(String item)
+ {
add (item, -1);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* This method adds the specified item to the end of the list.
*
* @param item The item to add to the list.
*
* @deprecated Use add() instead.
*/
-public void
-addItem(String item)
-{
- addItem (item, -1);
-}
+ public void addItem(String item)
+ {
+ addItem(item, -1);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Adds the specified item to the specified location in the list.
* If the desired index is -1 or greater than the number of rows
* in the list, then the item is added to the end.
@@ -487,16 +430,15 @@
* @param item The item to add to the list.
* @param index The location in the list to add the item, or -1 to add
* to the end.
+ *
+ * @since 1.1
*/
-public void
-add(String item, int index)
-{
- addItem (item, index);
-}
+ public void add(String item, int index)
+ {
+ addItem(item, index);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Adds the specified item to the specified location in the list.
* If the desired index is -1 or greater than the number of rows
* in the list, then the item is added to the end.
@@ -507,22 +449,25 @@
*
* @deprecated Use add() instead.
*/
-public void
-addItem(String item, int index)
-{
+ public void addItem(String item, int index)
+ {
+ if (item == null)
+ item = "";
+
+ if (index < -1)
+ index = -1;
+
if ((index == -1) || (index >= items.size ()))
items.addElement (item);
else
- items.insertElementAt (item, index);
+ items.insertElementAt(item, index);
- ListPeer peer = (ListPeer) getPeer ();
+ ListPeer peer = (ListPeer) getPeer();
if (peer != null)
peer.add (item, index);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Deletes the item at the specified index.
*
* @param index The index of the item to delete.
@@ -531,34 +476,40 @@
*
* @deprecated
*/
-public void
-delItem(int index) throws IllegalArgumentException
-{
+ public void delItem(int index) throws IllegalArgumentException
+ {
+ boolean selected = false;
+ if (isSelected(index))
+ {
+ selected = true;
+ deselect(index);
+ }
+
items.removeElementAt (index);
- ListPeer peer = (ListPeer) getPeer ();
+ if (selected)
+ select(index);
+
+ ListPeer peer = (ListPeer) getPeer();
if (peer != null)
peer.delItems (index, index);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Deletes the item at the specified index.
*
* @param index The index of the item to delete.
*
* @exception IllegalArgumentException If the index is not valid
+ *
+ * @since 1.1
*/
-public void
-remove(int index) throws IllegalArgumentException
-{
- delItem (index);
-}
+ public void remove(int index) throws IllegalArgumentException
+ {
+ delItem(index);
+ }
-/*************************************************************************/
-
-/**
+ /**
* Deletes all items in the specified index range.
*
* @param start The beginning index of the range to delete.
@@ -568,18 +519,9 @@
*
* @deprecated This method is deprecated for some unknown reason.
*/
-public synchronized void
-delItems(int start, int end) throws IllegalArgumentException
-{
- if ((start < 0) || (start >= items.size()))
- throw new IllegalArgumentException("Bad list start index value: " + start);
-
- if ((start < 0) || (start >= items.size()))
- throw new IllegalArgumentException("Bad list start index value: " + start);
-
- if (start > end)
- throw new IllegalArgumentException("Start is greater than end!");
-
+ public synchronized void delItems(int start, int end)
+ throws IllegalArgumentException
+ {
// We must run the loop in reverse direction.
for (int i = end; i >= start; --i)
items.removeElementAt (i);
@@ -588,70 +530,65 @@
ListPeer l = (ListPeer) peer;
l.delItems (start, end);
}
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Deletes the first occurrence of the specified item from the list.
*
* @param item The item to delete.
*
* @exception IllegalArgumentException If the specified item does not exist.
+ *
+ * @since 1.1
*/
-public synchronized void
-remove(String item) throws IllegalArgumentException
-{
+ public synchronized void remove(String item) throws IllegalArgumentException
+ {
int index = items.indexOf(item);
if (index == -1)
throw new IllegalArgumentException("List element to delete not found");
remove(index);
-}
+ }
-/*************************************************************************/
-
-/**
+ /**
* Deletes all of the items from the list.
+ *
+ * @since 1.1
*/
-public synchronized void
-removeAll()
-{
- clear ();
-}
+ public synchronized void removeAll()
+ {
+ clear();
+ }
-/*************************************************************************/
-
-/**
+ /**
* Deletes all of the items from the list.
*
* @deprecated This method is deprecated in favor of <code>removeAll()</code>.
*/
-public...
[truncated message content] |
|
From: <ls...@us...> - 2007-01-28 21:36:50
|
Revision: 3097
http://jnode.svn.sourceforge.net/jnode/?rev=3097&view=rev
Author: lsantha
Date: 2007-01-28 13:36:49 -0800 (Sun, 28 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/awt/Button.java
trunk/core/src/classpath/java/java/awt/Component.java
trunk/core/src/classpath/java/java/awt/MenuBar.java
Modified: trunk/core/src/classpath/java/java/awt/Button.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Button.java 2007-01-28 20:52:02 UTC (rev 3096)
+++ trunk/core/src/classpath/java/java/awt/Button.java 2007-01-28 21:36:49 UTC (rev 3097)
@@ -352,11 +352,11 @@
*
* @since 1.3
*/
- public EventListener[] getListeners(Class listenerType)
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
{
if (listenerType == ActionListener.class)
- return getActionListeners();
- return (EventListener[]) Array.newInstance(listenerType, 0);
+ return (T[]) getActionListeners();
+ return (T[]) Array.newInstance(listenerType, 0);
}
/*************************************************************************/
Modified: trunk/core/src/classpath/java/java/awt/Component.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/Component.java 2007-01-28 20:52:02 UTC (rev 3096)
+++ trunk/core/src/classpath/java/java/awt/Component.java 2007-01-28 21:36:49 UTC (rev 3097)
@@ -2847,29 +2847,29 @@
* @see #getPropertyChangeListeners()
* @since 1.3
*/
- public EventListener[] getListeners(Class listenerType)
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
{
if (listenerType == ComponentListener.class)
- return getComponentListeners();
+ return (T[]) getComponentListeners();
if (listenerType == FocusListener.class)
- return getFocusListeners();
+ return (T[]) getFocusListeners();
if (listenerType == HierarchyListener.class)
- return getHierarchyListeners();
+ return (T[]) getHierarchyListeners();
if (listenerType == HierarchyBoundsListener.class)
- return getHierarchyBoundsListeners();
+ return (T[]) getHierarchyBoundsListeners();
if (listenerType == KeyListener.class)
- return getKeyListeners();
+ return (T[]) getKeyListeners();
if (listenerType == MouseListener.class)
- return getMouseListeners();
+ return (T[]) getMouseListeners();
if (listenerType == MouseMotionListener.class)
- return getMouseMotionListeners();
+ return (T[]) getMouseMotionListeners();
if (listenerType == MouseWheelListener.class)
- return getMouseWheelListeners();
+ return (T[]) getMouseWheelListeners();
if (listenerType == InputMethodListener.class)
- return getInputMethodListeners();
+ return (T[]) getInputMethodListeners();
if (listenerType == PropertyChangeListener.class)
- return getPropertyChangeListeners();
- return (EventListener[]) Array.newInstance(listenerType, 0);
+ return (T[]) getPropertyChangeListeners();
+ return (T[]) Array.newInstance(listenerType, 0);
}
/**
Modified: trunk/core/src/classpath/java/java/awt/MenuBar.java
===================================================================
--- trunk/core/src/classpath/java/java/awt/MenuBar.java 2007-01-28 20:52:02 UTC (rev 3096)
+++ trunk/core/src/classpath/java/java/awt/MenuBar.java 2007-01-28 21:36:49 UTC (rev 3097)
@@ -272,7 +272,7 @@
*
* @return a list of all shortcuts for the menus in this menu bar
*/
- public synchronized Enumeration shortcuts()
+ public synchronized Enumeration<MenuShortcut> shortcuts()
{
Vector shortcuts = new Vector();
Enumeration e = menus.elements();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-28 20:52:04
|
Revision: 3096
http://jnode.svn.sourceforge.net/jnode/?rev=3096&view=rev
Author: lsantha
Date: 2007-01-28 12:52:02 -0800 (Sun, 28 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/lang/reflect/Array.java
Added Paths:
-----------
trunk/core/src/classpath/vm/java/lang/reflect/VMArray.java
Modified: trunk/core/src/classpath/java/java/lang/reflect/Array.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/reflect/Array.java 2007-01-27 21:52:45 UTC (rev 3095)
+++ trunk/core/src/classpath/java/java/lang/reflect/Array.java 2007-01-28 20:52:02 UTC (rev 3096)
@@ -35,19 +35,9 @@
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
+
package java.lang.reflect;
-import org.jnode.vm.Vm;
-import org.jnode.vm.memmgr.VmHeapManager;
-import org.jnode.vm.classmgr.VmType;
-import org.jnode.vm.classmgr.VmClassLoader;
-import org.jnode.vm.classmgr.VmArrayClass;
-
-import gnu.java.security.action.InvokeAction;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
/**
* Array holds static helper functions that allow you to create and
* manipulate arrays by reflection. Operations know how to perform widening
@@ -105,10 +95,10 @@
* @throws NegativeArraySizeException when length is less than 0
* @throws OutOfMemoryError if memory allocation fails
*/
- public static Object newInstance(Class componentType, int length)
+ public static Object newInstance(Class<?> componentType, int length)
{
- if (!componentType.isPrimitive())
- return createObjectArray(componentType, length);
+ if (! componentType.isPrimitive())
+ return VMArray.createObjectArray(componentType, length);
if (componentType == boolean.class)
return new boolean[length];
if (componentType == byte.class)
@@ -153,10 +143,10 @@
* than 0
* @throws OutOfMemoryError if memory allocation fails
*/
- public static Object newInstance(Class componentType, int[] dimensions)
+ public static Object newInstance(Class<?> componentType, int[] dimensions)
{
if (dimensions.length <= 0)
- throw new IllegalArgumentException("Empty dimensions array.");
+ throw new IllegalArgumentException ("Empty dimensions array.");
return createMultiArray(componentType, dimensions,
dimensions.length - 1);
}
@@ -175,7 +165,7 @@
if (array instanceof boolean[])
return ((boolean[]) array).length;
if (array instanceof byte[])
- return ((byte[]) array).length;
+ return ((byte[]) array). length;
if (array instanceof char[])
return ((char[]) array).length;
if (array instanceof short[])
@@ -654,7 +644,7 @@
Object toAdd = createMultiArray(type, dimensions, index - 1);
Class thisType = toAdd.getClass();
Object[] retval
- = (Object[]) createObjectArray(thisType, dimensions[index]);
+ = (Object[]) VMArray.createObjectArray(thisType, dimensions[index]);
if (dimensions[index] > 0)
retval[0] = toAdd;
int i = dimensions[index];
@@ -663,49 +653,4 @@
return retval;
}
-
- // LS
- // @classpath-bugfix-22923 should be placed in VMArray
- /**
- * Dynamically create an array of objects.
- *
- * @param type guaranteed to be a valid object type
- * @param dim the length of the array
- * @return the new array
- * @throws NegativeArraySizeException if dim is negative
- * @throws OutOfMemoryError if memory allocation fails
- */
- private static Object createObjectArray(final Class type, int dim) {
- final VmType vmClass = (VmType) AccessController.doPrivileged(
- new PrivilegedAction() {
- public Object run() {
- return type.getVmClass();
- }
- });
-
- final String arrClsName = vmClass.getArrayClassName();
- final VmType arrCls;
- try {
- final VmClassLoader curLoader = vmClass.getLoader();
- arrCls = curLoader.loadClass(arrClsName, true);
- //Screen.debug("an cls{");
- //Screen.debug(vmClass.getName());
- if (arrCls == null) {
- throw new NoClassDefFoundError(arrClsName);
- }
- } catch (ClassNotFoundException ex) {
- throw new NoClassDefFoundError(arrClsName);
- }
-
- VmHeapManager hm = heapManager;
- if (hm == null) {
- heapManager = hm = Vm.getVm().getHeapManager();
- }
- final Object result = hm.newArray((VmArrayClass) arrCls, dim);
-
- //Screen.debug("}");
- return result;
- }
- private static VmHeapManager heapManager;
- // @classpath-bugfix-end
}
Added: trunk/core/src/classpath/vm/java/lang/reflect/VMArray.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/reflect/VMArray.java (rev 0)
+++ trunk/core/src/classpath/vm/java/lang/reflect/VMArray.java 2007-01-28 20:52:02 UTC (rev 3096)
@@ -0,0 +1,91 @@
+/* java.lang.reflect.VMArray - VM class for array manipulation by reflection.
+ Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+import gnu.classpath.Configuration;
+import org.jnode.vm.classmgr.VmType;
+import org.jnode.vm.classmgr.VmClassLoader;
+import org.jnode.vm.classmgr.VmArrayClass;
+import org.jnode.vm.Vm;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+class VMArray
+{
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalangreflect");
+ }
+ }
+
+ /**
+ * Dynamically create an array of objects.
+ *
+ * @param type guaranteed to be a valid object type
+ * @param dim the length of the array
+ * @return the new array
+ * @throws NegativeArraySizeException if dim is negative
+ * @throws OutOfMemoryError if memory allocation fails
+ */
+ static Object createObjectArray(final Class type, int dim) {
+ final VmType vmClass = AccessController.doPrivileged(
+ new PrivilegedAction<VmType>() {
+ public VmType run() {
+ return type.getVmClass();
+ }
+ });
+
+ final String arrClsName = vmClass.getArrayClassName();
+ final VmType arrCls;
+ try {
+ final VmClassLoader curLoader = vmClass.getLoader();
+ arrCls = curLoader.loadClass(arrClsName, true);
+ if (arrCls == null) {
+ throw new NoClassDefFoundError(arrClsName);
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new NoClassDefFoundError(arrClsName);
+ }
+
+ return Vm.getHeapManager().newArray((VmArrayClass) arrCls, dim);
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ls...@us...> - 2007-01-27 21:52:49
|
Revision: 3095
http://jnode.svn.sourceforge.net/jnode/?rev=3095&view=rev
Author: lsantha
Date: 2007-01-27 13:52:45 -0800 (Sat, 27 Jan 2007)
Log Message:
-----------
Classpath patches.
Modified Paths:
--------------
trunk/core/src/classpath/java/java/lang/Compiler.java
trunk/core/src/classpath/java/java/lang/Math.java
trunk/core/src/classpath/java/java/lang/SecurityManager.java
trunk/core/src/classpath/java/java/lang/StrictMath.java
trunk/core/src/classpath/java/java/lang/ThreadGroup.java
trunk/core/src/classpath/vm/java/lang/Thread.java
Added Paths:
-----------
trunk/core/src/classpath/vm/java/lang/VMMath.java
Modified: trunk/core/src/classpath/java/java/lang/Compiler.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/Compiler.java 2007-01-27 21:37:48 UTC (rev 3094)
+++ trunk/core/src/classpath/java/java/lang/Compiler.java 2007-01-27 21:52:45 UTC (rev 3095)
@@ -74,7 +74,7 @@
* compilation failed, <code>true</code> if compilation succeeded
* @throws NullPointerException if oneClass is null
*/
- public static boolean compileClass(Class oneClass)
+ public static boolean compileClass(Class<?> oneClass)
{
return VMCompiler.compileClass(oneClass);
}
Modified: trunk/core/src/classpath/java/java/lang/Math.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/Math.java 2007-01-27 21:37:48 UTC (rev 3094)
+++ trunk/core/src/classpath/java/java/lang/Math.java 2007-01-27 21:52:45 UTC (rev 3095)
@@ -1,5 +1,5 @@
-/* java.lang.Math -- common mathematical functions, native allowed
- Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+/* java.lang.Math -- common mathematical functions, native allowed (VMMath)
+ Copyright (C) 1998, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,8 @@
package java.lang;
+import gnu.classpath.Configuration;
+
import java.util.Random;
/**
@@ -50,10 +52,26 @@
* @author Paul Fisher
* @author John Keiser
* @author Eric Blake (eb...@em...)
+ * @author Andrew John Hughes (gnu...@me...)
* @since 1.0
*/
public final class Math
{
+
+ // FIXME - This is here because we need to load the "javalang" system
+ // library somewhere late in the bootstrap cycle. We cannot do this
+ // from VMSystem or VMRuntime since those are used to actually load
+ // the library. This is mainly here because historically Math was
+ // late enough in the bootstrap cycle to start using System after it
+ // was initialized (called from the java.util classes).
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalang");
+ }
+ }
+
/**
* Math is non-instantiable
*/
@@ -288,11 +306,10 @@
* @param a the angle (in radians)
* @return sin(a)
*/
- // @classpath-bugfix-22918
- public static double sin(double a) {
- return StrictMath.sin(a);
+ public static double sin(double a)
+ {
+ return VMMath.sin(a);
}
- // @classpath-bugfix-end
/**
* The trigonometric function <em>cos</em>. The cosine of NaN or infinity is
@@ -301,11 +318,10 @@
* @param a the angle (in radians)
* @return cos(a)
*/
- // @classpath-bugfix-22918
- public static double cos(double a) {
- return StrictMath.cos(a);
+ public static double cos(double a)
+ {
+ return VMMath.cos(a);
}
- // @classpath-bugfix-end
/**
* The trigonometric function <em>tan</em>. The tangent of NaN or infinity
@@ -315,11 +331,10 @@
* @param a the angle (in radians)
* @return tan(a)
*/
- // @classpath-bugfix-22918
- public static double tan(double a) {
- return StrictMath.tan(a);
+ public static double tan(double a)
+ {
+ return VMMath.tan(a);
}
- // @classpath-bugfix-end
/**
* The trigonometric function <em>arcsin</em>. The range of angles returned
@@ -330,11 +345,10 @@
* @param a the sin to turn back into an angle
* @return arcsin(a)
*/
- // @classpath-bugfix-22918
- public static double asin(double a) {
- return StrictMath.asin(a);
+ public static double asin(double a)
+ {
+ return VMMath.asin(a);
}
- // @classpath-bugfix-end
/**
* The trigonometric function <em>arccos</em>. The range of angles returned
@@ -345,11 +359,10 @@
* @param a the cos to turn back into an angle
* @return arccos(a)
*/
- // @classpath-bugfix-22918
- public static double acos(double a) {
- return StrictMath.acos(a);
+ public static double acos(double a)
+ {
+ return VMMath.acos(a);
}
- // @classpath-bugfix-end
/**
* The trigonometric function <em>arcsin</em>. The range of angles returned
@@ -361,11 +374,10 @@
* @return arcsin(a)
* @see #atan2(double, double)
*/
- // @classpath-bugfix-22918
- public static double atan(double a) {
- return StrictMath.atan(a);
+ public static double atan(double a)
+ {
+ return VMMath.atan(a);
}
- // @classpath-bugfix-end
/**
* A special version of the trigonometric function <em>arctan</em>, for
@@ -414,11 +426,10 @@
* @return <em>theta</em> in the conversion of (x, y) to (r, theta)
* @see #atan(double)
*/
- // @classpath-bugfix-22918
- public static double atan2(double y, double x) {
- return StrictMath.atan2(y, x);
+ public static double atan2(double y, double x)
+ {
+ return VMMath.atan2(y,x);
}
- // @classpath-bugfix-end
/**
* Take <em>e</em><sup>a</sup>. The opposite of <code>log()</code>. If the
@@ -432,11 +443,10 @@
* @see #log(double)
* @see #pow(double, double)
*/
- // @classpath-bugfix-22918
- public static double exp(double a) {
- return StrictMath.exp(a);
+ public static double exp(double a)
+ {
+ return VMMath.exp(a);
}
- // @classpath-bugfix-end
/**
* Take ln(a) (the natural log). The opposite of <code>exp()</code>. If the
@@ -452,11 +462,10 @@
* @return the natural log of <code>a</code>
* @see #exp(double)
*/
- // @classpath-bugfix-22918
- public static double log(double a) {
- return StrictMath.log(a);
+ public static double log(double a)
+ {
+ return VMMath.log(a);
}
- // @classpath-bugfix-end
/**
* Take a square root. If the argument is NaN or negative, the result is
@@ -464,17 +473,18 @@
* infinity; and if the result is either zero, the result is the same.
* This is accurate within the limits of doubles.
*
- * <p>For other roots, use pow(a, 1 / rootNumber).
+ * <p>For a cube root, use <code>cbrt</code>. For other roots, use
+ * <code>pow(a, 1 / rootNumber)</code>.</p>
*
* @param a the numeric argument
* @return the square root of the argument
+ * @see #cbrt(double)
* @see #pow(double, double)
*/
- // @classpath-bugfix-22918
- public static double sqrt(double a) {
- return StrictMath.sqrt(a);
+ public static double sqrt(double a)
+ {
+ return VMMath.sqrt(a);
}
- // @classpath-bugfix-end
/**
* Raise a number to a power. Special cases:<ul>
@@ -544,11 +554,10 @@
* @param b the power to raise it to
* @return a<sup>b</sup>
*/
- // @classpath-bugfix-22918
- public static double pow(double a, double b) {
- return StrictMath.pow(a, b);
+ public static double pow(double a, double b)
+ {
+ return VMMath.pow(a,b);
}
- // @classpath-bugfix-end
/**
* Get the IEEE 754 floating point remainder on two numbers. This is the
@@ -564,11 +573,10 @@
* @return the IEEE 754-defined floating point remainder of x/y
* @see #rint(double)
*/
- // @classpath-bugfix-22918
- public static double IEEEremainder(double x, double y) {
- return StrictMath.IEEEremainder(x, y);
+ public static double IEEEremainder(double x, double y)
+ {
+ return VMMath.IEEEremainder(x,y);
}
- // @classpath-bugfix-end
/**
* Take the nearest integer that is that is greater than or equal to the
@@ -579,11 +587,10 @@
* @param a the value to act upon
* @return the nearest integer >= <code>a</code>
*/
- // @classpath-bugfix-22918
- public static double ceil(double a) {
- return StrictMath.ceil(a);
+ public static double ceil(double a)
+ {
+ return VMMath.ceil(a);
}
- // @classpath-bugfix-end
/**
* Take the nearest integer that is that is less than or equal to the
@@ -593,11 +600,10 @@
* @param a the value to act upon
* @return the nearest integer <= <code>a</code>
*/
- // @classpath-bugfix-22918
- public static double floor(double a) {
- return StrictMath.floor(a);
+ public static double floor(double a)
+ {
+ return VMMath.floor(a);
}
- // @classpath-bugfix-end
/**
* Take the nearest integer to the argument. If it is exactly between
@@ -607,12 +613,10 @@
* @param a the value to act upon
* @return the nearest integer to <code>a</code>
*/
- // @classpath-bugfix-22918
public static double rint(double a)
{
- return StrictMath.rint(a);
+ return VMMath.rint(a);
}
- // @classpath-bugfix-end
/**
* Take the nearest integer to the argument. This is equivalent to
@@ -701,6 +705,99 @@
/**
* <p>
+ * Take a cube root. If the argument is <code>NaN</code>, an infinity or
+ * zero, then the original value is returned. The returned result is
+ * within 1 ulp of the exact result. For a finite value, <code>x</code>,
+ * the cube root of <code>-x</code> is equal to the negation of the cube root
+ * of <code>x</code>.
+ * </p>
+ * <p>
+ * For a square root, use <code>sqrt</code>. For other roots, use
+ * <code>pow(a, 1 / rootNumber)</code>.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the cube root of the argument
+ * @see #sqrt(double)
+ * @see #pow(double, double)
+ * @since 1.5
+ */
+ public static double cbrt(double a)
+ {
+ return VMMath.cbrt(a);
+ }
+
+ /**
+ * <p>
+ * Returns the hyperbolic cosine of the given value. For a value,
+ * <code>x</code>, the hyperbolic cosine is <code>(e<sup>x</sup> +
+ * e<sup>-x</sup>)/2</code>
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result is within 2.5 ulps of the exact result.
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code>, then the original value is
+ * returned. For either infinity, positive infinity is returned.
+ * The hyperbolic cosine of zero is 1.0.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic cosine of <code>a</code>.
+ * @since 1.5
+ */
+ public static double cosh(double a)
+ {
+ return VMMath.cosh(a);
+ }
+
+ /**
+ * <p>
+ * Returns <code>e<sup>a</sup> - 1. For values close to 0, the
+ * result of <code>expm1(a) + 1</code> tend to be much closer to the
+ * exact result than simply <code>exp(x)</code>. The result is within
+ * 1 ulp of the exact result, and results are semi-monotonic. For finite
+ * inputs, the returned value is greater than or equal to -1.0. Once
+ * a result enters within half a ulp of this limit, the limit is returned.
+ * </p>
+ * <p>
+ * For <code>NaN</code>, positive infinity and zero, the original value
+ * is returned. Negative infinity returns a result of -1.0 (the limit).
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return <code>e<sup>a</sup> - 1</code>
+ * @since 1.5
+ */
+ public static double expm1(double a)
+ {
+ return VMMath.expm1(a);
+ }
+
+ /**
+ * <p>
+ * Returns the hypotenuse, <code>a<sup>2</sup> + b<sup>2</sup></code>,
+ * without intermediate overflow or underflow. The returned result is
+ * within 1 ulp of the exact result. If one parameter is held constant,
+ * then the result in the other parameter is semi-monotonic.
+ * </p>
+ * <p>
+ * If either of the arguments is an infinity, then the returned result
+ * is positive infinity. Otherwise, if either argument is <code>NaN</code>,
+ * then <code>NaN</code> is returned.
+ * </p>
+ *
+ * @param a the first parameter.
+ * @param b the second parameter.
+ * @return the hypotenuse matching the supplied parameters.
+ * @since 1.5
+ */
+ public static double hypot(double a, double b)
+ {
+ return VMMath.hypot(a,b);
+ }
+
+ /**
+ * <p>
* Returns the base 10 logarithm of the supplied value. The returned
* result is within 1 ulp of the exact result, and the results are
* semi-monotonic.
@@ -719,7 +816,7 @@
*/
public static double log10(double a)
{
- return log(a)/log(10);
+ return VMMath.log10(a);
}
/**
@@ -744,7 +841,7 @@
*/
public static double log1p(double a)
{
- return log(a + 1);
+ return VMMath.log1p(a);
}
/**
@@ -800,7 +897,58 @@
return -1.0f;
return a;
}
+
/**
+ * <p>
+ * Returns the hyperbolic sine of the given value. For a value,
+ * <code>x</code>, the hyperbolic sine is <code>(e<sup>x</sup> -
+ * e<sup>-x</sup>)/2</code>
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result is within 2.5 ulps of the exact result.
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code>, an infinity or a zero, then the
+ * original value is returned.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic sine of <code>a</code>.
+ * @since 1.5
+ */
+ public static double sinh(double a)
+ {
+ return VMMath.sinh(a);
+ }
+
+ /**
+ * <p>
+ * Returns the hyperbolic tangent of the given value. For a value,
+ * <code>x</code>, the hyperbolic tangent is <code>(e<sup>x</sup> -
+ * e<sup>-x</sup>)/(e<sup>x</sup> + e<sup>-x</sup>)</code>
+ * (i.e. <code>sinh(a)/cosh(a)</code>)
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result is within 2.5 ulps of the exact result. The absolute value
+ * of the exact result is always less than 1. Computed results are thus
+ * less than or equal to 1 for finite arguments, with results within
+ * half a ulp of either positive or negative 1 returning the appropriate
+ * limit value (i.e. as if the argument was an infinity).
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code> or zero, then the original
+ * value is returned. Positive infinity returns +1.0 and negative infinity
+ * returns -1.0.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic tangent of <code>a</code>.
+ * @since 1.5
+ */
+ public static double tanh(double a)
+ {
+ return VMMath.tanh(a);
+ }
+
+ /**
* Return the ulp for the given double argument. The ulp is the
* difference between the argument and the next larger double. Note
* that the sign of the double argument is ignored, that is,
Modified: trunk/core/src/classpath/java/java/lang/SecurityManager.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/SecurityManager.java 2007-01-27 21:37:48 UTC (rev 3094)
+++ trunk/core/src/classpath/java/java/lang/SecurityManager.java 2007-01-27 21:52:45 UTC (rev 3095)
@@ -1,5 +1,5 @@
/* SecurityManager.java -- security checks for privileged actions
- Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -240,7 +240,7 @@
* @return the most recent non-system Class on the execution stack
* @deprecated use {@link #checkPermission(Permission)} instead
*/
- protected Class currentLoadedClass()
+ protected Class<?> currentLoadedClass()
{
int i = classLoaderDepth();
return i >= 0 ? getClassContext()[i] : null;
@@ -421,7 +421,7 @@
public void checkAccess(Thread thread)
{
if (thread.getThreadGroup() != null
- && thread.getThreadGroup().getParent() == null)
+ && thread.getThreadGroup().parent == null)
checkPermission(new RuntimePermission("modifyThread"));
}
@@ -454,7 +454,7 @@
*/
public void checkAccess(ThreadGroup g)
{
- if (g.getParent() == null)
+ if (g.parent == null)
checkPermission(new RuntimePermission("modifyThreadGroup"));
}
@@ -983,7 +983,7 @@
* @see Member#PUBLIC
* @since 1.1
*/
- public void checkMemberAccess(Class c, int memberType)
+ public void checkMemberAccess(Class<?> c, int memberType)
{
if (c == null)
throw new NullPointerException();
Modified: trunk/core/src/classpath/java/java/lang/StrictMath.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/StrictMath.java 2007-01-27 21:37:48 UTC (rev 3094)
+++ trunk/core/src/classpath/java/java/lang/StrictMath.java 2007-01-27 21:52:45 UTC (rev 3095)
@@ -1,5 +1,5 @@
/* java.lang.StrictMath -- common mathematical functions, strict Java
- Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -633,6 +633,381 @@
}
/**
+ * Returns the hyperbolic sine of <code>x</code> which is defined as
+ * (exp(x) - exp(-x)) / 2.
+ *
+ * Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN</li>
+ * <li>If the argument is positive infinity, the result is positive
+ * infinity.</li>
+ * <li>If the argument is negative infinity, the result is negative
+ * infinity.</li>
+ * <li>If the argument is zero, the result is zero.</li>
+ * </ul>
+ *
+ * @param x the argument to <em>sinh</em>
+ * @return the hyperbolic sine of <code>x</code>
+ *
+ * @since 1.5
+ */
+ public static double sinh(double x)
+ {
+ // Method :
+ // mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+ // 1. Replace x by |x| (sinh(-x) = -sinh(x)).
+ // 2.
+ // E + E/(E+1)
+ // 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
+ // 2
+ //
+ // 22 <= x <= lnovft : sinh(x) := exp(x)/2
+ // lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2)
+ // ln2ovft < x : sinh(x) := +inf (overflow)
+
+ double t, w, h;
+
+ long bits;
+ long h_bits;
+ long l_bits;
+
+ // handle special cases
+ if (x != x)
+ return x;
+ if (x == Double.POSITIVE_INFINITY)
+ return Double.POSITIVE_INFINITY;
+ if (x == Double.NEGATIVE_INFINITY)
+ return Double.NEGATIVE_INFINITY;
+
+ if (x < 0)
+ h = - 0.5;
+ else
+ h = 0.5;
+
+ bits = Double.doubleToLongBits(x);
+ h_bits = getHighDWord(bits) & 0x7fffffffL; // ignore sign
+ l_bits = getLowDWord(bits);
+
+ // |x| in [0, 22], return sign(x) * 0.5 * (E+E/(E+1))
+ if (h_bits < 0x40360000L) // |x| < 22
+ {
+ if (h_bits < 0x3e300000L) // |x| < 2^-28
+ return x; // for tiny arguments return x
+
+ t = expm1(abs(x));
+
+ if (h_bits < 0x3ff00000L)
+ return h * (2.0 * t - t * t / (t + 1.0));
+
+ return h * (t + t / (t + 1.0));
+ }
+
+ // |x| in [22, log(Double.MAX_VALUE)], return 0.5 * exp(|x|)
+ if (h_bits < 0x40862e42L)
+ return h * exp(abs(x));
+
+ // |x| in [log(Double.MAX_VALUE), overflowthreshold]
+ if ((h_bits < 0x408633ceL)
+ || ((h_bits == 0x408633ceL) && (l_bits <= 0x8fb9f87dL)))
+ {
+ w = exp(0.5 * abs(x));
+ t = h * w;
+
+ return t * w;
+ }
+
+ // |x| > overflowthershold
+ return h * Double.POSITIVE_INFINITY;
+ }
+
+ /**
+ * Returns the hyperbolic cosine of <code>x</code>, which is defined as
+ * (exp(x) + exp(-x)) / 2.
+ *
+ * Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN</li>
+ * <li>If the argument is positive infinity, the result is positive
+ * infinity.</li>
+ * <li>If the argument is negative infinity, the result is positive
+ * infinity.</li>
+ * <li>If the argument is zero, the result is one.</li>
+ * </ul>
+ *
+ * @param x the argument to <em>cosh</em>
+ * @return the hyperbolic cosine of <code>x</code>
+ *
+ * @since 1.5
+ */
+ public static double cosh(double x)
+ {
+ // Method :
+ // mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
+ // 1. Replace x by |x| (cosh(x) = cosh(-x)).
+ // 2.
+ // [ exp(x) - 1 ]^2
+ // 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
+ // 2*exp(x)
+ //
+ // exp(x) + 1/exp(x)
+ // ln2/2 <= x <= 22 : cosh(x) := ------------------
+ // 2
+ // 22 <= x <= lnovft : cosh(x) := exp(x)/2
+ // lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
+ // ln2ovft < x : cosh(x) := +inf (overflow)
+
+ double t, w;
+ long bits;
+ long hx;
+ long lx;
+
+ // handle special cases
+ if (x != x)
+ return x;
+ if (x == Double.POSITIVE_INFINITY)
+ return Double.POSITIVE_INFINITY;
+ if (x == Double.NEGATIVE_INFINITY)
+ return Double.POSITIVE_INFINITY;
+
+ bits = Double.doubleToLongBits(x);
+ hx = getHighDWord(bits) & 0x7fffffffL; // ignore sign
+ lx = getLowDWord(bits);
+
+ // |x| in [0, 0.5 * ln(2)], return 1 + expm1(|x|)^2 / (2 * exp(|x|))
+ if (hx < 0x3fd62e43L)
+ {
+ t = expm1(abs(x));
+ w = 1.0 + t;
+
+ // for tiny arguments return 1.
+ if (hx < 0x3c800000L)
+ return w;
+
+ return 1.0 + (t * t) / (w + w);
+ }
+
+ // |x| in [0.5 * ln(2), 22], return exp(|x|)/2 + 1 / (2 * exp(|x|))
+ if (hx < 0x40360000L)
+ {
+ t = exp(abs(x));
+
+ return 0.5 * t + 0.5 / t;
+ }
+
+ // |x| in [22, log(Double.MAX_VALUE)], return 0.5 * exp(|x|)
+ if (hx < 0x40862e42L)
+ return 0.5 * exp(abs(x));
+
+ // |x| in [log(Double.MAX_VALUE), overflowthreshold],
+ // return exp(x/2)/2 * exp(x/2)
+ if ((hx < 0x408633ceL)
+ || ((hx == 0x408633ceL) && (lx <= 0x8fb9f87dL)))
+ {
+ w = exp(0.5 * abs(x));
+ t = 0.5 * w;
+
+ return t * w;
+ }
+
+ // |x| > overflowthreshold
+ return Double.POSITIVE_INFINITY;
+ }
+
+ /**
+ * Returns the hyperbolic tangent of <code>x</code>, which is defined as
+ * (exp(x) - exp(-x)) / (exp(x) + exp(-x)), i.e. sinh(x) / cosh(x).
+ *
+ Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN</li>
+ * <li>If the argument is positive infinity, the result is 1.</li>
+ * <li>If the argument is negative infinity, the result is -1.</li>
+ * <li>If the argument is zero, the result is zero.</li>
+ * </ul>
+ *
+ * @param x the argument to <em>tanh</em>
+ * @return the hyperbolic tagent of <code>x</code>
+ *
+ * @since 1.5
+ */
+ public static double tanh(double x)
+ {
+ // Method :
+ // 0. tanh(x) is defined to be (exp(x) - exp(-x)) / (exp(x) + exp(-x))
+ // 1. reduce x to non-negative by tanh(-x) = -tanh(x).
+ // 2. 0 <= x <= 2^-55 : tanh(x) := x * (1.0 + x)
+ // -t
+ // 2^-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
+ // t + 2
+ // 2
+ // 1 <= x <= 22.0 : tanh(x) := 1 - ----- ; t=expm1(2x)
+ // t + 2
+ // 22.0 < x <= INF : tanh(x) := 1.
+
+ double t, z;
+
+ long bits;
+ long h_bits;
+
+ // handle special cases
+ if (x != x)
+ return x;
+ if (x == Double.POSITIVE_INFINITY)
+ return 1.0;
+ if (x == Double.NEGATIVE_INFINITY)
+ return -1.0;
+
+ bits = Double.doubleToLongBits(x);
+ h_bits = getHighDWord(bits) & 0x7fffffffL; // ingnore sign
+
+ if (h_bits < 0x40360000L) // |x| < 22
+ {
+ if (h_bits < 0x3c800000L) // |x| < 2^-55
+ return x * (1.0 + x);
+
+ if (h_bits >= 0x3ff00000L) // |x| >= 1
+ {
+ t = expm1(2.0 * abs(x));
+ z = 1.0 - 2.0 / (t + 2.0);
+ }
+ else // |x| < 1
+ {
+ t = expm1(-2.0 * abs(x));
+ z = -t / (t + 2.0);
+ }
+ }
+ else // |x| >= 22
+ z = 1.0;
+
+ return (x >= 0) ? z : -z;
+ }
+
+ /**
+ * Returns the lower two words of a long. This is intended to be
+ * used like this:
+ * <code>getLowDWord(Double.doubleToLongBits(x))</code>.
+ */
+ private static long getLowDWord(long x)
+ {
+ return x & 0x00000000ffffffffL;
+ }
+
+ /**
+ * Returns the higher two words of a long. This is intended to be
+ * used like this:
+ * <code>getHighDWord(Double.doubleToLongBits(x))</code>.
+ */
+ private static long getHighDWord(long x)
+ {
+ return (x & 0xffffffff00000000L) >> 32;
+ }
+
+ /**
+ * Returns a double with the IEEE754 bit pattern given in the lower
+ * and higher two words <code>lowDWord</code> and <code>highDWord</code>.
+ */
+ private static double buildDouble(long lowDWord, long highDWord)
+ {
+ return Double.longBitsToDouble(((highDWord & 0xffffffffL) << 32)
+ | (lowDWord & 0xffffffffL));
+ }
+
+ /**
+ * Returns the cube root of <code>x</code>. The sign of the cube root
+ * is equal to the sign of <code>x</code>.
+ *
+ * Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN</li>
+ * <li>If the argument is positive infinity, the result is positive
+ * infinity.</li>
+ * <li>If the argument is negative infinity, the result is negative
+ * infinity.</li>
+ * <li>If the argument is zero, the result is zero with the same
+ * sign as the argument.</li>
+ * </ul>
+ *
+ * @param x the number to take the cube root of
+ * @return the cube root of <code>x</code>
+ * @see #sqrt(double)
+ *
+ * @since 1.5
+ */
+ public static double cbrt(double x)
+ {
+ boolean negative = (x < 0);
+ double r;
+ double s;
+ double t;
+ double w;
+
+ long bits;
+ long l;
+ long h;
+
+ // handle the special cases
+ if (x != x)
+ return x;
+ if (x == Double.POSITIVE_INFINITY)
+ return Double.POSITIVE_INFINITY;
+ if (x == Double.NEGATIVE_INFINITY)
+ return Double.NEGATIVE_INFINITY;
+ if (x == 0)
+ return x;
+
+ x = abs(x);
+ bits = Double.doubleToLongBits(x);
+
+ if (bits < 0x0010000000000000L) // subnormal number
+ {
+ t = TWO_54;
+ t *= x;
+
+ // __HI(t)=__HI(t)/3+B2;
+ bits = Double.doubleToLongBits(t);
+ h = getHighDWord(bits);
+ l = getLowDWord(bits);
+
+ h = h / 3 + CBRT_B2;
+
+ t = buildDouble(l, h);
+ }
+ else
+ {
+ // __HI(t)=__HI(x)/3+B1;
+ h = getHighDWord(bits);
+ l = 0;
+
+ h = h / 3 + CBRT_B1;
+ t = buildDouble(l, h);
+ }
+
+ // new cbrt to 23 bits
+ r = t * t / x;
+ s = CBRT_C + r * t;
+ t *= CBRT_G + CBRT_F / (s + CBRT_E + CBRT_D / s);
+
+ // chopped to 20 bits and make it larger than cbrt(x)
+ bits = Double.doubleToLongBits(t);
+ h = getHighDWord(bits);
+
+ // __LO(t)=0;
+ // __HI(t)+=0x00000001;
+ l = 0;
+ h += 1;
+ t = buildDouble(l, h);
+
+ // one step newton iteration to 53 bits with error less than 0.667 ulps
+ s = t * t; // t * t is exact
+ r = x / s;
+ w = t + t;
+ r = (r - t) / (w + r); // r - t is exact
+ t = t + t * r;
+
+ return negative ? -t : t;
+ }
+
+ /**
* Take <em>e</em><sup>a</sup>. The opposite of <code>log()</code>. If the
* argument is NaN, the result is NaN; if the argument is positive infinity,
* the result is positive infinity; and if the argument is negative
@@ -694,6 +1069,254 @@
}
/**
+ * Returns <em>e</em><sup>x</sup> - 1.
+ * Special cases:
+ * <ul>
+ * <li>If the argument is NaN, the result is NaN.</li>
+ * <li>If the argument is positive infinity, the result is positive
+ * infinity</li>
+ * <li>If the argument is negative infinity, the result is -1.</li>
+ * <li>If the argument is zero, the result is zero.</li>
+ * </ul>
+ *
+ * @param x the argument to <em>e</em><sup>x</sup> - 1.
+ * @return <em>e</em> raised to the power <code>x</code> minus one.
+ * @see #exp(double)
+ */
+ public static double expm1(double x)
+ {
+ // Method
+ // 1. Argument reduction:
+ // Given x, find r and integer k such that
+ //
+ // x = k * ln(2) + r, |r| <= 0.5 * ln(2)
+ //
+ // Here a correction term c will be computed to compensate
+ // the error in r when rounded to a floating-point number.
+ //
+ // 2. Approximating expm1(r) by a special rational function on
+ // the interval [0, 0.5 * ln(2)]:
+ // Since
+ // r*(exp(r)+1)/(exp(r)-1) = 2 + r^2/6 - r^4/360 + ...
+ // we define R1(r*r) by
+ // r*(exp(r)+1)/(exp(r)-1) = 2 + r^2/6 * R1(r*r)
+ // That is,
+ // R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
+ // = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
+ // = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
+ // We use a special Remes algorithm on [0, 0.347] to generate
+ // a polynomial of degree 5 in r*r to approximate R1. The
+ // maximum error of this polynomial approximation is bounded
+ // by 2**-61. In other words,
+ // R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
+ // where Q1 = -1.6666666666666567384E-2,
+ // Q2 = 3.9682539681370365873E-4,
+ // Q3 = -9.9206344733435987357E-6,
+ // Q4 = 2.5051361420808517002E-7,
+ // Q5 = -6.2843505682382617102E-9;
+ // (where z=r*r, and Q1 to Q5 are called EXPM1_Qx in the source)
+ // with error bounded by
+ // | 5 | -61
+ // | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
+ // | |
+ //
+ // expm1(r) = exp(r)-1 is then computed by the following
+ // specific way which minimize the accumulation rounding error:
+ // 2 3
+ // r r [ 3 - (R1 + R1*r/2) ]
+ // expm1(r) = r + --- + --- * [--------------------]
+ // 2 2 [ 6 - r*(3 - R1*r/2) ]
+ //
+ // To compensate the error in the argument reduction, we use
+ // expm1(r+c) = expm1(r) + c + expm1(r)*c
+ // ~ expm1(r) + c + r*c
+ // Thus c+r*c will be added in as the correction terms for
+ // expm1(r+c). Now rearrange the term to avoid optimization
+ // screw up:
+ // ( 2 2 )
+ // ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
+ // expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
+ // ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
+ // ( )
+ //
+ // = r - E
+ // 3. Scale back to obtain expm1(x):
+ // From step 1, we have
+ // expm1(x) = either 2^k*[expm1(r)+1] - 1
+ // = or 2^k*[expm1(r) + (1-2^-k)]
+ // 4. Implementation notes:
+ // (A). To save one multiplication, we scale the coefficient Qi
+ // to Qi*2^i, and replace z by (x^2)/2.
+ // (B). To achieve maximum accuracy, we compute expm1(x) by
+ // (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
+ // (ii) if k=0, return r-E
+ // (iii) if k=-1, return 0.5*(r-E)-0.5
+ // (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
+ // else return 1.0+2.0*(r-E);
+ // (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
+ // (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
+ // (vii) return 2^k(1-((E+2^-k)-r))
+
+ boolean negative = (x < 0);
+ double y, hi, lo, c, t, e, hxs, hfx, r1;
+ int k;
+
+ long bits;
+ long h_bits;
+ long l_bits;
+
+ c = 0.0;
+ y = abs(x);
+
+ bits = Double.doubleToLongBits(y);
+ h_bits = getHighDWord(bits);
+ l_bits = getLowDWord(bits);
+
+ // handle special cases and large arguments
+ if (h_bits >= 0x4043687aL) // if |x| >= 56 * ln(2)
+ {
+ if (h_bits >= 0x40862e42L) // if |x| >= EXP_LIMIT_H
+ {
+ if (h_bits >= 0x7ff00000L)
+ {
+ if (((h_bits & 0x000fffffL) | (l_bits & 0xffffffffL)) != 0)
+ return x; // exp(NaN) = NaN
+ else
+ return negative ? -1.0 : x; // exp({+-inf}) = {+inf, -1}
+ }
+
+ if (x > EXP_LIMIT_H)
+ return Double.POSITIVE_INFINITY; // overflow
+ }
+
+ if (negative) // x <= -56 * ln(2)
+ return -1.0;
+ }
+
+ // argument reduction
+ if (h_bits > 0x3fd62e42L) // |x| > 0.5 * ln(2)
+ {
+ if (h_bits < 0x3ff0a2b2L) // |x| < 1.5 * ln(2)
+ {
+ if (negative)
+ {
+ hi = x + LN2_H;
+ lo = -LN2_L;
+ k = -1;
+ }
+ else
+ {
+ hi = x - LN2_H;
+ lo = LN2_L;
+ k = 1;
+ }
+ }
+ else
+ {
+ k = (int) (INV_LN2 * x + (negative ? - 0.5 : 0.5));
+ t = k;
+ hi = x - t * LN2_H;
+ lo = t * LN2_L;
+ }
+
+ x = hi - lo;
+ c = (hi - x) - lo;
+
+ }
+ else if (h_bits < 0x3c900000L) // |x| < 2^-54 return x
+ return x;
+ else
+ k = 0;
+
+ // x is now in primary range
+ hfx = 0.5 * x;
+ hxs = x * hfx;
+ r1 = 1.0 + hxs * (EXPM1_Q1
+ + hxs * (EXPM1_Q2
+ + hxs * (EXPM1_Q3
+ + hxs * (EXPM1_Q4
+ + hxs * EXPM1_Q5))));
+ t = 3.0 - r1 * hfx;
+ e = hxs * ((r1 - t) / (6.0 - x * t));
+
+ if (k == 0)
+ {
+ return x - (x * e - hxs); // c == 0
+ }
+ else
+ {
+ e = x * (e - c) - c;
+ e -= hxs;
+
+ if (k == -1)
+ return 0.5 * (x - e) - 0.5;
+
+ if (k == 1)
+ {
+ if (x < - 0.25)
+ return -2.0 * (e - (x + 0.5));
+ else
+ return 1.0 + 2.0 * (x - e);
+ }
+
+ if (k <= -2 || k > 56) // sufficient to return exp(x) - 1
+ {
+ y = 1.0 - (e - x);
+
+ bits = Double.doubleToLongBits(y);
+ h_bits = getHighDWord(bits);
+ l_bits = getLowDWord(bits);
+
+ h_bits += (k << 20); // add k to y's exponent
+
+ y = buildDouble(l_bits, h_bits);
+
+ return y - 1.0;
+ }
+
+ t = 1.0;
+ if (k < 20)
+ {
+ bits = Double.doubleToLongBits(t);
+ h_bits = 0x3ff00000L - (0x00200000L >> k);
+ l_bits = getLowDWord(bits);
+
+ t = buildDouble(l_bits, h_bits); // t = 1 - 2^(-k)
+ y = t - (e - x);
+
+ bits = Double.doubleToLongBits(y);
+ h_bits = getHighDWord(bits);
+ l_bits = getLowDWord(bits);
+
+ h_bits += (k << 20); // add k to y's exponent
+
+ y = buildDouble(l_bits, h_bits);
+ }
+ else
+ {
+ bits = Double.doubleToLongBits(t);
+ h_bits = (0x000003ffL - k) << 20;
+ l_bits = getLowDWord(bits);
+
+ t = buildDouble(l_bits, h_bits); // t = 2^(-k)
+
+ y = x - (e + t);
+ y += 1.0;
+
+ bits = Double.doubleToLongBits(y);
+ h_bits = getHighDWord(bits);
+ l_bits = getLowDWord(bits);
+
+ h_bits += (k << 20); // add k to y's exponent
+
+ y = buildDouble(l_bits, h_bits);
+ }
+ }
+
+ return y;
+ }
+
+ /**
* Take ln(a) (the natural log). The opposite of <code>exp()</code>. If the
* argument is NaN or negative, the result is NaN; if the argument is
* positive infinity, the result is positive infinity; and if the argument
@@ -1429,6 +2052,33 @@
AT10 = 0.016285820115365782; // Long bits 0x3f90ad3ae322da11L.
/**
+ * Constants for computing {@link #cbrt(double)}.
+ */
+ private static final int
+ CBRT_B1 = 715094163, // B1 = (682-0.03306235651)*2**20
+ CBRT_B2 = 696219795; // B2 = (664-0.03306235651)*2**20
+
+ /**
+ * Constants for computing {@link #cbrt(double)}.
+ */
+ private static final double
+ CBRT_C = 5.42857142857142815906e-01, // Long bits 0x3fe15f15f15f15f1L
+ CBRT_D = -7.05306122448979611050e-01, // Long bits 0xbfe691de2532c834L
+ CBRT_E = 1.41428571428571436819e+00, // Long bits 0x3ff6a0ea0ea0ea0fL
+ CBRT_F = 1.60714285714285720630e+00, // Long bits 0x3ff9b6db6db6db6eL
+ CBRT_G = 3.57142857142857150787e-01; // Long bits 0x3fd6db6db6db6db7L
+
+ /**
+ * Constants for computing {@link #expm1(double)}
+ */
+ private static final double
+ EXPM1_Q1 = -3.33333333333331316428e-02, // Long bits 0xbfa11111111110f4L
+ EXPM1_Q2 = 1.58730158725481460165e-03, // Long bits 0x3f5a01a019fe5585L
+ EXPM1_Q3 = -7.93650757867487942473e-05, // Long bits 0xbf14ce199eaadbb7L
+ EXPM1_Q4 = 4.00821782732936239552e-06, // Long bits 0x3ed0cfca86e65239L
+ EXPM1_Q5 = -2.01099218183624371326e-07; // Long bits 0xbe8afdb76e09c32dL
+
+ /**
* Helper function for reducing an angle to a multiple of pi/2 within
* [-pi/4, pi/4].
*
@@ -1628,8 +2278,9 @@
j |= iq[i];
if (j == 0) // Need recomputation.
{
- int k;
- for (k = 1; iq[jk - k] == 0; k++); // k = no. of terms needed.
+ int k; // k = no. of terms needed.
+ for (k = 1; iq[jk - k] == 0; k++)
+ ;
for (i = jz + 1; i <= jz + k; i++) // Add q[jz+1] to q[jz+k].
{
@@ -1841,4 +2492,84 @@
double t = (float) a;
return t + a * (1 + t * z + t * v);
}
+
+ /**
+ * <p>
+ * Returns the sign of the argument as follows:
+ * </p>
+ * <ul>
+ * <li>If <code>a</code> is greater than zero, the result is 1.0.</li>
+ * <li>If <code>a</code> is less than zero, the result is -1.0.</li>
+ * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>.
+ * <li>If <code>a</code> is positive or negative zero, the result is the
+ * same.</li>
+ * </ul>
+ *
+ * @param a the numeric argument.
+ * @return the sign of the argument.
+ * @since 1.5.
+ */
+ public static double signum(double a)
+ {
+ // There's no difference.
+ return Math.signum(a);
}
+
+ /**
+ * <p>
+ * Returns the sign of the argument as follows:
+ * </p>
+ * <ul>
+ * <li>If <code>a</code> is greater than zero, the result is 1.0f.</li>
+ * <li>If <code>a</code> is less than zero, the result is -1.0f.</li>
+ * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>.
+ * <li>If <code>a</code> is positive or negative zero, the result is the
+ * same.</li>
+ * </ul>
+ *
+ * @param a the numeric argument.
+ * @return the sign of the argument.
+ * @since 1.5.
+ */
+ public static float signum(float a)
+ {
+ // There's no difference.
+ return Math.signum(a);
+ }
+
+ /**
+ * Return the ulp for the given double argument. The ulp is the
+ * difference between the argument and the next larger double. Note
+ * that the sign of the double argument is ignored, that is,
+ * ulp(x) == ulp(-x). If the argument is a NaN, then NaN is returned.
+ * If the argument is an infinity, then +Inf is returned. If the
+ * argument is zero (either positive or negative), then
+ * {@link Double#MIN_VALUE} is returned.
+ * @param d the double whose ulp should be returned
+ * @return the difference between the argument and the next larger double
+ * @since 1.5
+ */
+ public static double ulp(double d)
+ {
+ // There's no difference.
+ return Math.ulp(d);
+ }
+
+ /**
+ * Return the ulp for the given float argument. The ulp is the
+ * difference between the argument and the next larger float. Note
+ * that the sign of the float argument is ignored, that is,
+ * ulp(x) == ulp(-x). If the argument is a NaN, then NaN is returned.
+ * If the argument is an infinity, then +Inf is returned. If the
+ * argument is zero (either positive or negative), then
+ * {@link Float#MIN_VALUE} is returned.
+ * @param f the float whose ulp should be returned
+ * @return the difference between the argument and the next larger float
+ * @since 1.5
+ */
+ public static float ulp(float f)
+ {
+ // There's no difference.
+ return Math.ulp(f);
+ }
+}
Modified: trunk/core/src/classpath/java/java/lang/ThreadGroup.java
===================================================================
--- trunk/core/src/classpath/java/java/lang/ThreadGroup.java 2007-01-27 21:37:48 UTC (rev 3094)
+++ trunk/core/src/classpath/java/java/lang/ThreadGroup.java 2007-01-27 21:52:45 UTC (rev 3095)
@@ -37,6 +37,7 @@
package java.lang;
+import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Vector;
/**
@@ -53,7 +54,7 @@
* @since 1.0
* @status updated to 1.4
*/
-public class ThreadGroup
+public class ThreadGroup implements UncaughtExceptionHandler
{
/** The Initial, top-level ThreadGroup. */
static ThreadGroup root = new ThreadGroup();
@@ -65,7 +66,7 @@
static boolean had_uncaught_exception;
/** The parent thread group. */
- private final ThreadGroup parent;
+ final ThreadGroup parent;
/** The group name, non-null. */
final String name;
@@ -545,6 +546,8 @@
{
if (parent != null)
parent.uncaughtException(thread, t);
+ else if (Thread.getDefaultUncaughtExceptionHandler() != null)
+ Thread.getDefaultUncaughtExceptionHandler().uncaughtException(thread, t);
else if (! (t instanceof ThreadDeath))
{
if (t == null)
@@ -746,4 +749,43 @@
parent.removeGroup(this);
}
}
+
+ /*
+ * Helper method for the VM. Find a Thread by its Id.
+ *
+ * @param id The Thread Id.
+ * @return Thread object or null if thread doesn't exist.
+ */
+ static Thread getThreadFromId(long id)
+ {
+ return root.getThreadFromIdImpl(id);
+ }
+
+ private Thread getThreadFromIdImpl(long id)
+ {
+ synchronized (threads)
+ {
+ for (int i = 0; i < threads.size(); i++)
+ {
+ Thread t = (Thread) threads.get(i);
+ if (t.getId() == id)
+ return t;
+ }
+ }
+ Vector groups = this.groups;
+ if (groups != null)
+ {
+ synchronized (groups)
+ {
+ for (int i = 0; i < groups.size(); i++)
+ {
+ ThreadGroup g = (ThreadGroup) groups.get(i);
+ Thread t = g.getThreadFromIdImpl(id);
+ if (t != null)
+ return t;
+ }
+ }
+ }
+ return null;
+ }
} // class ThreadGroup
Modified: trunk/core/src/classpath/vm/java/lang/Thread.java
===================================================================
--- trunk/core/src/classpath/vm/java/lang/Thread.java 2007-01-27 21:37:48 UTC (rev 3094)
+++ trunk/core/src/classpath/vm/java/lang/Thread.java 2007-01-27 21:52:45 UTC (rev 3095)
@@ -1,21 +1,41 @@
/* Thread -- an independent thread of executable code
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; If not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
+ Free Software Foundation
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
package java.lang;
import java.util.Map;
@@ -32,205 +52,270 @@
import org.jnode.vm.scheduler.VmProcessor;
import org.jnode.vm.scheduler.VmThread;
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete to version 1.4, with caveats. We do not
+ * implement the deprecated (and dangerous) stop, suspend, and resume
+ * methods. Security implementation is not complete.
+ */
+
/**
- * Kore implementation of the <code>java.lang.Thread</code> class.
- * <p>
- * All native methods are indirected through <code>java.lang.NativeLang</code>.
- *
- * @version Kore 0.0.3, June 1997
- * @author Glynn Clements <a href="mailto:gl...@se...">gl...@se...
- * </a>
- * @author E. Prangsma (connection to JNode)
+ * Thread represents a single thread of execution in the VM. When an
+ * application VM starts up, it creates a non-daemon Thread which calls the
+ * main() method of a particular class. There may be other Threads running,
+ * such as the garbage collection thread.
+ *
+ * <p>Threads have names to identify them. These names are not necessarily
+ * unique. Every Thread has a priority, as well, which tells the VM which
+ * Threads should get more running time. New threads inherit the priority
+ * and daemon status of the parent thread, by default.
+ *
+ * <p>There are two methods of creating a Thread: you may subclass Thread and
+ * implement the <code>run()</code> method, at which point you may start the
+ * Thread by calling its <code>start()</code> method, or you may implement
+ * <code>Runnable</code> in the class you want to use and then call new
+ * <code>Thread(your_obj).start()</code>.
+ *
+ * <p>The virtual machine runs until all non-daemon threads have died (either
+ * by returning from the run() method as invoked by start(), or by throwing
+ * an uncaught exception); or until <code>System.exit</code> is called with
+ * adequate permissions.
+ *
+ * <p>It is unclear at what point a Thread should be added to a ThreadGroup,
+ * and at what point it should be removed. Should it be inserted when it
+ * starts, or when it is created? Should it be removed when it is suspended
+ * or interrupted? The only thing that is clear is that the Thread should be
+ * removed when it is stopped.
+ *
+ * @author Tom Tromey
+ * @author John Keiser
+ * @author Eric Blake (eb...@em...)
+ * @author Andrew John Hughes (gnu...@me...)
+ * @see Runnable
+ * @see Runtime#exit(int)
+ * @see #run()
+ * @see #start()
+ * @see ThreadLocal
+ * @since 1.0
+ * @status updated to 1.4
*/
-public class Thread implements Runnable {
+public class Thread implements Runnable
+{
+ /** The minimum priority for a Thread. */
+ public static final int MIN_PRIORITY = 1;
- /**
- * Number of threads created. Used only for generating "unique" names.
- *
- * @see java.lang.Thread#autoName()
+ /** The priority a Thread gets by default. */
+ public static final int NORM_PRIORITY = 5;
+
+ /** The maximum priority for a Thread. */
+ public static final int MAX_PRIORITY = 10;
+
+ /** The VM thread implementing this thread */
+ private final VmThread vmThread;
+
+ /** The group this thread belongs to.
+ *
*/
- private static int count = 0;
+ ThreadGroup group;
- private static final JNodePermission GETVMTHREAD_PERM = new JNodePermission(
- "getVmThread");
+ /** The object to run(), null if this is the target. */
+ final Runnable runnable;
- public final static int MAX_PRIORITY = 10;
+ /** The name of this thread */
+ String name;
- public final static int MIN_PRIORITY = 1;
+ /** Is this a daemon thread? */
+ private boolean daemon;
- public final static int NORM_PRIORITY = 5;
+ /** The context classloader of this thread */
+ private ClassLoader contextClassLoader;
+ /** The thread in which I was created */
+ private final Thread parent;
+
+ /** The default exception handler. */
+ private static UncaughtExceptionHandler defaultHandler;
+
/** Thread local storage. Package accessible for use by
* InheritableThreadLocal.
*/
WeakHashMap locals;
- /**
- * Gets the active number of threads in the current thread's thread group.
- *
- * @return the active number of threads in the current thread's thread
- * group.
- */
- public static int activeCount() {
- return currentThread().getThreadGroup().activeCount();
- }
+ /** The uncaught exception handler. */
+ UncaughtExceptionHandler exceptionHandler;
/**
- * Generate a "unique" default name for a thread.
+ * Number of threads created. Used only for generating "unique" names.
+ *
+ * @see java.lang.Thread#autoName()
*/
- private static synchronized String autoName() {
- return "Thread-" + (++count);
- }
+ private static int count = 0;
- /**
- * Gets the current thread.
- *
- * @return
- */
- public static Thread currentThread() {
- VmThread current = VmThread.currentThread();
- if (current != null) {
- return current.asThread();
- } else {
- return null;
- }
- }
+ private static final JNodePermission GETVMTHREAD_PERM = new JNodePermission(
+ "getVmThread");
/**
- * Prints a stack trace of the current thread.
- */
- public static void dumpStack() {
- new Exception("Stack trace").printStackTrace();
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, null,</code>
+ * <i>gname</i><code>)</code>, where <b><i>gname</i></b> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ * <p>
+ * Threads created this way must have overridden their
+ * <code>run()</code> method to actually do anything. An example
+ * illustrating this method being used follows:
+ * <p><blockquote><pre>
+ * import java.lang.*;
+ *
+ * class plain01 implements Runnable {
+ * String name;
+ * plain01() {
+ * name = null;
+ * }
+ * plain01(String s) {
+ * name = s;
+ * }
+ * public void run() {
+ * if (name == null)
+ * System.out.println("A new thread created");
+ * else
+ * System.out.println("A new thread with name " + name +
+ * " created");
+ * }
+ * }
+ * class threadtest01 {
+ * public static void main(String args[] ) {
+ * int failed = 0 ;
+ *
+ * <b>Thread t1 = new Thread();</b>
+ * if (t1 != null)
+ * System.out.println("new Thread() succeed");
+ * else {
+ * System.out.println("new Thread() failed");
+ * failed++;
+ * }
+ * }
+ * }
+ * </pre></blockquote>
+ *
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
+ */
+ public Thread()
+ {
+ this(null, null, autoName());
}
- public static int enumerate(Thread[] threads) {
- return currentThread().getThreadGroup().enumerate(threads);
- }
-
/**
- * Checks whether the current thread holds the monitor on a given object.
- * This allows you to do <code>assert Thread.holdsLock(obj)</code>.
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, target,</code>
+ * <i>gname</i><code>)</code>, where <i>gname</i> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
*
- * @param obj
- * the object to test lock ownership on.
- * @return true if the current thread is currently synchronized on obj
- * @throws NullPointerException
- * if obj is null
- * @since 1.4
+ * @param target the object whose <code>run</code> method is called.
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
*/
- public static boolean holdsLock(Object obj) {
- return MonitorManager.holdsLock(obj);
+ public Thread(Runnable target)
+ {
+ this(null, target, autoName());
}
/**
- * Has the current thread been interrupted.
- * The interrupted flag is cleared.
- * @return
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, null, name)</code>.
+ *
+ * @param name the name of the new thread.
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
*/
- public static boolean interrupted() {
- VmThread current = VmThread.currentThread();
- if (current != null) {
- return current.isInterrupted(true);
- } else {
- return false;
- }
+ public Thread(String name)
+ {
+ this(null, null, name);
}
- public static void sleep(long millis) throws InterruptedException {
- sleep(millis, 0);
- }
-
/**
- * XXX needs to be synchronized to avoid losing interrupts? it checks and
- * sets state, which should be protected...
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(group, target,</code>
+ * <i>gname</i><code>)</code>, where <i>gname</i> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see #Thread(ThreadGroup, Runnable, String)
*/
- public static void sleep(long millis, int nanos)
- throws InterruptedException {
- VmThread.currentThread().sleep(millis, nanos);
+ public Thread(ThreadGroup group, Runnable target)
+ {
+ this(group, target, autoName());
}
- public static void yield() {
- VmThread.yield();
- }
-
- /** The context classloader of this thread */
- private ClassLoader contextClassLoader;
-
- /** Is this a daemon thread? */
- private boolean daemon;
-
- /** The group this thread belongs to */
- ThreadGroup group;
-
- /** The name of this thread */
- String name;
-
- /** The thread in which I was created */
- private final Thread parent;
-
- /** A runnable target (if any) */
- private final Runnable target;
-
- /** The VM thread implementing this thread */
- private final VmThread vmThread;
-
/**
- * Create a new default instance
- *
- * @see java.lang.Object#Object()
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(group, null, name)</code>
+ *
+ * @param group the group to put the Thread into
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see #Thread(ThreadGroup, Runnable, String)
*/
- public Thread() {
- this(null, null, autoName());
+ public Thread(ThreadGroup group, String name)
+ {
+ this(group, null, name);
}
/**
- * Create a new instance with a runnable as thread runner.
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, target, name)</code>.
*
- * @param target
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @see #Thread(ThreadGroup, Runnable, String)
*/
- public Thread(Runnable target) {
- this(null, target, autoName());
- }
-
- /**
- * Create a new instance with a runnable as thread runner and a given name.
- *
- * @param target
- * @param name
- */
- public Thread(Runnable target, String name) {
+ public Thread(Runnable target, String name)
+ {
this(null, target, name);
}
/**
- * Create a new instance with a given name.
+ * Allocate a new Thread object, with the specified ThreadGroup and name, and
+ * using the specified Runnable object's <code>run()</code> method to
+ * execute. If the Runnable object is null, <code>this</code> (which is
+ * a Runnable) is used instead.
*
- * @param name
+ * <p>If the ThreadGroup is null, the security manager is checked. If a
+ * manager exists and returns a non-null object for
+ * <code>getThreadGroup</code>, that group is used; otherwise the group
+ * of the creating thread is used. Note that the security manager calls
+ * <code>checkAccess</code> if the ThreadGroup is not null.
+ *
+ * <p>The new Thread will inherit its creator's priority and daemon status.
+ * These can be changed with <code>setPriority</code> and
+ * <code>setDaemon</code>.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see Runnable#run()
+ * @see #run()
+ * @see #setDaemon(boolean)
+ * @see #setPriority(int)
+ * @see SecurityManager#checkAccess(ThreadGroup)
+ * @see ThreadGroup#checkAccess()
*/
- public Thread(String name) {
- this(null, null, name);
- }
-
- /**
- * Create a new instance with a given group as containing group and a
- * runnable as thread runner.
- *
- * @param group
- * @param target
- */
- public Thread(ThreadGroup group, Runnable target) {
- this(group, target, autoName());
- }
-
- /**
- * Create a new instance with a given group as containing group, a runnable
- * as thread runner and a given name.
- *
- * @param group
- * @param target
- * @param name
- */
- public Thread(ThreadGroup group, Runnable target, String name) {
+ public Thread(ThreadGroup group, Runnable target, String name)
+ {
Thread current = currentThread();
if (group != null) {
@@ -246,7 +331,7 @@
group.addThread(this);
this.group = group;
- this.target = target;
+ this.runnable = target;
this.name = name;
this.parent = current;
@@ -296,7 +381,7 @@
group.addThread(this);
this.group = group;
- this.target = target;
+ this.runnable = target;
this.name = name;
this.parent = current;
@@ -328,7 +413,7 @@
group.addThread(this);
...
[truncated message content] |