diff --git a/AppKit/CPDatePicker/CPDatePicker.j b/AppKit/CPDatePicker/CPDatePicker.j index 922e8cbd9..d7065ddc8 100644 --- a/AppKit/CPDatePicker/CPDatePicker.j +++ b/AppKit/CPDatePicker/CPDatePicker.j @@ -533,10 +533,10 @@ CPEraDatePickerElementFlag = 0x0100; { if (_datePickerStyle == CPTextFieldAndStepperDatePickerStyle || _datePickerStyle == CPTextFieldDatePickerStyle) { - if ([super becomeFirstResponder]) + if (![super becomeFirstResponder]) return NO; - [_datePickerTextfield _selecteTextFieldWithFlags:[[CPApp currentEvent] modifierFlags]]; + [_datePickerTextfield _selectTextFieldWithFlags:[[CPApp currentEvent] modifierFlags]]; return YES; } diff --git a/AppKit/CPDatePicker/_CPDatePickerCalendar.j b/AppKit/CPDatePicker/_CPDatePickerCalendar.j index a7e444ca8..165e91ec1 100644 --- a/AppKit/CPDatePicker/_CPDatePickerCalendar.j +++ b/AppKit/CPDatePicker/_CPDatePickerCalendar.j @@ -894,14 +894,46 @@ var CPShortWeekDayNameArrayEn = [@"Mo", @"Tu", @"We", @"Th", @"Fr", @"Sa", @"Su" // Check if we have to change or not the month of the component if ([dayTile date].getMonth() == _date.getMonth()) { - var minDate = [[_datePicker minDate] copy], - maxDate = [[_datePicker maxDate] copy]; + if ([_datePicker datePickerMode] == CPRangeDateMode && [anEvent modifierFlags] & CPShiftKeyMask) + { + var dateValueAtMidnight = [[_datePicker dateValue] copy]; - [minDate _resetToMidnight]; - [maxDate _resetToLastSeconds]; + [dateValueAtMidnight _resetToMidnight]; - if (dateTile >= minDate && dateTile <= maxDate) - [_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:dateTile] timeInterval:0]; + if (dateTile < dateValueAtMidnight) + { + var interval; + + if (dateTile == dateValueAtMidnight) + interval = [_datePicker timeInterval]; + else + interval = ([dateValueAtMidnight timeIntervalSinceDate:dateTile] + [_datePicker timeInterval]); + + [_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:dateTile] timeInterval:interval]; + } + else if ([[dayTile date] isEqualToDate:dateValueAtMidnight]) + { + [_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:dateTile] timeInterval:0]; + } + else + { + [_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:[dateValueAtMidnight copy]] timeInterval:([dateTile timeIntervalSinceDate:dateValueAtMidnight])]; + } + + // Be sure to display the good month + [_delegate setDateValue:dateTile]; + } + else + { + var minDate = [[_datePicker minDate] copy], + maxDate = [[_datePicker maxDate] copy]; + + [minDate _resetToMidnight]; + [maxDate _resetToLastSeconds]; + + if (dateTile >= minDate && dateTile <= maxDate) + [_datePicker _setDateValue:[self _hoursMinutesSecondsFromDatePickerForDate:dateTile] timeInterval:0]; + } } else { diff --git a/AppKit/CPDatePicker/_CPDatePickerTextField.j b/AppKit/CPDatePicker/_CPDatePickerTextField.j index 02c7a7148..e002707ad 100644 --- a/AppKit/CPDatePicker/_CPDatePickerTextField.j +++ b/AppKit/CPDatePicker/_CPDatePickerTextField.j @@ -180,7 +180,7 @@ var CPZeroKeyCode = 48, #pragma mark - #pragma mark SelectTextField action -- (void)_selecteTextFieldWithFlags:(unsigned)flags +- (void)_selectTextFieldWithFlags:(unsigned)flags { [_datePickerElementView _updateResponderTextField]; @@ -1226,14 +1226,14 @@ var CPMonthDateType = 0, CPTimer _timerEdition; } - -#pragma mark - -#pragma mark Getter Setter methods - -- (BOOL)acceptFirstResponder +- (id)init { - _firstEvent = YES; - return NO; + if (self = [super init]) + { + _firstEvent = YES; + } + + return self; } /*! Set the dateType of the textField diff --git a/AppKit/CPTabView.j b/AppKit/CPTabView.j index 6aa303cae..0e3ac7030 100644 --- a/AppKit/CPTabView.j +++ b/AppKit/CPTabView.j @@ -391,6 +391,7 @@ var CPTabViewDidSelectTabViewItemSelector = 1 << 1, [_box setFrame:CGRectMake(0, origin, CGRectGetWidth(aFrame), CGRectGetHeight(aFrame) - segmentedHeight / 2)]; + [self _updateItems]; [self _repositionTabs]; } } diff --git a/AppKit/CPTabViewItem.j b/AppKit/CPTabViewItem.j index c2e4347ea..6c073b1d0 100644 --- a/AppKit/CPTabViewItem.j +++ b/AppKit/CPTabViewItem.j @@ -90,6 +90,7 @@ CPPressedTab = 2; - (void)setLabel:(CPString)aLabel { _label = aLabel; + [_tabView setNeedsLayout]; } /*! diff --git a/AppKit/CPTableView.j b/AppKit/CPTableView.j index acac9078e..51074d6c6 100644 --- a/AppKit/CPTableView.j +++ b/AppKit/CPTableView.j @@ -5077,10 +5077,16 @@ Your delegate can implement this method to avoid subclassing the tableview to ad [self getColumn:@ref(column) row:@ref(row) forView:responder]; + if (row == CPNotFound && column == CPNotFound) + [self _notifyViewDidResignFirstResponder]; _editingRow = row; _editingColumn = column; - if (_editingRow !== CPNotFound && _editingColumn !== CPNotFound && [responder isKindOfClass:[CPTextField class]] && (!_isViewBased || ![responder isBezeled])) + // We want to keep the 'First Responder' theme state for the table view as a whole, even when a subview is being edited. + // This makes sure the theming effects of a focused table remain in effect even as cells are being edited in it. + [self _notifyViewDidBecomeFirstResponder]; + + if (_editingRow !== CPNotFound && [responder isKindOfClass:[CPTextField class]] && ![responder isBezeled]) { [responder setBezeled:YES]; [self _registerForEndEditingNote:responder]; diff --git a/AppKit/Platform/DOM/CPPlatformPasteboard.j b/AppKit/Platform/DOM/CPPlatformPasteboard.j index 014d00d06..e749a1fae 100644 --- a/AppKit/Platform/DOM/CPPlatformPasteboard.j +++ b/AppKit/Platform/DOM/CPPlatformPasteboard.j @@ -71,7 +71,6 @@ var hasEditableTarget = function(aDOMEvent) BOOL hasBugWhichPreventsNonEditablePaste; BOOL hasBugWhichPreventsNonEditablePasteRedirect; - CPEvent _lastKeyDownEvent; BOOL currentEventIsNativePasteEvent; BOOL currentEventIsNativeCopyOrCutEvent; BOOL currentEventShouldBeSuppressed; @@ -208,8 +207,6 @@ var hasEditableTarget = function(aDOMEvent) if (!(modifierFlags & (CPControlKeyMask | CPCommandKeyMask))) return; - _lastKeyDownEvent = anEvent; - var aDOMEvent = anEvent._DOMEvent, characters = [anEvent characters], mayRequireDOMPasteboardElement = [self _mayRequireDOMPasteboardElementHack:aDOMEvent flags:modifierFlags]; @@ -302,7 +299,7 @@ var hasEditableTarget = function(aDOMEvent) timestamp = [CPEvent currentTimestamp], // fake event, might as well use current timestamp windowNumber = [[CPApp keyWindow] windowNumber], modifierFlags = CPPlatformActionKeyMask, - location = [_lastKeyDownEvent locationInWindow], + location = [[CPApp currentEvent] locationInWindow], anEvent = [CPEvent keyEventWithType:CPKeyDown location:location modifierFlags:modifierFlags timestamp:timestamp windowNumber:windowNumber context:nil characters:characters charactersIgnoringModifiers:characters isARepeat:NO keyCode:keyCode]; diff --git a/AppKit/Themes/Aristo/ThemeDescriptors.j b/AppKit/Themes/Aristo/ThemeDescriptors.j index 9d7eff56c..a88a1de84 100755 --- a/AppKit/Themes/Aristo/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo/ThemeDescriptors.j @@ -986,22 +986,22 @@ var themedButtonValues = nil, [@"vertical-alignment", CPCenterVerticalTextAlignment, CPThemeStateTableDataView], [@"content-inset", CGInsetMake(3.0, 3.0, 3.0, 5.0), CPThemeStateTableDataView], - [@"text-color", [CPColor colorWithCalibratedWhite:51.0 / 255.0 alpha:1.0], CPThemeStateTableDataView], - [@"text-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], - [@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateSelectedDataView]], - [@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateEditable]], - [@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateEditing]], - [@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateBezeled]], - [@"content-inset", CGInsetMake(8.0, 8.0, 7.0, 5.0), [CPThemeStateTableDataView, CPThemeStateEditing]], - [@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateEditing]], - [@"bezel-inset", CGInsetMake(-1.0, -1.0, -1.0, -1.0), [CPThemeStateTableDataView, CPThemeStateEditing]], + [@"text-color", [CPColor colorWithCalibratedWhite:51.0 / 255.0 alpha:1.0], CPThemeStateTableDataView], + [@"text-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], + [@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateSelectedDataView]], + [@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateEditable]], + [@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateEditing]], + [@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateBezeled]], + [@"content-inset", CGInsetMake(8.0, 8.0, 7.0, 5.0), [CPThemeStateTableDataView, CPThemeStateEditing]], + [@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateEditing]], + [@"bezel-inset", CGInsetMake(-1.0, -1.0, -1.0, -1.0), [CPThemeStateTableDataView, CPThemeStateEditing]], [@"text-color", [CPColor colorWithCalibratedWhite:125.0 / 255.0 alpha:1.0], [CPThemeStateTableDataView, CPThemeStateGroupRow]], - [@"text-color", [CPColor colorWithCalibratedWhite:1.0 alpha:1.0], [CPThemeStateTableDataView, CPThemeStateGroupRow, CPThemeStateSelectedDataView]], - [@"text-shadow-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateGroupRow]], - [@"text-shadow-offset", CGSizeMake(0,1), [CPThemeStateTableDataView, CPThemeStateGroupRow]], - [@"text-shadow-color", [CPColor colorWithCalibratedWhite:0.0 alpha:0.6], [CPThemeStateTableDataView, CPThemeStateGroupRow, CPThemeStateSelectedDataView]], - [@"font", [CPFont boldSystemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateGroupRow]] + [@"text-color", [CPColor colorWithCalibratedWhite:1.0 alpha:1.0], [CPThemeStateTableDataView, CPThemeStateGroupRow, CPThemeStateSelectedDataView]], + [@"text-shadow-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateGroupRow]], + [@"text-shadow-offset", CGSizeMake(0,1), [CPThemeStateTableDataView, CPThemeStateGroupRow]], + [@"text-shadow-color", [CPColor colorWithCalibratedWhite:0.0 alpha:0.6], [CPThemeStateTableDataView, CPThemeStateGroupRow, CPThemeStateSelectedDataView]], + [@"font", [CPFont boldSystemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateGroupRow]] ]; [self registerThemeValues:themedTextFieldValues forView:textfield]; diff --git a/AppKit/Themes/Aristo2/ThemeDescriptors.j b/AppKit/Themes/Aristo2/ThemeDescriptors.j index a970a203e..960d5d994 100644 --- a/AppKit/Themes/Aristo2/ThemeDescriptors.j +++ b/AppKit/Themes/Aristo2/ThemeDescriptors.j @@ -558,21 +558,21 @@ var themedButtonValues = nil, [@"vertical-alignment", CPCenterVerticalTextAlignment, CPThemeStateTableDataView], [@"content-inset", CGInsetMake(0.0, 0.0, 0.0, 5.0), CPThemeStateTableDataView], - [@"text-color", [CPColor colorWithCalibratedWhite:51.0 / 255.0 alpha:1.0], CPThemeStateTableDataView], - [@"text-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], - [@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateSelectedDataView]], - [@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateEditing, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], - [@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateEditable, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], - [@"content-inset", CGInsetMake(7.0, 7.0, 5.0, 10.0), [CPThemeStateTableDataView, CPThemeStateEditable]], - [@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateEditing]], - [@"bezel-inset", CGInsetMake(-2.0, -2.0, -2.0, -2.0), [CPThemeStateTableDataView, CPThemeStateEditing]], + [@"text-color", [CPColor colorWithCalibratedWhite:51.0 / 255.0 alpha:1.0], CPThemeStateTableDataView], + [@"text-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], + [@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateSelectedDataView]], + [@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateEditing, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], + [@"text-color", [CPColor blackColor], [CPThemeStateTableDataView, CPThemeStateSelectedDataView, CPThemeStateEditable, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], + [@"content-inset", CGInsetMake(7.0, 7.0, 5.0, 10.0), [CPThemeStateTableDataView, CPThemeStateEditable]], + [@"font", [CPFont systemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateEditing]], + [@"bezel-inset", CGInsetMake(-2.0, -2.0, -2.0, -2.0), [CPThemeStateTableDataView, CPThemeStateEditing]], [@"text-color", [CPColor colorWithCalibratedWhite:125.0 / 255.0 alpha:1.0], [CPThemeStateTableDataView, CPThemeStateGroupRow]], - [@"text-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateGroupRow, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], - [@"text-shadow-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateGroupRow]], - [@"text-shadow-offset", CGSizeMake(0, 1), [CPThemeStateTableDataView, CPThemeStateGroupRow]], - [@"text-shadow-color", [CPColor colorWithCalibratedWhite:0.0 alpha:0.6], [CPThemeStateTableDataView, CPThemeStateGroupRow, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], - [@"font", [CPFont boldSystemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateGroupRow]] + [@"text-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateGroupRow, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], + [@"text-shadow-color", [CPColor whiteColor], [CPThemeStateTableDataView, CPThemeStateGroupRow]], + [@"text-shadow-offset", CGSizeMake(0, 1), [CPThemeStateTableDataView, CPThemeStateGroupRow]], + [@"text-shadow-color", [CPColor colorWithCalibratedWhite:0.0 alpha:0.6], [CPThemeStateTableDataView, CPThemeStateGroupRow, CPThemeStateSelectedDataView, CPThemeStateFirstResponder, CPThemeStateKeyWindow]], + [@"font", [CPFont boldSystemFontOfSize:CPFontCurrentSystemSize], [CPThemeStateTableDataView, CPThemeStateGroupRow]] ]; [self registerThemeValues:themedTextFieldValues forView:textfield]; diff --git a/AppKit/_CPPopUpList.j b/AppKit/_CPPopUpList.j index b6e400ff0..f69f68f0a 100644 --- a/AppKit/_CPPopUpList.j +++ b/AppKit/_CPPopUpList.j @@ -863,6 +863,15 @@ var _CPPopUpListDataSourceKey = @"_CPPopUpListDataSourceKey", return self; } +/*! + Returns \c YES if the receiver is able to receive input events + even when a modal session is active. +*/ +- (BOOL)worksWhenModal +{ + return YES; +} + - (void)sendEvent:(CPEvent)anEvent { var type = [anEvent type]; diff --git a/AppKit/_CPPopoverWindow.j b/AppKit/_CPPopoverWindow.j index 8861a9f56..899fab08b 100644 --- a/AppKit/_CPPopoverWindow.j +++ b/AppKit/_CPPopoverWindow.j @@ -55,8 +55,9 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4, int _appearance @accessors(getter=appearance); BOOL _isClosing @accessors(property=isClosing); - BOOL _closeOnBlur; BOOL _browserAnimates; + BOOL _closeOnBlur; + BOOL _isObservingFrame; BOOL _shouldPerformAnimation; CPInteger _implementedDelegateMethods; JSObject _orderOutTransitionFunction; @@ -160,6 +161,32 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4, #pragma mark - #pragma mark Observer +/*! + @ignore + Adds self as frame observer if not already observing it +*/ +- (void)_addFrameObserver +{ + if (_isObservingFrame) + return; + + _isObservingFrame = YES; + [_targetView addObserver:self forKeyPath:@"frame" options:0 context:nil]; +} + +/*! + @ignore + Removes self as frame observer if already observing it +*/ +- (void)_removeFrameObserver +{ + if (!_isObservingFrame) + return; + + _isObservingFrame = NO; + [_targetView removeObserver:self forKeyPath:@"frame"]; +} + /*! Update the _CPPopoverWindow frame if a resize event is observed. */ @@ -331,7 +358,7 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4, if (positioningView !== _targetView) { [[_targetView window] removeChildWindow:self]; - [_targetView removeObserver:self forKeyPath:@"frame"]; + [self _removeFrameObserver]; _targetView = positioningView; } @@ -521,14 +548,14 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4, - (void)_orderFront { if (![self isVisible]) - [_targetView addObserver:self forKeyPath:@"frame" options:0 context:nil]; + [self _addFrameObserver]; [super _orderFront]; } - (void)_parentDidOrderInChild { - [_targetView addObserver:self forKeyPath:@"frame" options:0 context:nil]; + [self _addFrameObserver]; } /*! @@ -564,7 +591,7 @@ var _CPPopoverWindow_shouldClose_ = 1 << 4, _DOMElement.removeEventListener(CPBrowserStyleProperty("transitionend"), _orderOutTransitionFunction, YES); #endif - [_targetView removeObserver:self forKeyPath:@"frame"]; + [self _removeFrameObserver]; [_parentWindow removeChildWindow:self]; [super _orderOutRecursively:recursive]; diff --git a/Foundation/CPDate.j b/Foundation/CPDate.j index 86bf25deb..736ca9ff2 100644 --- a/Foundation/CPDate.j +++ b/Foundation/CPDate.j @@ -146,6 +146,15 @@ var CPDateReferenceDate = new Date(Date.UTC(2001, 0, 1, 0, 0, 0, 0)); return [[CPDate date] timeIntervalSinceReferenceDate]; } +/** + Return a new date representing the receiver's time plus the given interval into the future, + or into the past for a negative interval. +*/ +- (id)dateByAddingTimeInterval:(CPTimeInterval)seconds +{ + return [[CPDate alloc] initWithTimeInterval:seconds sinceDate:self]; +} + - (BOOL)isEqual:(CPDate)aDate { if (self === aDate) diff --git a/Tests/Foundation/CPDateTest.j b/Tests/Foundation/CPDateTest.j index 996d05787..4223e2168 100644 --- a/Tests/Foundation/CPDateTest.j +++ b/Tests/Foundation/CPDateTest.j @@ -35,6 +35,30 @@ [self assert:middle equals:[middle laterDate:past] message:"laterDate incorrect"]; } +- (void)testDateByAddingTimeIntervalZeroShouldReturnSameDate +{ + var a = [CPDate dateWithTimeIntervalSince1970:1231889490.0], + b = [a dateByAddingTimeInterval:0]; + + [self assert:[b timeIntervalSince1970] equals:1231889490]; +} + +- (void)testDateByAddingTimeIntervalPositiveShouldReturnNewerDate +{ + var a = [CPDate dateWithTimeIntervalSince1970:1231889490.0], + b = [a dateByAddingTimeInterval:789]; + + [self assert:[b timeIntervalSince1970] equals:1231889490 + 789]; +} + +- (void)testDateByAddingTimeIntervalNegativeShouldReturnOlderDate +{ + var a = [CPDate dateWithTimeIntervalSince1970:1231889490.0], + b = [a dateByAddingTimeInterval:-789]; + + [self assert:[b timeIntervalSince1970] equals:1231889490 - 789]; +} + - (void)testEquals { var now = [CPDate date]; diff --git a/bootstrap.sh b/bootstrap.sh index 7ae61916e..92cc46028 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -134,8 +134,8 @@ function check_install_environment () { java_version=$(java -version 2>&1) echo $java_version | grep OpenJDK > /dev/null if [ "$?" = "0" ]; then # OpenJDK: make sure >= 6b18 - openjdk_version=$(echo $java_version | egrep -o '[0-9]b[0-9]+') - if [ $(echo $openjdk_version | tr -d 'b') -lt 618 ]; then + openjdk_version=$(echo $java_version | egrep -o '[0-9]\-?b[0-9]+') + if [ $(echo $openjdk_version | tr -d 'b' | tr -d '-') -lt 618 ]; then echo "Error: Narwhal is not compatible with your version of OpenJDK: $openjdk_version." echo "Please upgrade to OpenJDK >= 6b18 or switch to the Sun JVM. Then re-run bootstrap.sh." exit 1