Browse Source

SwingSet3

master
Konstantin Bulenkov 11 years ago
parent
commit
c4c9517d5d
  1. 9
      .idea/copyright/JetBrains.xml
  2. 6
      .idea/copyright/profiles_settings.xml
  3. 7
      .idea/fileColors.xml
  4. 13
      .idea/libraries/SwingSet3_Libraries.xml
  5. 2
      .idea/misc.xml
  6. 3
      .idea/scopes/Darcula.xml
  7. 3
      .idea/scopes/Demos.xml
  8. 2
      Darcula.iml
  9. BIN
      lib/demo/AnimatedTransitions.jar
  10. BIN
      lib/demo/AppFramework.jar
  11. BIN
      lib/demo/TimingFramework.jar
  12. BIN
      lib/demo/swing-worker.jar
  13. BIN
      lib/demo/swingx.jar
  14. 16
      src/com/bulenkov/darcula/DarculaDefaultTableHeaderRenderer.java
  15. 17
      src/com/bulenkov/darcula/DarculaLaf.java
  16. 16
      src/com/bulenkov/darcula/DarculaLookAndFeelInfo.java
  17. 98
      src/com/bulenkov/darcula/DarculaMetalTheme.java
  18. 16
      src/com/bulenkov/darcula/DarculaTableHeaderBorder.java
  19. 2
      src/com/bulenkov/darcula/DarculaTableHeaderUI.java
  20. 2
      src/com/bulenkov/darcula/DarculaUIUtil.java
  21. 2
      src/com/bulenkov/darcula/darcula.css
  22. 16
      src/com/bulenkov/darcula/darcula.properties
  23. 16
      src/com/bulenkov/darcula/darcula_linux.properties
  24. 16
      src/com/bulenkov/darcula/darcula_mac.properties
  25. 28
      src/com/bulenkov/darcula/darcula_windows.properties
  26. 2
      src/com/bulenkov/darcula/ui/DarculaButtonPainter.java
  27. 2
      src/com/bulenkov/darcula/ui/DarculaButtonUI.java
  28. 2
      src/com/bulenkov/darcula/ui/DarculaCheckBoxBorder.java
  29. 2
      src/com/bulenkov/darcula/ui/DarculaCheckBoxUI.java
  30. 2
      src/com/bulenkov/darcula/ui/DarculaComboBoxUI.java
  31. 2
      src/com/bulenkov/darcula/ui/DarculaEditorPaneUI.java
  32. 2
      src/com/bulenkov/darcula/ui/DarculaInternalBorder.java
  33. 2
      src/com/bulenkov/darcula/ui/DarculaInternalFrameUI.java
  34. 2
      src/com/bulenkov/darcula/ui/DarculaMenuBarBorder.java
  35. 16
      src/com/bulenkov/darcula/ui/DarculaMenuBarUI.java
  36. 16
      src/com/bulenkov/darcula/ui/DarculaMenuItemBorder.java
  37. 2
      src/com/bulenkov/darcula/ui/DarculaPanelUI.java
  38. 2
      src/com/bulenkov/darcula/ui/DarculaPasswordFieldUI.java
  39. 2
      src/com/bulenkov/darcula/ui/DarculaPopupMenuBorder.java
  40. 2
      src/com/bulenkov/darcula/ui/DarculaProgressBarBorder.java
  41. 2
      src/com/bulenkov/darcula/ui/DarculaProgressBarUI.java
  42. 2
      src/com/bulenkov/darcula/ui/DarculaRadioButtonUI.java
  43. 2
      src/com/bulenkov/darcula/ui/DarculaRootPaneUI.java
  44. 2
      src/com/bulenkov/darcula/ui/DarculaScrollBarUI.java
  45. 2
      src/com/bulenkov/darcula/ui/DarculaSpinnerBorder.java
  46. 2
      src/com/bulenkov/darcula/ui/DarculaSpinnerUI.java
  47. 2
      src/com/bulenkov/darcula/ui/DarculaTabbedPaneUI.java
  48. 2
      src/com/bulenkov/darcula/ui/DarculaTextBorder.java
  49. 2
      src/com/bulenkov/darcula/ui/DarculaTextFieldUI.java
  50. 2
      src/com/bulenkov/darcula/ui/DarculaTitlePane.java
  51. 16
      src/com/bulenkov/darcula/ui/DarculaToolBarUI.java
  52. 2
      src/com/bulenkov/darcula/ui/DarculaTreeUI.java
  53. 16
      src/com/bulenkov/darcula/ui/win/DarculaWindowsInternalFrameUI.java
  54. 16
      src/com/bulenkov/darcula/util/Animator.java
  55. 16
      src/com/bulenkov/darcula/util/DarculaColors.java
  56. 30
      swingset2/SwingSet2.java
  57. 22
      swingset3/META-INF/demolist
  58. 0
      swingset3/META-INF/services/javax.swing.LookAndFeel
  59. 57
      swingset3/com/sun/swingset3/AboutBox.java
  60. 350
      swingset3/com/sun/swingset3/Demo.java
  61. 291
      swingset3/com/sun/swingset3/DemoPanel.java
  62. 48
      swingset3/com/sun/swingset3/DemoProperties.java
  63. 370
      swingset3/com/sun/swingset3/DemoSelectorPanel.java
  64. 131
      swingset3/com/sun/swingset3/IntroPanel.java
  65. 707
      swingset3/com/sun/swingset3/SwingSet3.java
  66. 410
      swingset3/com/sun/swingset3/codeview/CodeStyler.java
  67. 927
      swingset3/com/sun/swingset3/codeview/CodeViewer.java
  68. 51
      swingset3/com/sun/swingset3/codeview/Snippet.java
  69. 661
      swingset3/com/sun/swingset3/codeview/SnippetHighlighter.java
  70. 339
      swingset3/com/sun/swingset3/codeview/SnippetMap.java
  71. 322
      swingset3/com/sun/swingset3/codeview/SnippetNavigator.java
  72. 143
      swingset3/com/sun/swingset3/codeview/SnippetParser.java
  73. 16
      swingset3/com/sun/swingset3/codeview/resources/CodeViewer.properties
  74. BIN
      swingset3/com/sun/swingset3/codeview/resources/images/snippetglyph.png
  75. BIN
      swingset3/com/sun/swingset3/codeview/resources/images/snippetglyph.psd
  76. 129
      swingset3/com/sun/swingset3/demos/DemoUtilities.java
  77. 238
      swingset3/com/sun/swingset3/demos/JGridPanel.java
  78. 244
      swingset3/com/sun/swingset3/demos/JHyperlink.java
  79. 84
      swingset3/com/sun/swingset3/demos/ResourceManager.java
  80. 132
      swingset3/com/sun/swingset3/demos/Stacker.java
  81. 226
      swingset3/com/sun/swingset3/demos/button/ButtonDemo.java
  82. 1
      swingset3/com/sun/swingset3/demos/button/resources/ButtonDemo.html
  83. BIN
      swingset3/com/sun/swingset3/demos/button/resources/images/ButtonDemo.gif
  84. BIN
      swingset3/com/sun/swingset3/demos/button/resources/images/blogs.png
  85. BIN
      swingset3/com/sun/swingset3/demos/button/resources/images/document-print.png
  86. BIN
      swingset3/com/sun/swingset3/demos/button/resources/images/earth_day.gif
  87. BIN
      swingset3/com/sun/swingset3/demos/button/resources/images/earth_night.gif
  88. BIN
      swingset3/com/sun/swingset3/demos/button/resources/images/edit-find.png
  89. BIN
      swingset3/com/sun/swingset3/demos/button/resources/images/redbutton.png
  90. BIN
      swingset3/com/sun/swingset3/demos/button/resources/images/redbutton_dark.png
  91. BIN
      swingset3/com/sun/swingset3/demos/button/resources/images/redbutton_glow.png
  92. 270
      swingset3/com/sun/swingset3/demos/colorchooser/BezierAnimationPanel.java
  93. 186
      swingset3/com/sun/swingset3/demos/colorchooser/ColorChooserDemo.java
  94. 11
      swingset3/com/sun/swingset3/demos/colorchooser/resources/ColorChooserDemo.properties
  95. BIN
      swingset3/com/sun/swingset3/demos/colorchooser/resources/images/ColorChooserDemo.gif
  96. 445
      swingset3/com/sun/swingset3/demos/combobox/ComboBoxDemo.java
  97. 42
      swingset3/com/sun/swingset3/demos/combobox/resources/ComboBoxDemo.properties
  98. BIN
      swingset3/com/sun/swingset3/demos/combobox/resources/images/ComboBoxDemo.gif
  99. BIN
      swingset3/com/sun/swingset3/demos/combobox/resources/images/brenteyes.jpg
  100. BIN
      swingset3/com/sun/swingset3/demos/combobox/resources/images/brenthair.jpg
  101. Some files were not shown because too many files have changed in this diff Show More

9
.idea/copyright/JetBrains.xml

@ -0,0 +1,9 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright 2000-&amp;#36;today.year JetBrains s.r.o.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
<option name="keyword" value="Copyright" />
<option name="allowReplaceKeyword" value="" />
<option name="myName" value="JetBrains" />
<option name="myLocal" value="true" />
</copyright>
</component>

6
.idea/copyright/profiles_settings.xml

@ -1,3 +1,7 @@
<component name="CopyrightManager"> <component name="CopyrightManager">
<settings default="" /> <settings default="">
<module2copyright>
<element module="Darcula" copyright="JetBrains" />
</module2copyright>
</settings>
</component> </component>

7
.idea/fileColors.xml

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SharedFileColors">
<fileColor scope="Demos" color="Blue" />
</component>
</project>

13
.idea/libraries/SwingSet3_Libraries.xml

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="SwingSet3 Libraries">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/demo/AnimatedTransitions.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/demo/AppFramework.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/demo/swing-worker.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/demo/swingx.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/demo/TimingFramework.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

2
.idea/misc.xml

@ -6,7 +6,7 @@
<component name="ProjectKey"> <component name="ProjectKey">
<option name="state" value="https://bulenkov@bitbucket.org/bulenkov/darcula.git" /> <option name="state" value="https://bulenkov@bitbucket.org/bulenkov/darcula.git" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
</project> </project>

3
.idea/scopes/Darcula.xml

@ -0,0 +1,3 @@
<component name="DependencyValidationManager">
<scope name="Darcula" pattern="file:src//*" />
</component>

3
.idea/scopes/Demos.xml

@ -0,0 +1,3 @@
<component name="DependencyValidationManager">
<scope name="Demos" pattern="file:swingset2//*||file:swingset3//*" />
</component>

2
Darcula.iml

@ -5,10 +5,12 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/swingset2" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/swingset2" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/swingset3" isTestSource="false" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="IconLoader" level="project" /> <orderEntry type="library" name="IconLoader" level="project" />
<orderEntry type="library" name="SwingSet3 Libraries" level="project" />
</component> </component>
</module> </module>

BIN
lib/demo/AnimatedTransitions.jar

Binary file not shown.

BIN
lib/demo/AppFramework.jar

Binary file not shown.

BIN
lib/demo/TimingFramework.jar

Binary file not shown.

BIN
lib/demo/swing-worker.jar

Binary file not shown.

BIN
lib/demo/swingx.jar

Binary file not shown.

16
src/com/bulenkov/darcula/DarculaDefaultTableHeaderRenderer.java

@ -1,3 +1,19 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula; package com.bulenkov.darcula;
import javax.swing.*; import javax.swing.*;

17
src/com/bulenkov/darcula/DarculaLaf.java

@ -1,3 +1,19 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula; package com.bulenkov.darcula;
import com.bulenkov.iconloader.util.ColorUtil; import com.bulenkov.iconloader.util.ColorUtil;
@ -37,6 +53,7 @@ public final class DarculaLaf extends BasicLookAndFeel {
} else { } else {
final String name = UIManager.getSystemLookAndFeelClassName(); final String name = UIManager.getSystemLookAndFeelClassName();
base = (BasicLookAndFeel)Class.forName(name).newInstance(); base = (BasicLookAndFeel)Class.forName(name).newInstance();
MetalLookAndFeel.setCurrentTheme(new DarculaMetalTheme());
} }
} }
catch (Exception ignore) { catch (Exception ignore) {

16
src/com/bulenkov/darcula/DarculaLookAndFeelInfo.java

@ -1,3 +1,19 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula; package com.bulenkov.darcula;
import javax.swing.*; import javax.swing.*;

98
src/com/bulenkov/darcula/DarculaMetalTheme.java

@ -0,0 +1,98 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.DefaultMetalTheme;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class DarculaMetalTheme extends DefaultMetalTheme {
private final ColorUIResource myControlHighlightColor = new ColorUIResource(108, 111, 113);
private final ColorUIResource myControlDarkShadowColor = new ColorUIResource(39, 42, 44);
private final ColorUIResource myControlColor = new ColorUIResource(0x3c3f41);
private static final ColorUIResource white = new ColorUIResource(255, 255, 255);
private static final ColorUIResource darkBlue = new ColorUIResource(82, 108, 164);
private static final ColorUIResource lightGray = new ColorUIResource(214, 214, 214);
private final ColorUIResource mySeparatorForeground = new ColorUIResource(53, 56, 58);
public static final ColorUIResource primary1 = new ColorUIResource(53, 56, 58);
private static final ColorUIResource primary2 = new ColorUIResource(91, 135, 206);
private static final ColorUIResource primary3 = new ColorUIResource(166, 202, 240);
public String getName() {
return "Darcula theme";
}
public ColorUIResource getControl() {
return myControlColor;
}
@Override
public ColorUIResource getControlHighlight() {
return myControlHighlightColor;
}
@Override
public ColorUIResource getControlDarkShadow() {
return myControlDarkShadowColor;
}
public ColorUIResource getSeparatorBackground() {
return getControl();
}
public ColorUIResource getSeparatorForeground() {
return mySeparatorForeground;
}
public ColorUIResource getMenuBackground() {
return lightGray;
}
public ColorUIResource getMenuSelectedBackground() {
return darkBlue;
}
public ColorUIResource getMenuSelectedForeground() {
return white;
}
public ColorUIResource getAcceleratorSelectedForeground() {
return white;
}
public ColorUIResource getFocusColor() {
return new ColorUIResource(Color.black);
}
protected ColorUIResource getPrimary1() {
return primary1;
}
protected ColorUIResource getPrimary2() {
return primary2;
}
protected ColorUIResource getPrimary3() {
return primary3;
}
}

16
src/com/bulenkov/darcula/DarculaTableHeaderBorder.java

@ -1,3 +1,19 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula; package com.bulenkov.darcula;
import javax.swing.border.Border; import javax.swing.border.Border;

2
src/com/bulenkov/darcula/DarculaTableHeaderUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2012 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/DarculaUIUtil.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/darcula.css

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

16
src/com/bulenkov/darcula/darcula.properties

@ -1,3 +1,19 @@
#
# Copyright 2000-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# suppress inspection "UnusedProperty" for whole file # suppress inspection "UnusedProperty" for whole file
darcula.background=3c3f41 darcula.background=3c3f41
darcula.textBackground=3c3f41 darcula.textBackground=3c3f41

16
src/com/bulenkov/darcula/darcula_linux.properties

@ -1,3 +1,19 @@
#
# Copyright 2000-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# suppress inspection "UnusedProperty" for whole file # suppress inspection "UnusedProperty" for whole file
darcula.selectionBackground=2F65CA darcula.selectionBackground=2F65CA
darcula.selectionForeground=bbbbbb darcula.selectionForeground=bbbbbb

16
src/com/bulenkov/darcula/darcula_mac.properties

@ -1,3 +1,19 @@
#
# Copyright 2000-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# suppress inspection "UnusedProperty" for whole file # suppress inspection "UnusedProperty" for whole file
darcula.selectionBackground=2F65CA darcula.selectionBackground=2F65CA
#Menu.arrowIcon=AllIcons.Mac.Tree_white_right_arrow #Menu.arrowIcon=AllIcons.Mac.Tree_white_right_arrow

28
src/com/bulenkov/darcula/darcula_windows.properties

@ -1,3 +1,19 @@
#
# Copyright 2000-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# suppress inspection "UnusedProperty" for whole file # suppress inspection "UnusedProperty" for whole file
darcula.selectionBackground=4B6EAF darcula.selectionBackground=4B6EAF
darcula.selectionForeground=bbbbbb darcula.selectionForeground=bbbbbb
@ -5,6 +21,12 @@ darcula.selectionForeground=bbbbbb
PopupMenu.border=com.bulenkov.darcula.ui.DarculaPopupMenuBorder PopupMenu.border=com.bulenkov.darcula.ui.DarculaPopupMenuBorder
MenuBar.border=com.bulenkov.darcula.ui.DarculaMenuBarBorder MenuBar.border=com.bulenkov.darcula.ui.DarculaMenuBarBorder
#InternalFrameUI=com.bulenkov.darcula.ui.DarculaInternalFrameUI
#InternalFrame.border=com.bulenkov.darcula.ui.DarculaInternalBorder ToolBar.floatingBackground=3c3f41
#RootPaneUI=com.bulenkov.darcula.ui.DarculaRootPaneUI ToolBar.floatingForeground=bbbbbb
ToolBar.borderColor=555555
ToolBar.shadow=555555
menu=3c3f41
MenuBar.gradient=null
MenuBar.borderColor=555555
MenuBar.highlight=555555

2
src/com/bulenkov/darcula/ui/DarculaButtonPainter.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaButtonUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaCheckBoxBorder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2012 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaCheckBoxUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaComboBoxUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaEditorPaneUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2012 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaInternalBorder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaInternalFrameUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaMenuBarBorder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

16
src/com/bulenkov/darcula/ui/DarculaMenuBarUI.java

@ -1,3 +1,19 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula.ui; package com.bulenkov.darcula.ui;
import javax.swing.*; import javax.swing.*;

16
src/com/bulenkov/darcula/ui/DarculaMenuItemBorder.java

@ -1,3 +1,19 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula.ui; package com.bulenkov.darcula.ui;
import javax.swing.plaf.BorderUIResource; import javax.swing.plaf.BorderUIResource;

2
src/com/bulenkov/darcula/ui/DarculaPanelUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2012 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaPasswordFieldUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2012 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaPopupMenuBorder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2012 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaProgressBarBorder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaProgressBarUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaRadioButtonUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaRootPaneUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaScrollBarUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2012 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaSpinnerBorder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaSpinnerUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaTabbedPaneUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2012 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaTextBorder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaTextFieldUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

2
src/com/bulenkov/darcula/ui/DarculaTitlePane.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

16
src/com/bulenkov/darcula/ui/DarculaToolBarUI.java

@ -1,3 +1,19 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula.ui; package com.bulenkov.darcula.ui;
import javax.swing.*; import javax.swing.*;

2
src/com/bulenkov/darcula/ui/DarculaTreeUI.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2000-2013 JetBrains s.r.o. * Copyright 2000-2014 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

16
src/com/bulenkov/darcula/ui/win/DarculaWindowsInternalFrameUI.java

@ -1,3 +1,19 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula.ui.win; package com.bulenkov.darcula.ui.win;
import javax.swing.*; import javax.swing.*;

16
src/com/bulenkov/darcula/util/Animator.java

@ -1,3 +1,19 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula.util; package com.bulenkov.darcula.util;
import javax.swing.*; import javax.swing.*;

16
src/com/bulenkov/darcula/util/DarculaColors.java

@ -1,3 +1,19 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.bulenkov.darcula.util; package com.bulenkov.darcula.util;
import java.awt.*; import java.awt.*;

30
swingset2/SwingSet2.java

@ -46,10 +46,7 @@ import javax.swing.plaf.metal.MetalLookAndFeel;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Iterator; import java.util.*;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Vector;
/** /**
* A demo that shows all of the Swing components. * A demo that shows all of the Swing components.
@ -723,7 +720,30 @@ public class SwingSet2 extends JPanel {
f.show(); f.show();
numSSs++; numSSs++;
swingSets.add(this); swingSets.add(this);
}
final UIDefaults defaults = UIManager.getDefaults();
Enumeration keys = defaults.keys();
final Object[][] data = new Object[defaults.size()][2];
int i = 0;
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
data[i][0] = key;
data[i][1] = defaults.get(key);
i++;
}
Arrays.sort(data, new Comparator<Object[]>() {
@Override
public int compare(Object[] o1, Object[] o2) {
return o1[0 ].toString().compareTo(o2[0].toString());
}
});
for (int j = 0; j < data.length; j++) {
Object[] objects = data[j];
System.out.println(objects[0] + ": " + objects[1]);
}
}
} }
/** /**

22
swingset3/META-INF/demolist

@ -0,0 +1,22 @@
com.sun.swingset3.demos.frame.FrameDemo
com.sun.swingset3.demos.dialog.DialogDemo
com.sun.swingset3.demos.window.WindowDemo
com.sun.swingset3.demos.internalframe.InternalFrameDemo
com.sun.swingset3.demos.tabbedpane.TabbedPaneDemo
com.sun.swingset3.demos.scrollpane.ScrollPaneDemo
com.sun.swingset3.demos.splitpane.SplitPaneDemo
com.sun.swingset3.demos.gridbaglayout.GridBagLayoutDemo
com.sun.swingset3.demos.table.TableDemo
com.sun.swingset3.demos.tree.TreeDemo
com.sun.swingset3.demos.list.ListDemo
com.sun.swingset3.demos.togglebutton.ToggleButtonDemo
com.sun.swingset3.demos.button.ButtonDemo
com.sun.swingset3.demos.combobox.ComboBoxDemo
com.sun.swingset3.demos.progressbar.ProgressBarDemo
com.sun.swingset3.demos.slider.SliderDemo
com.sun.swingset3.demos.spinner.SpinnerDemo
com.sun.swingset3.demos.textfield.TextFieldDemo
com.sun.swingset3.demos.editorpane.EditorPaneDemo
com.sun.swingset3.demos.colorchooser.ColorChooserDemo
com.sun.swingset3.demos.optionpane.OptionPaneDemo
com.sun.swingset3.demos.tooltip.ToolTipDemo

0
swingset3/META-INF/services/javax.swing.LookAndFeel

57
swingset3/com/sun/swingset3/AboutBox.java

@ -0,0 +1,57 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
/**
*
* @author Amy Fowler
*/
public class AboutBox extends JPanel {
private BufferedImage bgImage;
public AboutBox() {
try {
bgImage = ImageIO.read(AboutBox.class.getResource("resources/images/about.jpg"));
} catch (Exception ex) {
}
}
}

350
swingset3/com/sun/swingset3/Demo.java

@ -0,0 +1,350 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3;
import java.awt.Component;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;
import java.util.logging.Level;
import javax.swing.Icon;
import javax.swing.ImageIcon;
/**
* Wrapper class which encapsulates a GUI component to be displayed
* as a SwingSet3 demo.
* @author Amy Fowler
*/
public class Demo {
public enum State { UNINITIALIZED, INITIALIZING, INITIALIZED, RUNNING, STOPPED, FAILED }
private static final String IMAGE_EXTENSIONS[] = {".gif", ".png", ".jpg"};
public static String deriveCategoryFromPackageName(String className) {
String parts[] = className.split("\\.");
// return the right-most package name
return parts.length >= 2? parts[parts.length-2] : "general";
}
public static String deriveCategoryFromPackageName(Class demoClass) {
String packageName = demoClass.getPackage() != null?
demoClass.getPackage().getName() : null;
if (packageName != null) {
// if root package is swingset3, then remove it
String swingsetPackageName = Demo.class.getPackage().getName();
if (packageName.startsWith(swingsetPackageName + ".demos.")) {
packageName = packageName.replaceFirst(swingsetPackageName + ".demos.",
"");
}
}
return packageName != null? packageName : "general";
}
public static String deriveNameFromClassName(String className) {
String simpleName = className.substring(className.lastIndexOf(".")+1, className.length());
return convertToDemoName(simpleName);
}
public static String deriveNameFromClassName(Class demoClass) {
String className = demoClass.getSimpleName();
return convertToDemoName(className);
}
private static String convertToDemoName(String simpleClassName) {
StringBuffer nameBuffer = new StringBuffer();
if (simpleClassName.endsWith("Demo")) {
nameBuffer.append(simpleClassName.substring(0, simpleClassName.indexOf("Demo")));
nameBuffer.append(" ");
nameBuffer.append("Demo");
}
return nameBuffer.toString();
}
private Class<?> demoClass;
private String name;
private String category;
private String shortDescription; // used for tooltips
private String iconPath;
private Icon icon;
private String[] sourceFilePaths;
private URL[] sourceFiles;
private Component component;
private State state;
private Exception failException;
private PropertyChangeSupport pcs;
public Demo(Class<?> demoClass) {
this.demoClass = demoClass;
initializeProperties();
}
protected void initializeProperties() {
// First look for DemoProperties annotation if it exists
DemoProperties properties = demoClass.getAnnotation(DemoProperties.class);
if (properties != null) {
this.name = properties.value();
this.category = properties.category();
this.shortDescription = properties.description();
this.iconPath = properties.iconFile();
this.sourceFilePaths = properties.sourceFiles();
} else {
this.name = deriveNameFromClassName(demoClass);
this.category = deriveCategoryFromPackageName(demoClass);
this.shortDescription = "No demo description, run it to find out...";
}
state = State.UNINITIALIZED;
pcs = new PropertyChangeSupport(this);
}
public Class getDemoClass() {
return demoClass;
}
public String getName() {
return name;
}
public String getCategory() {
return category;
}
public Icon getIcon() {
if (icon == null) {
if (iconPath != null && !iconPath.equals("")) {
// icon packageName was specified in DemoProperties annotation
icon = getIconFromPath(iconPath);
} else {
// Look for icon with same name as demo class
for(String ext : IMAGE_EXTENSIONS) {
icon = getIconFromPath(getIconImagePath(ext));
if (icon != null) {
break;
}
}
}
}
return icon;
}
protected String getIconImagePath(String extension) {
// by default look for an image with the same name as the demo class
return "resources/images/" +
demoClass.getSimpleName() + extension;
}
private Icon getIconFromPath(String path) {
Icon icon = null;
URL imageURL = demoClass.getResource(path);
if (imageURL != null) {
icon = new ImageIcon(imageURL);
}
return icon;
}
public String getShortDescription() {
return shortDescription;
}
public URL getHTMLDescription() {
// by default look for an html file with the same name as the demo class
return demoClass.getResource("resources/" +
demoClass.getSimpleName() + ".html");
}
public URL[] getSourceFiles() {
// If not already cached, then look them up
if (sourceFiles == null) {
ArrayList<URL> pathURLs = new ArrayList<URL>();
// Get any names registered in DemoProperties meta-data.
// If meta-data is not specified then sourceFilePaths contains
// one empty string. In this case we skip it.
if (!(sourceFilePaths.length == 1 && sourceFilePaths[0].length() == 0)) {
for (String path : sourceFilePaths) {
URL url = getClass().getClassLoader().getResource(path);
if (url == null) {
SwingSet3.logger.log(Level.WARNING,
"unable to load source file '" + path + "'");
} else {
pathURLs.add(url);
}
}
}
this.sourceFiles = pathURLs.toArray(new URL[pathURLs.size()]);
}
return sourceFiles;
}
void startInitializing() {
setState(Demo.State.INITIALIZING);
}
void setDemoComponent(Component component) {
if (component != null && !demoClass.isInstance(component)) {
setState(State.FAILED);
IllegalArgumentException e =
new IllegalArgumentException("component must be an instance of " +
demoClass.getCanonicalName());
failException = e;
throw e;
}
Component old = this.component;
this.component = component;
if (component != null) {
init();
} else {
setState(State.UNINITIALIZED);
}
pcs.firePropertyChange("demoComponent", old, component);
}
public Component createDemoComponent() {
Component component = null;
try {
component = (Component)demoClass.newInstance();
setDemoComponent(component);
} catch (Exception e) {
System.err.println(e);
e.printStackTrace();
failException = e;
setState(State.FAILED);
}
return component;
}
public Component getDemoComponent() {
return component;
}
public State getState() {
return state;
}
protected void setState(State state) {
State oldState = this.state;
this.state = state;
SwingSet3.logger.log(Level.FINE, "***>" +getName() + ":setState="+state);
pcs.firePropertyChange("state", oldState, state);
}
public void addPropertyChangeListener(PropertyChangeListener pcl) {
pcs.addPropertyChangeListener(pcl);
}
public void removePropertyChangeListener(PropertyChangeListener pcl) {
pcs.removePropertyChangeListener(pcl);
}
private void init() {
setState(State.INITIALIZED);
try {
Method initMethod = demoClass.getMethod("init", (Class[])null);
initMethod.invoke(component, (Object[])null);
} catch (NoSuchMethodException nsme) {
// okay, no init method exists
} catch (IllegalAccessException iae) {
SwingSet3.logger.log(Level.SEVERE, "unable to init demo: "+demoClass.getName(), iae);
failException = iae;
setState(State.FAILED);
} catch (java.lang.reflect.InvocationTargetException ite) {
SwingSet3.logger.log(Level.SEVERE, "init method failed for demo: "+demoClass.getName(), ite);
failException = ite;
setState(State.FAILED);
} catch (NullPointerException npe) {
SwingSet3.logger.log(Level.SEVERE, "init method called before demo was instantiated: "
+demoClass.getName(), npe);
failException = npe;
setState(State.FAILED);
}
}
public void start() {
try {
Method startMethod = demoClass.getMethod("start", (Class[])null);
startMethod.invoke(component, (Object[])null);
setState(State.RUNNING);
} catch (NoSuchMethodException nsme) {
setState(State.RUNNING);
// okay, no start method exists
} catch (IllegalAccessException iae) {
SwingSet3.logger.log(Level.SEVERE, "unable to start demo: "+demoClass.getName(), iae);
failException = iae;
setState(State.FAILED);
} catch (java.lang.reflect.InvocationTargetException ite) {
SwingSet3.logger.log(Level.SEVERE, "start method failed for demo: "+demoClass.getName(), ite);
failException = ite;
setState(State.FAILED);
} catch (NullPointerException npe) {
SwingSet3.logger.log(Level.SEVERE, "start method called before demo was instantiated: "
+demoClass.getName(), npe);
failException = npe;
setState(State.FAILED);
}
}
public void stop() {
setState(State.STOPPED);
try {
Method stopMethod = demoClass.getMethod("stop", (Class[])null);
stopMethod.invoke(component, (Object[])null);
} catch (NoSuchMethodException nsme) {
// okay, no stop method exists
} catch (IllegalAccessException iae) {
SwingSet3.logger.log(Level.SEVERE, "unable to stop demo: "+demoClass.getName(), iae);
failException = iae;
setState(State.FAILED);
} catch (java.lang.reflect.InvocationTargetException ite) {
SwingSet3.logger.log(Level.SEVERE, "stop method failed for demo: "+demoClass.getName(), ite);
failException = ite;
setState(State.FAILED);
} catch (NullPointerException npe) {
SwingSet3.logger.log(Level.SEVERE, "stop method called before demo was instantiated: "
+demoClass.getName(), npe);
}
}
}

291
swingset3/com/sun/swingset3/DemoPanel.java

@ -0,0 +1,291 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3;
import com.sun.swingset3.utilities.HTMLPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.net.URL;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.UIManager;
import javax.swing.border.Border;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.timing.interpolation.PropertySetter;
import org.jdesktop.animation.timing.triggers.TimingTrigger;
import org.jdesktop.animation.timing.triggers.TimingTriggerEvent;
import org.jdesktop.swingx.JXPanel;
import com.sun.swingset3.utilities.RoundedBorder;
import com.sun.swingset3.utilities.RoundedPanel;
import com.sun.swingset3.utilities.RoundedTitleBorder;
import com.sun.swingset3.utilities.Utilities;
/**
*
* @author aim
*/
public class DemoPanel extends JXPanel {
private static final Border roundedBorder = new RoundedBorder(10);
private static final Insets margin = new Insets(8, 10, 8, 8);
private Demo demo;
public DemoPanel(Demo demo) {
this.demo = demo;
setLayout(new BorderLayout());
// remind(aim): how to access resourceMap?
//resourceMap = getContext().getResourceMap();
LoadAnimationPanel loadAnimationPanel = new LoadAnimationPanel();
add(loadAnimationPanel);
loadAnimationPanel.setAnimating(true);
LoadedDemoPanel demoPanel = new LoadedDemoPanel(demo);
try {
loadAnimationPanel.setAnimating(false);
Animator fadeOutAnimator = new Animator(400,
new FadeOut(DemoPanel.this,
loadAnimationPanel, demoPanel));
fadeOutAnimator.setAcceleration(.2f);
fadeOutAnimator.setDeceleration(.3f);
Animator fadeInAnimator = new Animator(400,
new PropertySetter(DemoPanel.this, "alpha", 0.3f, 1.0f));
TimingTrigger.addTrigger(fadeOutAnimator, fadeInAnimator, TimingTriggerEvent.STOP);
fadeOutAnimator.start();
} catch (Exception ignore) {
System.err.println(ignore);
ignore.printStackTrace();
}
}
public Demo getDemo() {
return demo;
}
private static class FadeOut extends PropertySetter {
private JXPanel parent;
private JXPanel out;
private JComponent in;
public FadeOut(JXPanel parent, JXPanel out, JComponent in) {
super(out, "alpha", 1.0f, 0.3f);
this.parent = parent;
this.out = out;
this.in = in;
}
public void end() {
parent.setAlpha(0.3f);
parent.remove(out);
parent.add(in);
parent.revalidate();
}
} // Fader
private static class LoadAnimationPanel extends RoundedPanel {
private String message;
private int triState = 0;
private boolean animating = false;
private Animator animator;
public LoadAnimationPanel() {
super(10);
setBorder(roundedBorder);
setBackground(Utilities.deriveColorHSB(
UIManager.getColor("Panel.background"), 0, 0, -.06f));
// remind(aim): get from resource map
message = "demo loading";
PropertySetter rotator = new PropertySetter(this, "triState", 0, 3);
animator = new Animator(500, Animator.INFINITE,
Animator.RepeatBehavior.LOOP, rotator);
// Don't animate gears if loading is quick
animator.setStartDelay(200);
}
public void setAnimating(boolean animating) {
this.animating = animating;
if (animating) {
animator.start();
} else {
animator.stop();
}
}
public boolean isAnimating() {
return animating;
}
public void setTriState(int triState) {
this.triState = triState;
repaint();
}
public int getTriState() {
return triState;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
Dimension size = getSize();
Color textColor = Utilities.deriveColorHSB(getBackground(), 0, 0, -.3f);
Color dotColor = Utilities.deriveColorHSB(textColor, 0, .2f, -.08f);
g2.setColor(textColor);
g2.setFont(UIManager.getFont("Label.font").deriveFont(32f));
FontMetrics metrics = g2.getFontMetrics();
Rectangle2D rect = metrics.getStringBounds(message, g2);
Rectangle2D dotRect = metrics.getStringBounds(".", g2);
float x = (float) (size.width - (rect.getWidth() + 3 * dotRect.getWidth())) / 2;
float y = (float) (size.height - rect.getHeight()) / 2;
g2.drawString(message, x, y);
int tri = getTriState();
float dx = 0;
for (int i = 0; i < 3; i++) {
g2.setColor(animator.isRunning() && i == tri ?
dotColor :
textColor);
g2.drawString(".", x + (float) (rect.getWidth() + dx), y);
dx += dotRect.getWidth();
}
}
} // LoadAnimationPanel
private static class LoadedDemoPanel extends RoundedPanel {
private String demoName;
private JComponent descriptionArea;
private JComponent demoPanel;
public LoadedDemoPanel(Demo demo) {
super(10);
setLayout(null);
demoName = demo.getName();
URL description = demo.getHTMLDescription();
if (description != null) {
descriptionArea = createDescriptionArea(description);
add(descriptionArea);
demoPanel = new RoundedPanel(new BorderLayout());
demoPanel.setBorder(roundedBorder);
} else {
// no description
demoPanel = new JXPanel(new BorderLayout());
}
demoPanel.add(demo.createDemoComponent());
add(demoPanel);
applyDefaults();
}
private static JComponent createDescriptionArea(URL descriptionURL) {
JEditorPane descriptionPane = new HTMLPanel();
descriptionPane.setEditable(false);
descriptionPane.setMargin(margin);
descriptionPane.setOpaque(true);
try {
descriptionPane.setPage(descriptionURL);
} catch (IOException e) {
System.err.println("couldn't load description from URL:" + descriptionURL);
}
return descriptionPane;
}
@Override
public void doLayout() {
if (demoPanel != null) {
Dimension size = getSize();
Insets insets = getInsets();
if (descriptionArea == null) {
// Make demo fill entire area within border
demoPanel.setBounds(insets.left, insets.top,
size.width - insets.left - insets.right,
size.height - insets.top - insets.bottom);
} else {
// Split space between HTML description and running demo
Dimension demoSize = demoPanel.getPreferredSize();
int margin = insets.top / 2;
Rectangle bounds = new Rectangle();
bounds.width = Math.max(demoSize.width, (int) (size.width * .50));
bounds.height = Math.max(demoSize.height, size.height -
2 * margin);
bounds.x = size.width - bounds.width - margin;
bounds.y = margin;
demoPanel.setBounds(bounds);
descriptionArea.setBounds(insets.left, insets.top,
size.width - margin - insets.right - bounds.width,
size.height - insets.top - insets.bottom);
}
}
}
@Override
public void updateUI() {
super.updateUI();
applyDefaults();
}
private void applyDefaults() {
setBorder(new RoundedTitleBorder(demoName,
UIManager.getColor(SwingSet3.TITLE_GRADIENT_COLOR1_KEY),
UIManager.getColor(SwingSet3.TITLE_GRADIENT_COLOR2_KEY)));
setFont(UIManager.getFont(SwingSet3.TITLE_FONT_KEY));
Color bg = Utilities.deriveColorHSB(
UIManager.getColor("Panel.background"), 0, 0, -.06f);
setBackground(bg);
setForeground(UIManager.getColor(SwingSet3.TITLE_FOREGROUND_KEY));
if (demoPanel != null) {
demoPanel.setBackground(Utilities.deriveColorHSB(bg, 0, 0, .04f));
}
if (descriptionArea != null) {
descriptionArea.setBackground(bg);
}
}
}
}

48
swingset3/com/sun/swingset3/DemoProperties.java

@ -0,0 +1,48 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Annotation type for specifying meta-data about Demo
* @author aim
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface DemoProperties {
String value(); // Name
String category();
String description();
String iconFile() default "";
String[] sourceFiles() default "";
}

370
swingset3/com/sun/swingset3/DemoSelectorPanel.java

@ -0,0 +1,370 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3;
import com.sun.swingset3.utilities.GradientPanel;
import com.sun.swingset3.utilities.CollapsiblePanel;
import com.sun.swingset3.utilities.ArrowIcon;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.MatteBorder;
import com.sun.swingset3.utilities.Utilities;
/**
*
* @author Administrator
*/
public class DemoSelectorPanel extends JPanel {
private static final Border chiselBorder = new ChiselBorder();
private static final Border panelBorder = new CompoundBorder(
chiselBorder, new EmptyBorder(6,8,6,0));
private static final Border categoryBorder = new CompoundBorder(
chiselBorder, new EmptyBorder(0,0,10,0));
private static final Border buttonBorder = new CompoundBorder(
new DemoButtonBorder(), new EmptyBorder(0, 18, 0, 0));
private GradientPanel titlePanel;
private JLabel demoListLabel;
private JPanel viewPanel;
private JScrollPane scrollPane;
// need to track components that have defaults customizations
private final List<CollapsiblePanel> collapsePanels = new ArrayList<CollapsiblePanel>();
private Icon expandedIcon;
private Icon collapsedIcon;
private Color visitedForeground;
private Color failedForeground;
private ButtonGroup group;
private final ActionListener demoActionListener = new DemoActionListener();
private int buttonHeight = 0;
private Demo selectedDemo;
public DemoSelectorPanel(String demoSetTitle, List<Demo> demoSet) {
super(new BorderLayout());
visitedForeground = new Color(100, 100, 150);
failedForeground = new Color(245, 20, 80);
// only one demo may be selected at a time
group = new ButtonGroup();
// create demo set title area at top
add(createTitleArea(demoSetTitle), BorderLayout.NORTH);
// create scrollable demo panel at bottom
JComponent selector = createDemoSelector(demoSet);
scrollPane = new JScrollPane(selector);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
add(scrollPane, BorderLayout.CENTER);
applyDefaults();
}
protected JComponent createTitleArea(String demoSetTitle) {
JPanel titleAreaPanel = new JPanel(new BorderLayout());
titlePanel = new GradientPanel(
UIManager.getColor(SwingSet3.TITLE_GRADIENT_COLOR1_KEY),
UIManager.getColor(SwingSet3.TITLE_GRADIENT_COLOR2_KEY));
titlePanel.setLayout(new BorderLayout());
titlePanel.setBorder(panelBorder);
demoListLabel = new JLabel(demoSetTitle);
demoListLabel.setOpaque(false);
demoListLabel.setHorizontalAlignment(JLabel.LEADING);
titlePanel.add(demoListLabel, BorderLayout.CENTER);
titleAreaPanel.add(titlePanel, BorderLayout.NORTH);
// Add panel with view combobox
viewPanel = new JPanel();
viewPanel.setLayout(new BoxLayout(viewPanel, BoxLayout.X_AXIS));
viewPanel.setBorder(new CompoundBorder(chiselBorder,
new EmptyBorder(12,8,12,8)));
JLabel viewLabel = new JLabel("View:");
viewPanel.add(viewLabel);
viewPanel.add(Box.createHorizontalStrut(6));
JComboBox viewComboBox = new JComboBox();
viewComboBox.addItem("by category");
viewPanel.add(viewComboBox);
titleAreaPanel.add(viewPanel, BorderLayout.CENTER);
return titleAreaPanel;
}
protected JComponent createDemoSelector(List<Demo> demoSet) {
JPanel selectorPanel = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
selectorPanel.setLayout(gridbag);
GridBagConstraints c = new GridBagConstraints();
c.gridx = c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
HashMap<String,JPanel> categoryMap = new HashMap<String,JPanel>();
GridBagLayout categoryGridbag = null;
GridBagConstraints cc = new GridBagConstraints();
cc.gridx = cc.gridy = 0;
cc.weightx = 1;
cc.fill = GridBagConstraints.HORIZONTAL;
CollapsiblePanel collapsePanel;
for(Demo demo: demoSet) {
String category = demo.getCategory();
JPanel categoryPanel = categoryMap.get(category);
if (categoryPanel == null) {
// Create category collapsible panel
categoryPanel = new JPanel();
categoryGridbag = new GridBagLayout();
categoryPanel.setLayout(categoryGridbag);
collapsePanel = new CollapsiblePanel(categoryPanel, category,
"click to expand or contract category");
collapsePanels.add(collapsePanel);
collapsePanel.setBorder(categoryBorder);
categoryMap.put(category, categoryPanel);
gridbag.addLayoutComponent(collapsePanel, c);
selectorPanel.add(collapsePanel);
c.gridy++;
}
DemoButton demoButton = new DemoButton(demo);
categoryGridbag.addLayoutComponent(demoButton, cc);
cc.gridy++;
group.add(demoButton);
categoryPanel.add(demoButton);
if (buttonHeight == 0) {
buttonHeight = demoButton.getPreferredSize().height;
}
}
// add empty component to take up any extra room on bottom
JPanel trailer = new JPanel();
c.weighty = 1.0;
gridbag.addLayoutComponent(trailer, c);
selectorPanel.add(trailer);
applyDefaults();
return selectorPanel;
}
public void updateUI() {
super.updateUI();
applyDefaults();
}
protected void applyDefaults() {
expandedIcon = new ArrowIcon(ArrowIcon.SOUTH,
UIManager.getColor(SwingSet3.TITLE_FOREGROUND_KEY));
collapsedIcon = new ArrowIcon(ArrowIcon.EAST,
UIManager.getColor(SwingSet3.TITLE_FOREGROUND_KEY));
setBorder(new MatteBorder(0,0,0,1,
UIManager.getColor(SwingSet3.CONTROL_MID_SHADOW_KEY)));
if (titlePanel != null) {
titlePanel.setGradientColor1(
UIManager.getColor(SwingSet3.TITLE_GRADIENT_COLOR1_KEY));
titlePanel.setGradientColor2(
UIManager.getColor(SwingSet3.TITLE_GRADIENT_COLOR2_KEY));
}
if (demoListLabel != null) {
demoListLabel.setForeground(UIManager.getColor(SwingSet3.TITLE_FOREGROUND_KEY));
demoListLabel.setFont(UIManager.getFont(SwingSet3.TITLE_FONT_KEY));
}
if (viewPanel != null) {
viewPanel.setBackground(UIManager.getColor(SwingSet3.SUB_PANEL_BACKGROUND_KEY));
}
if (collapsePanels != null) {
for (CollapsiblePanel collapsePanel : collapsePanels) {
collapsePanel.setFont(
UIManager.getFont("CheckBox.font").deriveFont(Font.BOLD));
collapsePanel.setForeground(UIManager.getColor(SwingSet3.TITLE_FOREGROUND_KEY));
collapsePanel.setExpandedIcon(expandedIcon);
collapsePanel.setCollapsedIcon(collapsedIcon);
}
}
revalidate();
}
public Demo getSelectedDemo() {
return selectedDemo;
}
protected void setSelectedDemo(Demo demo) {
Demo oldSelectedDemo = selectedDemo;
selectedDemo = demo;
firePropertyChange("selectedDemo", oldSelectedDemo, demo);
}
private class DemoButton extends JToggleButton {
private Demo demo;
public DemoButton(Demo demo) {
super();
this.demo = demo;
String demoName = demo.getName();
if (demoName.endsWith("Demo")) {
setText(demoName.substring(0, demoName.indexOf("Demo")));
} else {
setText(demoName);
}
setIcon(demo.getIcon());
setIconTextGap(10);
setHorizontalTextPosition(JToggleButton.TRAILING);
setHorizontalAlignment(JToggleButton.LEADING);
setOpaque(false);
setBorder(buttonBorder);
setFocusPainted(false);
setContentAreaFilled(false);
setToolTipText(demo.getShortDescription());
addActionListener(demoActionListener);
}
@Override
public void updateUI() {
super.updateUI();
// some look and feels replace our border, so take it back
setBorder(buttonBorder);
}
@Override
protected void paintComponent(Graphics g) {
if (isSelected()) {
setBackground(UIManager.getColor("Tree.selectionBackground"));
g.setColor(UIManager.getColor("Tree.selectionBackground"));
Dimension size = getSize();
g.fillRect(0, 0, size.width, size.height);
setForeground(UIManager.getColor("Tree.selectionForeground"));
} else {
setBackground(UIManager.getColor("ToggleButton.background"));
Color foreground = UIManager.getColor("ToggleButton.foreground");
switch(demo.getState()) {
case STOPPED: {
foreground = visitedForeground;
break;
}
case FAILED: {
foreground = failedForeground;
}
}
setForeground(foreground);
}
super.paintComponent(g);
}
public Demo getDemo() {
return demo;
}
}
private class DemoActionListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
DemoButton demoButton = (DemoButton)event.getSource();
setSelectedDemo(demoButton.getDemo());
}
}
private static class DemoButtonBorder implements Border {
private Insets insets = new Insets(2, 1, 1, 1);
public DemoButtonBorder() {
}
public Insets getBorderInsets(Component c) {
return insets;
}
public boolean isBorderOpaque() {
return true;
}
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
AbstractButton b = (AbstractButton)c;
if (b.isSelected()) {
Color color = c.getBackground();
g.setColor(Utilities.deriveColorHSB(color, 0, 0, -.20f));
g.drawLine(x, y, x + width, y);
g.setColor(Utilities.deriveColorHSB(color, 0, 0, -.10f));
g.drawLine(x, y + 1, x + width, y + 1);
g.drawLine(x, y + 2, x, y + height - 2);
g.setColor(Utilities.deriveColorHSB(color, 0, 0, .24f));
g.drawLine(x, y + height - 1, x + width, y + height-1);
}
}
}
private static class ChiselBorder implements Border {
private Insets insets = new Insets(1, 0, 1, 0);
public ChiselBorder() {
}
public Insets getBorderInsets(Component c) {
return insets;
}
public boolean isBorderOpaque() {
return true;
}
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Color color = c.getBackground();
// render highlight at top
g.setColor(Utilities.deriveColorHSB(color, 0, 0, .2f));
g.drawLine(x, y, x + width, y);
// render shadow on bottom
g.setColor(Utilities.deriveColorHSB(color, 0, 0, -.2f));
g.drawLine(x, y + height - 1, x + width, y + height - 1);
}
}
}

131
swingset3/com/sun/swingset3/IntroPanel.java

@ -0,0 +1,131 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3;
import com.sun.swingset3.utilities.RoundedPanel;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.timing.interpolation.PropertySetter;
/**
*
* @author Amy Fowler
*/
public class IntroPanel extends RoundedPanel {
private JLabel introImage;
private SlidingLabel introText;
public IntroPanel() {
setLayout(null);
setOpaque(false);
introImage = new JLabel(new ImageIcon(
SwingSet3.class.getResource("resources/images/home_notext.png")));
introImage.setVerticalAlignment(JLabel.TOP);
introText = new SlidingLabel(new ImageIcon(
SwingSet3.class.getResource("resources/images/home_text.png")));
introText.setVisible(false);
introImage.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent event) {
slideTextIn();
}
});
add(introText);
add(introImage);
}
@Override
public void doLayout() {
Dimension size = getSize();
Insets insets = getInsets();
int w = size.width - insets.left - insets.right;
Dimension prefSize = introImage.getPreferredSize();
introImage.setBounds(0, 0, prefSize.width, prefSize.height);
if (introText.isVisible()) {
prefSize = introText.getPreferredSize();
introText.setBounds(introText.getX(), introText.getY(),
prefSize.width, prefSize.height);
}
}
@Override
public void paint(Graphics g) {
super.paint(g);
if (!introText.isVisible()) {
introText.setLocation(1000, 110);
introText.setVisible(true);
slideTextIn();
}
}
public void slideTextIn() {
Animator animator = new Animator(800,
new PropertySetter(introText, "x", getWidth(), 30));
animator.setStartDelay(800);
animator.setAcceleration(.2f);
animator.setDeceleration(.5f);
animator.start();
}
public void slideTextOut() {
Animator animator = new Animator(600,
new PropertySetter(introText, "x", introText.getX(), -introText.getWidth()));
animator.setStartDelay(10);
animator.setAcceleration(.5f);
animator.setDeceleration(.2f);
animator.start();
}
public class SlidingLabel extends JLabel {
public SlidingLabel(Icon icon) {
super(icon);
}
public void setX(int x) {
setLocation(x, getY());
revalidate();
}
}
}

707
swingset3/com/sun/swingset3/SwingSet3.java

@ -0,0 +1,707 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3;
import com.sun.swingset3.codeview.CodeViewer;
import com.sun.swingset3.utilities.AnimatingSplitPane;
import com.sun.swingset3.utilities.RoundedBorder;
import com.sun.swingset3.utilities.RoundedPanel;
import com.sun.swingset3.utilities.Utilities;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.View;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;
import java.util.*;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Amy Fowler
*/
public class SwingSet3 extends SingleFrameApplication {
static final Logger logger = Logger.getLogger(SwingSet3.class.getName());
private static final ServiceLoader<LookAndFeel> LOOK_AND_FEEL_LOADER = ServiceLoader.load(LookAndFeel.class);
public static String title;
public static final String CONTROL_VERY_LIGHT_SHADOW_KEY = "controlVeryLightShadowColor";
public static final String CONTROL_LIGHT_SHADOW_KEY = "controlLightShadowColor";
public static final String CONTROL_MID_SHADOW_KEY = "controlMidShadowColor";
public static final String CONTROL_VERY_DARK_SHADOW_KEY = "controlVeryDarkShadowColor";
public static final String CONTROL_DARK_SHADOW_KEY = "controlDarkShadowColor";
public static final String TITLE_GRADIENT_COLOR1_KEY = "titleGradientColor1";
public static final String TITLE_GRADIENT_COLOR2_KEY = "titleGradientColor2";
public static final String TITLE_FOREGROUND_KEY = "titleForegroundColor";
public static final String CODE_HIGHLIGHT_KEY = "codeHighlightColor";
public static final String TITLE_FONT_KEY = "titleFont";
public static final String SUB_PANEL_BACKGROUND_KEY = "subPanelBackgroundColor";
public static final int MAIN_FRAME_WIDTH = 880;
public static final int MAIN_FRAME_HEIGHT = 640;
public static final int DEMO_SELECTOR_WIDTH = 186;
public static final int DEMO_PANEL_HEIGHT = 400;
public static final int DEMO_PANEL_WIDTH = MAIN_FRAME_WIDTH - DEMO_SELECTOR_WIDTH;
private static final Border EMPTY_BORDER = new EmptyBorder(0, 0, 0, 0);
private static final Border PANEL_BORDER = new EmptyBorder(10, 10, 10, 10);
private static final String DEMO_LIST_FILE = "/META-INF/demolist";
static {
// Property must be set *early* due to Apple Bug#3909714
if (System.getProperty("os.name").equals("Mac OS X")) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
}
// temporary workaround for problem with Nimbus classname
UIManager.LookAndFeelInfo lafInfo[] = UIManager.getInstalledLookAndFeels();
for(int i = 0; i < lafInfo.length; i++) {
if (lafInfo[i].getName().equals("Nimbus")) {
lafInfo[i] = new UIManager.LookAndFeelInfo("Nimbus",
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
break;
}
}
UIManager.setInstalledLookAndFeels(lafInfo);
UIManager.put("swing.boldMetal", Boolean.FALSE);
}
public static void main(String[] args) {
launch(SwingSet3.class, args);
}
public static boolean runningOnMac() {
return System.getProperty("os.name").equals("Mac OS X");
}
public static boolean usingNimbus() {
return UIManager.getLookAndFeel().getName().equals("Nimbus");
}
private static List<String> readDemoClassNames(Reader reader) throws IOException {
List<String> demoClassNames = new ArrayList<String>();
BufferedReader breader = new BufferedReader(reader);
String line;
while((line = breader.readLine()) != null) {
demoClassNames.add(line);
}
breader.close();
return demoClassNames;
}
// End of statics
private ResourceMap resourceMap;
// Application models
private String demoListTitle;
private List<Demo> demoList;
private PropertyChangeListener demoPropertyChangeListener;
private Map<String, DemoPanel> runningDemoCache;
private Demo currentDemo;
// GUI components
private JPanel mainPanel;
private DemoSelectorPanel demoSelectorPanel;
private AnimatingSplitPane demoSplitPane;
private JPanel demoContainer;
private JComponent currentDemoPanel;
private JComponent demoPlaceholder;
private JPanel codeContainer;
private CodeViewer codeViewer;
private JCheckBoxMenuItem sourceCodeCheckboxItem;
private ButtonGroup lookAndFeelRadioGroup;
private JPopupMenu popup;
// Properties
private String lookAndFeel;
private boolean sourceVisible = true;
@Override
protected void initialize(String args[]) {
try {
UIManager.setLookAndFeel("com.bulenkov.darcula.DarculaLaf");
} catch (Exception ex) {
// not catestrophic
}
resourceMap = getContext().getResourceMap();
title = resourceMap.getString("mainFrame.title");
runningDemoCache = new HashMap<String, DemoPanel>();
setDemoList(resourceMap.getString("demos.title"), getDemoClassNames(args));
IntroPanel intro = new IntroPanel();
setDemoPlaceholder(intro);
}
private List<String>getDemoClassNames(String args[]) {
List<String> demoList = new ArrayList<String>();
boolean augment = false;
Exception exception = null;
// First look for any demo list files specified on the command-line
for(String arg : args) {
if (arg.equals("-a") || arg.equals("-augment")) {
augment = true;
} else {
// process argument as filename containing names of demo classes
try {
demoList.addAll(readDemoClassNames(new FileReader(arg) /*filename*/));
} catch (IOException ex) {
exception = ex;
logger.log(Level.WARNING, "unable to read demo class names from file: "+arg, ex);
}
}
}
if (demoList.isEmpty() || augment) {
// Load default Demos
try {
demoList.addAll(readDemoClassNames(new InputStreamReader(getClass().getResourceAsStream(DEMO_LIST_FILE))));
} catch (IOException ex) {
exception = ex;
logger.log(Level.WARNING, "unable to read resource: " + DEMO_LIST_FILE, ex);
}
}
if (demoList.isEmpty()) {
displayErrorMessage(resourceMap.getString("error.noDemosLoaded"),
exception);
}
return demoList;
}
public void setDemoList(String demoListTitle, List<String> demoClassNamesList) {
List<Demo> demoList = new ArrayList<Demo>();
for(String demoClassName: demoClassNamesList) {
Demo demo = createDemo(demoClassName);
if (demo != null) {
demoList.add(demo);
}
}
this.demoListTitle = demoListTitle;
this.demoList = demoList;
}
/**
*/
protected Demo createDemo(String demoClassName) {
Class<?> demoClass = null;
Demo demo = null;
try {
demoClass = Class.forName(demoClassName);
} catch (ClassNotFoundException cnfe) {
logger.log(Level.WARNING, "demo class not found:"+ demoClassName);
}
if (demoClass != null) {
// Wrap Demo
demo = new Demo(demoClass);
demo.addPropertyChangeListener(getDemoPropertyChangeListener());
}
return demo;
}
protected PropertyChangeListener getDemoPropertyChangeListener() {
if (demoPropertyChangeListener == null) {
demoPropertyChangeListener = new DemoPropertyChangeListener();
}
return demoPropertyChangeListener;
}
@Override
protected void startup() {
UIManager.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals("lookAndFeel")) {
configureDefaults();
}
}
});
configureDefaults();
View view = getMainView();
view.setComponent(createMainPanel());
view.setMenuBar(createMenuBar());
applyDefaults();
// application framework should handle this
getMainFrame().setIconImage(resourceMap.getImageIcon("Application.icon").getImage());
show(view);
}
private void configureDefaults() {
// Color palette algorithm courtesy of Jasper Potts
Color controlColor = UIManager.getColor("control");
UIManager.put(CONTROL_VERY_LIGHT_SHADOW_KEY,
Utilities.deriveColorHSB(controlColor, 0, 0, -0.02f));
UIManager.put(CONTROL_LIGHT_SHADOW_KEY,
Utilities.deriveColorHSB(controlColor, 0, 0, -0.06f));
UIManager.put(CONTROL_MID_SHADOW_KEY,
Utilities.deriveColorHSB(controlColor, 0, 0, -0.16f));
UIManager.put(CONTROL_VERY_DARK_SHADOW_KEY,
Utilities.deriveColorHSB(controlColor, 0, 0, -0.5f));
UIManager.put(CONTROL_DARK_SHADOW_KEY,
Utilities.deriveColorHSB(controlColor, 0, 0, -0.32f));
// Calculate gradient colors for title panels
Color titleColor = UIManager.getColor(usingNimbus()? "nimbusBase" : "activeCaption");
// Some LAFs (e.g. GTK) don't contain "activeCaption"
if (titleColor == null) {
titleColor = controlColor;
}
float hsb[] = Color.RGBtoHSB(
titleColor.getRed(), titleColor.getGreen(), titleColor.getBlue(), null);
UIManager.put(TITLE_GRADIENT_COLOR1_KEY,
Color.getHSBColor(hsb[0]-.013f, .15f, .85f));
UIManager.put(TITLE_GRADIENT_COLOR2_KEY,
Color.getHSBColor(hsb[0]-.005f, .24f, .80f));
UIManager.put(TITLE_FOREGROUND_KEY,
Color.getHSBColor(hsb[0], .54f, .40f));
// Calculate highlight color for code pane
UIManager.put(CODE_HIGHLIGHT_KEY,
Color.getHSBColor(hsb[0]-.005f, .20f, .95f));
Font labelFont = UIManager.getFont("Label.font");
UIManager.put(TITLE_FONT_KEY, labelFont.deriveFont(Font.BOLD, labelFont.getSize()+4f));
Color panelColor = UIManager.getColor("Panel.background");
UIManager.put(SUB_PANEL_BACKGROUND_KEY,
Utilities.deriveColorHSB(panelColor, 0, 0, -.06f));
applyDefaults();
}
protected void applyDefaults() {
if (codeViewer != null) {
codeViewer.setHighlightColor(UIManager.getColor(CODE_HIGHLIGHT_KEY));
}
}
protected JComponent createMainPanel() {
// Create main panel with demo selection on left and demo/source on right
mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
// Create demo selector panel on left
demoSelectorPanel = new DemoSelectorPanel(demoListTitle, demoList);
demoSelectorPanel.setPreferredSize(new Dimension(DEMO_SELECTOR_WIDTH, MAIN_FRAME_HEIGHT));
demoSelectorPanel.addPropertyChangeListener(new DemoSelectionListener());
mainPanel.add(demoSelectorPanel, BorderLayout.WEST);
// Create splitpane on right to hold demo and source code
demoSplitPane = new AnimatingSplitPane(JSplitPane.VERTICAL_SPLIT);
demoSplitPane.setBorder(EMPTY_BORDER);
mainPanel.add(demoSplitPane, BorderLayout.CENTER);
// Create panel to contain currently running demo
demoContainer = new JPanel();
demoContainer.setLayout(new BorderLayout());
demoContainer.setBorder(PANEL_BORDER);
demoContainer.setPreferredSize(new Dimension(DEMO_PANEL_WIDTH, DEMO_PANEL_HEIGHT));
demoSplitPane.setTopComponent(demoContainer);
currentDemoPanel = demoPlaceholder;
demoContainer.add(demoPlaceholder, BorderLayout.CENTER);
// Create collapsible source code pane
codeViewer = new CodeViewer();
codeContainer = new JPanel(new BorderLayout());
codeContainer.add(codeViewer);
codeContainer.setBorder(PANEL_BORDER);
codeContainer.setMinimumSize(new Dimension(0,0));
demoSplitPane.setBottomComponent(codeContainer);
addPropertyChangeListener(new SwingSetPropertyListener());
// Create shareable popup menu for demo actions
popup = new JPopupMenu();
popup.add(new EditPropertiesAction());
popup.add(new ViewCodeSnippetAction());
return mainPanel;
}
protected JMenuBar createMenuBar() {
JMenuBar menubar = new JMenuBar();
menubar.setName("menubar");
// File menu
JMenu fileMenu = new JMenu();
fileMenu.setName("file");
menubar.add(fileMenu);
// File -> Quit
if (!runningOnMac()) {
JMenuItem quitItem = new JMenuItem();
quitItem.setName("quit");
quitItem.setAction(getAction("quit"));
fileMenu.add(quitItem);
}
// View menu
JMenu viewMenu = new JMenu();
viewMenu.setName("view");
// View -> Look and Feel
viewMenu.add(createLookAndFeelMenu());
// View -> Source Code Visible
sourceCodeCheckboxItem = new JCheckBoxMenuItem();
sourceCodeCheckboxItem.setSelected(isSourceCodeVisible());
sourceCodeCheckboxItem.setName("sourceCodeCheckboxItem");
sourceCodeCheckboxItem.addChangeListener(new SourceVisibilityChangeListener());
viewMenu.add(sourceCodeCheckboxItem);
menubar.add(viewMenu);
return menubar;
}
protected JMenu createLookAndFeelMenu() {
JMenu menu = new JMenu();
menu.setName("lookAndFeel");
// Look for toolkit look and feels first
UIManager.LookAndFeelInfo lookAndFeelInfos[] = UIManager.getInstalledLookAndFeels();
lookAndFeel = UIManager.getLookAndFeel().getClass().getName();
lookAndFeelRadioGroup = new ButtonGroup();
for(UIManager.LookAndFeelInfo lafInfo: lookAndFeelInfos) {
menu.add(createLookAndFeelItem(lafInfo.getName(), lafInfo.getClassName()));
}
// Now load any look and feels defined externally as service via java.util.ServiceLoader
LOOK_AND_FEEL_LOADER.iterator();
for (LookAndFeel laf : LOOK_AND_FEEL_LOADER) {
menu.add(createLookAndFeelItem(laf.getName(), laf.getClass().getName()));
}
return menu;
}
protected JRadioButtonMenuItem createLookAndFeelItem(String lafName, String lafClassName) {
JRadioButtonMenuItem lafItem = new JRadioButtonMenuItem();
lafItem.setSelected(lafClassName.equals(lookAndFeel));
lafItem.setHideActionText(true);
lafItem.setAction(getAction("setLookAndFeel"));
lafItem.setText(lafName);
lafItem.setActionCommand(lafClassName);
lookAndFeelRadioGroup.add(lafItem);
return lafItem;
}
private javax.swing.Action getAction(String actionName) {
return getContext().getActionMap().get(actionName);
}
// For displaying error messages to user
protected void displayErrorMessage(String message, Exception ex) {
JPanel messagePanel = new JPanel(new BorderLayout());
JLabel label = new JLabel(message);
messagePanel.add(label);
if (ex != null) {
RoundedPanel panel = new RoundedPanel(new BorderLayout());
panel.setBorder(new RoundedBorder());
// remind(aim): provide way to allow user to see exception only if desired
StringWriter writer = new StringWriter();
ex.printStackTrace(new PrintWriter(writer));
JTextArea exceptionText = new JTextArea();
exceptionText.setText("Cause of error:\n" +
writer.getBuffer().toString());
exceptionText.setBorder(new RoundedBorder());
exceptionText.setOpaque(false);
exceptionText.setBackground(
Utilities.deriveColorHSB(UIManager.getColor("Panel.background"),
0, 0, -.2f));
JScrollPane scrollpane = new JScrollPane(exceptionText);
scrollpane.setBorder(EMPTY_BORDER);
scrollpane.setPreferredSize(new Dimension(600,240));
panel.add(scrollpane);
messagePanel.add(panel, BorderLayout.SOUTH);
}
JOptionPane.showMessageDialog(getMainFrame(), messagePanel,
resourceMap.getString("error.title"),
JOptionPane.ERROR_MESSAGE);
}
public void setDemoPlaceholder(JComponent demoPlaceholder) {
JComponent oldDemoPlaceholder = this.demoPlaceholder;
this.demoPlaceholder = demoPlaceholder;
firePropertyChange("demoPlaceholder", oldDemoPlaceholder, demoPlaceholder);
}
public JComponent getDemoPlaceholder() {
return demoPlaceholder;
}
public void setCurrentDemo(Demo demo) {
if (currentDemo == demo) {
return; // already there
}
Demo oldCurrentDemo = currentDemo;
currentDemo = demo;
if (demo != null) {
DemoPanel demoPanel = runningDemoCache.get(demo.getName());
if (demoPanel == null || demo.getDemoComponent() == null) {
demo.startInitializing();
demoPanel = new DemoPanel(demo);
demoPanel.setPreferredSize(currentDemoPanel.getPreferredSize());
runningDemoCache.put(demo.getName(), demoPanel);
}
demoContainer.remove(currentDemoPanel);
currentDemoPanel = demoPanel;
demoContainer.add(currentDemoPanel, BorderLayout.CENTER);
demoContainer.revalidate();
demoContainer.repaint();
getMainFrame().validate();
}
if (currentDemo == null) {
demoContainer.add(demoPlaceholder, BorderLayout.CENTER);
}
if (isSourceCodeVisible()) {
codeViewer.setSourceFiles(currentDemo != null?
currentDemo.getSourceFiles() : null);
}
firePropertyChange("currentDemo", oldCurrentDemo, demo);
}
public Demo getCurrentDemo() {
return currentDemo;
}
public void setLookAndFeel(String lookAndFeel) throws ClassNotFoundException,
InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
String oldLookAndFeel = this.lookAndFeel;
if (oldLookAndFeel != lookAndFeel) {
UIManager.setLookAndFeel(lookAndFeel);
this.lookAndFeel = lookAndFeel;
updateLookAndFeel();
firePropertyChange("lookAndFeel", oldLookAndFeel, lookAndFeel);
}
}
@Action
public void setLookAndFeel() {
ButtonModel model = lookAndFeelRadioGroup.getSelection();
String lookAndFeelName = model.getActionCommand();
try {
setLookAndFeel(lookAndFeelName);
} catch (Exception ex) {
displayErrorMessage(resourceMap.getString("error.unableToChangeLookAndFeel") +
"to "+lookAndFeelName, ex);
}
}
public String getLookAndFeel() {
return lookAndFeel;
}
public void setSourceCodeVisible(boolean sourceVisible) {
boolean oldSourceVisible = this.sourceVisible;
this.sourceVisible = sourceVisible;
firePropertyChange("sourceCodeVisible", oldSourceVisible, sourceVisible);
}
public boolean isSourceCodeVisible() {
return sourceVisible;
}
private void updateLookAndFeel() {
Window windows[] = Frame.getWindows();
for(Window window : windows) {
SwingUtilities.updateComponentTreeUI(window);
for(DemoPanel demoPanel : runningDemoCache.values()) {
SwingUtilities.updateComponentTreeUI(demoPanel);
}
}
}
// hook used to detect if any components in the demo have registered a
// code snippet key for the their creation code inside the source
private void registerPopups(Component component) {
if (component instanceof Container) {
Component children[] = ((Container)component).getComponents();
for(Component child: children) {
if (child instanceof JComponent) {
registerPopups(child);
}
}
}
if (component instanceof JComponent) {
JComponent jcomponent = (JComponent)component;
String snippetKey = (String)jcomponent.getClientProperty("snippetKey");
if (snippetKey != null) {
jcomponent.setComponentPopupMenu(popup);
}
}
}
private class DemoSelectionListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName().equals("selectedDemo")) {
setCurrentDemo((Demo)event.getNewValue());
}
}
}
// registered on Demo to detect when the demo component is instantiated.
// we need this because when we embed the demo inside an HTML description pane,
// we don't have control over the demo component's instantiation
private class DemoPropertyChangeListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if (propertyName.equals("demoComponent")) {
Demo demo = (Demo)e.getSource();
JComponent demoComponent = (JComponent)e.getNewValue();
if (demoComponent != null) {
demoComponent.putClientProperty("swingset3.demo", demo);
demoComponent.addHierarchyListener(new DemoVisibilityListener());
registerPopups(demoComponent);
}
}
}
}
private class DemoVisibilityListener implements HierarchyListener {
public void hierarchyChanged(HierarchyEvent event) {
if ((event.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) > 0) {
JComponent component = (JComponent)event.getComponent();
final Demo demo = (Demo)component.getClientProperty("swingset3.demo");
if (!component.isShowing()) {
demo.stop();
} else {
demoContainer.revalidate();
EventQueue.invokeLater(new Runnable() {
public void run() {
demo.start();
}
});
}
}
}
}
// activated when user selects/unselects checkbox menu item
private class SourceVisibilityChangeListener implements ChangeListener {
public void stateChanged(ChangeEvent event) {
setSourceCodeVisible(sourceCodeCheckboxItem.isSelected());
}
}
private class SwingSetPropertyListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent event) {
String propertyName = event.getPropertyName();
if (propertyName.equals("sourceCodeVisible")) {
boolean sourceVisible = ((Boolean)event.getNewValue()).booleanValue();
if (sourceVisible) {
// update codeViewer in case current demo changed while
// source was invisible
codeViewer.setSourceFiles(currentDemo != null?
currentDemo.getSourceFiles() : null);
}
demoSplitPane.setExpanded(!sourceVisible);
sourceCodeCheckboxItem.setSelected(sourceVisible);
}
}
}
private class ViewCodeSnippetAction extends AbstractAction {
public ViewCodeSnippetAction() {
super("View Source Code");
}
public void actionPerformed(ActionEvent actionEvent) {
Container popup = (JComponent)actionEvent.getSource();
while(popup != null && !(popup instanceof JPopupMenu)) {
popup = popup.getParent();
}
JComponent target = (JComponent)((JPopupMenu)popup).getInvoker();
setSourceCodeVisible(true);
String snippetKey = (String)target.getClientProperty("snippetKey");
if (snippetKey != null) {
codeViewer.highlightSnippetSet(snippetKey);
} else {
logger.log(Level.WARNING, "can't find source code snippet for:" + snippetKey);
}
}
}
private static class EditPropertiesAction extends AbstractAction {
public EditPropertiesAction() {
super("Edit Properties");
}
public boolean isEnabled() {
return false;
}
public void actionPerformed(ActionEvent actionEvent) {
}
}
}

410
swingset3/com/sun/swingset3/codeview/CodeStyler.java

@ -0,0 +1,410 @@
/**
* CodeStyler.java
*
* Bill Lynch & Matt Tucker
* CoolServlets.com, October 1999
*
* Please visit CoolServlets.com for high quality, open source Java servlets.
*
* Copyright (C) 1999 CoolServlets.com
*
* Any errors or suggested improvements to this class can be reported
* as instructed on Coolservlets.com. We hope you enjoy
* this program... your comments will encourage further development!
*
* This software is distributed under the terms of The BSD License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither name of CoolServlets.com nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY COOLSERVLETS.COM AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COOLSERVLETS.COM OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* @(#)CodeStyler.java 1.6 02/06/13
*/
package com.sun.swingset3.codeview;
import java.util.*;
/**
* A class that syntax highlights Java code by turning it into html.
*
* <p> A <code>CodeStyler</code> object is created and then keeps state as
* lines are passed in. Each line passed in as java text, is returned as syntax
* highlighted html text. (note: this class was originally named CodeViewer)
*
* <p> Users of the class can set how the java code will be highlighted with
* setter methods.
*
* <p> Only valid java lines should be passed in since the object maintains
* state and may not handle illegal code gracefully.
*
* <p> The actual system is implemented as a series of filters that deal with
* specific portions of the java code. The filters are as follows:
*
* <pre>
* htmlFilter
* |__
* multiLineCommentFilter
* |___
* inlineCommentFilter
* |___
* stringFilter
* |__
* keywordFilter
* </pre>
*
* @author Bill Lynch, Matt Tucker, CoolServlets.com
* @version 1.6 06/13/02
*/
public class CodeStyler {
private final static Map<String, String> RESERVED_WORDS = new HashMap<String, String>(); // >= Java2 only (also, not thread-safe)
private boolean inMultiLineComment = false;
private String commentStart = "</font><font size=4 color=\"#0000aa\"><i>";
private String commentEnd = "</font></i><font size=4 color=black>";
private String stringStart = "</font><font size=4 color=\"#00bb00\">";
private String stringEnd = "</font><font size=4 color=black>";
private String reservedWordStart = "<b>";
private String reservedWordEnd = "</b>";
static {
loadHash();
}
public CodeStyler() {
}
public void setCommentStart(String commentStart) {
this.commentStart = commentStart;
}
public void setCommentEnd(String commentEnd) {
this.commentEnd = commentEnd;
}
public void setStringStart(String stringStart) {
this.stringStart = stringStart;
}
public void setStringEnd(String stringEnd) {
this.stringEnd = stringEnd;
}
public void setReservedWordStart(String reservedWordStart) {
this.reservedWordStart = reservedWordStart;
}
public void setReservedWordEnd(String reservedWordEnd) {
this.reservedWordEnd = reservedWordEnd;
}
public String getCommentStart() {
return commentStart;
}
public String getCommentEnd() {
return commentEnd;
}
public String getStringStart() {
return stringStart;
}
public String getStringEnd() {
return stringEnd;
}
public String getReservedWordStart() {
return reservedWordStart;
}
public String getReservedWordEnd() {
return reservedWordEnd;
}
/**
* Passes off each line to the first filter.
* @param line The line of Java code to be highlighted.
*/
public String syntaxHighlight( String line ) {
return htmlFilter(line);
}
/*
* Filter html tags into more benign text.
*/
private String htmlFilter( String line ) {
if( line == null || line.equals("") ) {
return "";
}
// replace ampersands with HTML escape sequence for ampersand;
line = replace(line, "&", "&#38;");
// replace the \\ with HTML escape sequences. fixes a problem when
// backslashes preceed quotes.
line = replace(line, "\\\\", "&#92;&#92;" );
// replace \" sequences with HTML escape sequences;
line = replace(line, "" + (char)92 + (char)34, "&#92;&#34");
// replace less-than signs which might be confused
// by HTML as tag angle-brackets;
line = replace(line, "<", "&#60;");
// replace greater-than signs which might be confused
// by HTML as tag angle-brackets;
line = replace(line, ">", "&#62;");
return multiLineCommentFilter(line);
}
/*
* Filter out multiLine comments. State is kept with a private boolean
* variable.
*/
private String multiLineCommentFilter(String line) {
if (line == null || line.equals("")) {
return "";
}
StringBuffer buf = new StringBuffer();
int index;
//First, check for the end of a multi-line comment.
if (inMultiLineComment && (index = line.indexOf("*/")) > -1 && !isInsideString(line,index)) {
inMultiLineComment = false;
buf.append(line.substring(0,index));
buf.append("*/").append(commentEnd);
if (line.length() > index+2) {
buf.append(inlineCommentFilter(line.substring(index+2)));
}
return buf.toString();
}
//If there was no end detected and we're currently in a multi-line
//comment, we don't want to do anymore work, so return line.
else if (inMultiLineComment) {
return line;
}
//We're not currently in a comment, so check to see if the start
//of a multi-line comment is in this line.
else if ((index = line.indexOf("/*")) > -1 && !isInsideString(line,index)) {
inMultiLineComment = true;
//Return result of other filters + everything after the start
//of the multiline comment. We need to pass the through the
//to the multiLineComment filter again in case the comment ends
//on the same line.
buf.append(inlineCommentFilter(line.substring(0,index)));
buf.append(commentStart).append("/*");
buf.append(multiLineCommentFilter(line.substring(index+2)));
return buf.toString();
}
//Otherwise, no useful multi-line comment information was found so
//pass the line down to the next filter for processesing.
else {
return inlineCommentFilter(line);
}
}
/*
* Filter inline comments from a line and formats them properly.
*/
private String inlineCommentFilter(String line) {
if (line == null || line.equals("")) {
return "";
}
StringBuffer buf = new StringBuffer();
int index;
if ((index = line.indexOf("//")) > -1 && !isInsideString(line,index)) {
buf.append(stringFilter(line.substring(0,index)));
buf.append(commentStart);
buf.append(line.substring(index));
buf.append(commentEnd);
}
else {
buf.append(stringFilter(line));
}
return buf.toString();
}
/*
* Filters strings from a line of text and formats them properly.
*/
private String stringFilter(String line) {
if (line == null || line.equals("")) {
return "";
}
StringBuffer buf = new StringBuffer();
if (!line.contains("\"")) {
return keywordFilter(line);
}
int start = 0;
int startStringIndex = -1;
int endStringIndex;
int tempIndex;
//Keep moving through String characters until we want to stop...
while ((tempIndex = line.indexOf("\"")) > -1) {
//We found the beginning of a string
if (startStringIndex == -1) {
startStringIndex = 0;
buf.append( stringFilter(line.substring(start,tempIndex)) );
buf.append(stringStart).append("\"");
line = line.substring(tempIndex+1);
}
//Must be at the end
else {
startStringIndex = -1;
endStringIndex = tempIndex;
buf.append(line.substring(0,endStringIndex+1));
buf.append(stringEnd);
line = line.substring(endStringIndex+1);
}
}
buf.append( keywordFilter(line) );
return buf.toString();
}
/*
* Filters keywords from a line of text and formats them properly.
*/
private String keywordFilter( String line ) {
if( line == null || line.equals("") ) {
return "";
}
StringBuffer buf = new StringBuffer();
Map<String, String> usedReservedWords = new HashMap<String, String>(); // >= Java2 only (not thread-safe)
//Hashtable usedReservedWords = new Hashtable(); // < Java2 (thread-safe)
int i=0;
char ch;
StringBuffer temp = new StringBuffer();
while( i < line.length() ) {
temp.setLength(0);
ch = line.charAt(i);
// 65-90, uppercase letters
// 97-122, lowercase letters
while( i<line.length() && ( ( ch >= 65 && ch <= 90 )
|| ( ch >= 97 && ch <= 122 ) ) ) {
temp.append(ch);
i++;
if( i < line.length() ) {
ch = line.charAt(i);
}
}
String tempString = temp.toString();
if( RESERVED_WORDS.containsKey(tempString) && !usedReservedWords.containsKey(tempString)) {
usedReservedWords.put(tempString,tempString);
line = replace( line, tempString, (reservedWordStart+tempString+reservedWordEnd) );
i += (reservedWordStart.length() + reservedWordEnd.length());
}
else {
i++;
}
}
buf.append(line);
return buf.toString();
}
/*
* All important replace method. Replaces all occurences of oldString in
* line with newString.
*/
private static String replace( String line, String oldString, String newString ) {
int i=0;
while( ( i=line.indexOf( oldString, i ) ) >= 0 ) {
line = (new StringBuffer().append(line.substring(0,i)).append(newString).append(line.substring(i+oldString.length()))).toString();
i += newString.length();
}
return line;
}
/*
* Checks to see if some position in a line is between String start and
* ending characters. Not yet used in code or fully working :)
*/
private static boolean isInsideString(String line, int position) {
if (!line.contains("\"")) {
return false;
}
int index;
String left = line.substring(0,position);
String right = line.substring(position);
int leftCount = 0;
int rightCount = 0;
while ((index = left.indexOf("\"")) > -1) {
leftCount ++;
left = left.substring(index+1);
}
while ((index = right.indexOf("\"")) > -1) {
rightCount ++;
right = right.substring(index+1);
}
return rightCount % 2 != 0 && leftCount % 2 != 0;
}
/*
* Load Hashtable (or HashMap) with Java reserved words.
*/
private static void loadHash() {
RESERVED_WORDS.put("abstract", "abstract");
RESERVED_WORDS.put("do", "do");
RESERVED_WORDS.put("inner", "inner");
RESERVED_WORDS.put("public", "public");
RESERVED_WORDS.put("var", "var");
RESERVED_WORDS.put("boolean", "boolean");
RESERVED_WORDS.put("continue", "continue");
RESERVED_WORDS.put("int", "int");
RESERVED_WORDS.put("return", "return");
RESERVED_WORDS.put("void", "void");
RESERVED_WORDS.put("break", "break");
RESERVED_WORDS.put("else", "else");
RESERVED_WORDS.put("interface", "interface");
RESERVED_WORDS.put("short", "short");
RESERVED_WORDS.put("volatile", "volatile");
RESERVED_WORDS.put("byvalue", "byvalue");
RESERVED_WORDS.put("extends", "extends");
RESERVED_WORDS.put("long", "long");
RESERVED_WORDS.put("static", "static");
RESERVED_WORDS.put("while", "while");
RESERVED_WORDS.put("case", "case");
RESERVED_WORDS.put("final", "final");
RESERVED_WORDS.put("naive", "naive");
RESERVED_WORDS.put("super", "super");
RESERVED_WORDS.put("transient", "transient");
RESERVED_WORDS.put("cast", "cast");
RESERVED_WORDS.put("float", "float");
RESERVED_WORDS.put("new", "new");
RESERVED_WORDS.put("rest", "rest");
RESERVED_WORDS.put("catch", "catch");
RESERVED_WORDS.put("for", "for");
RESERVED_WORDS.put("null", "null");
RESERVED_WORDS.put("synchronized", "synchronized");
RESERVED_WORDS.put("char", "char");
RESERVED_WORDS.put("finally", "finally");
RESERVED_WORDS.put("operator", "operator");
RESERVED_WORDS.put("this", "this");
RESERVED_WORDS.put("class", "class");
RESERVED_WORDS.put("generic", "generic");
RESERVED_WORDS.put("outer", "outer");
RESERVED_WORDS.put("switch", "switch");
RESERVED_WORDS.put("const", "const");
RESERVED_WORDS.put("goto", "goto");
RESERVED_WORDS.put("package", "package");
RESERVED_WORDS.put("throw", "throw");
RESERVED_WORDS.put("double", "double");
RESERVED_WORDS.put("if", "if");
RESERVED_WORDS.put("private", "private");
RESERVED_WORDS.put("true", "true");
RESERVED_WORDS.put("default", "default");
RESERVED_WORDS.put("import", "import");
RESERVED_WORDS.put("protected", "protected");
RESERVED_WORDS.put("try", "try");
}
}

927
swingset3/com/sun/swingset3/codeview/CodeViewer.java

@ -0,0 +1,927 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.codeview;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.Highlighter;
import com.sun.swingset3.utilities.RoundedBorder;
import com.sun.swingset3.utilities.RoundedPanel;
import com.sun.swingset3.utilities.Utilities;
/**
* GUI component for viewing a set of one or more Java source code files,
* providing the user with the ability to easily highlight specific code fragments.
* A tabbedpane is used to control which source code file is shown within the set
* if more than one file is loaded.
* <p>
* Example usage:
* <pre><code>
* CodeViewer codeViewer = new CodeViewer();
* codeViewer.setSourceFiles(mySourceURLs);
* frame.add(codeViewer);
* </code></pre>
*
* <p>
* When loading the source code, this viewer will automatically parse the files for
* any source fragments which are marked with &quot;snippet&quot; start/end tags that
* are embedded within Java comments. The viewer will allow the user to highlight
* these code snippets for easier inspection of specific code.
* <p>
* The text following immediately after the start tag will be used
* as the key for that snippet. Multiple snippets may share the same
* key, defining a &quot;snippet set&quot;. Snippet sets may even span across
* multiple source files.
* The key for each snippet set is displayed in a combobox to allow the user to
* select which snippet set should be highlighted. For example:<p>
* <pre><code>
* //<snip>Create dog array
* ArrayList dogs = new ArrayList();
* //</snip>
*
* [other code...]
*
* //<snip>Create dog array
* dogs.add("Labrador");
* dogs.add("Golden Retriever");
* dogs.add("Australian Shepherd");
* //</snip>
* </code></pre>
* The above code would create a snippet set (containing 2 snippets) with the key
* &quot;Create dog array&quot;.
* <p>
* The viewer will allow the user to easily navigate across the currently highlighted
* snippet set by pressing the navigation buttons or using accelerator keys.
*
* @author aim
*/
public class CodeViewer extends JPanel {
public static final String SOURCES_JAVA = ".+\\.java";
public static final String SOURCES_TEXT = ".+\\.properties|.+\\.txt|.+\\.html|.+\\.xml";
public static final String SOURCES_IMAGES = ".+\\.jpg|.+\\.gif|.+\\.png";
private static final Color DEFAULT_HIGHLIGHT_COLOR = new Color(255,255,176);
private static BufferedImage SNIPPET_GLYPH;
private static String NO_SNIPPET_SELECTED;
static final Logger logger = Logger.getLogger(CodeViewer.class.getName());
static {
try {
URL imageURL = CodeViewer.class.getResource("resources/images/snippetglyph.png");
SNIPPET_GLYPH = ImageIO.read(imageURL);
} catch (Exception e) {
System.err.println(e);
}
}
// Cache all processed code files in case they are reloaded later
private final Map<URL,CodeFileInfo> codeCache = new HashMap<URL,CodeFileInfo>();
private JComponent codeHighlightBar;
private JComboBox snippetComboBox;
private JComponent codePanel;
private JLabel noCodeLabel;
private JTabbedPane codeTabbedPane;
private Color highlightColor;
private Highlighter.HighlightPainter snippetPainter;
private ResourceBundle bundle;
// Current code file set
private Map<URL, CodeFileInfo> currentCodeFilesInfo;
private List<URL> additionalSourceFiles;
// Map of all snippets in current code file set
private final SnippetMap snippetMap = new SnippetMap();
private Action firstSnippetAction;
private Action nextSnippetAction;
private Action previousSnippetAction;
private Action lastSnippetAction;
/**
* Creates a new instance of CodeViewer
*/
public CodeViewer() {
setHighlightColor(DEFAULT_HIGHLIGHT_COLOR);
initActions();
setLayout(new BorderLayout());
codeHighlightBar = createCodeHighlightBar();
codeHighlightBar.setVisible(false);
add(codeHighlightBar, BorderLayout.NORTH);
codePanel = createCodePanel();
add(codePanel, BorderLayout.CENTER);
applyDefaults();
}
protected JComponent createCodeHighlightBar() {
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
JPanel bar = new JPanel(gridbag);
bar.setBorder(new EmptyBorder(0, 0, 10, 0));
NO_SNIPPET_SELECTED = getString("CodeViewer.snippets.selectOne",
"Select One");
JLabel snippetSetsLabel = new JLabel(getString("CodeViewer.snippets.highlightCode",
"Highlight code to: "));
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.WEST;
c.weightx = 0;
gridbag.addLayoutComponent(snippetSetsLabel, c);
bar.add(snippetSetsLabel);
snippetComboBox = new JComboBox();
snippetComboBox.setMaximumRowCount(20);
snippetComboBox.setRenderer(new SnippetCellRenderer(snippetComboBox.getRenderer()));
snippetComboBox.addActionListener(new SnippetActivator());
snippetSetsLabel.setLabelFor(snippetComboBox);
c.gridx++;
c.weightx = 1;
gridbag.addLayoutComponent(snippetComboBox, c);
bar.add(snippetComboBox);
SnippetNavigator snippetNavigator = new SnippetNavigator(snippetMap);
snippetNavigator.setNavigateNextAction(nextSnippetAction);
snippetNavigator.setNavigatePreviousAction(previousSnippetAction);
c.gridx++;
c.anchor = GridBagConstraints.EAST;
c.weightx = 0;
gridbag.addLayoutComponent(snippetNavigator, c);
bar.add(snippetNavigator);
return bar;
}
protected JComponent createCodePanel() {
JPanel panel = new RoundedPanel(new BorderLayout(), 10);
panel.setBorder(new RoundedBorder(10));
noCodeLabel = new JLabel(getString("CodeViewer.noCodeLoaded", "no code loaded"));
noCodeLabel.setHorizontalAlignment(JLabel.CENTER);
panel.add(noCodeLabel, BorderLayout.CENTER);
return panel;
}
@Override
public void updateUI() {
super.updateUI();
applyDefaults();
}
protected void applyDefaults() {
if (noCodeLabel != null) {
noCodeLabel.setOpaque(false);
noCodeLabel.setFont(UIManager.getFont("Label.font").deriveFont(24f));
noCodeLabel.setForeground(
Utilities.deriveColorAlpha(UIManager.getColor("Label.foreground"), 110));
}
if (codePanel != null) {
Color base = UIManager.getColor("Panel.background");
codePanel.setBackground(Utilities.deriveColorHSB(base, 0, 0, -.06f));
}
if (snippetComboBox != null) {
// Now that the look and feel has changed, we need to wrap the new delegate
snippetComboBox.setRenderer(new SnippetCellRenderer(
new JComboBox().getRenderer()));
}
if (currentCodeFilesInfo != null) {
Collection<CodeFileInfo> codeFiles = currentCodeFilesInfo.values();
for(CodeFileInfo cfi : codeFiles) {
makeSelectionTransparent(cfi.textPane, 180);
}
}
}
private void makeSelectionTransparent(JEditorPane textPane, int alpha) {
Color c = textPane.getSelectionColor();
textPane.setSelectionColor(
new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha));
}
protected String getString(String key, String fallback) {
String value = fallback;
if (bundle == null) {
String bundleName = getClass().getPackage().getName()+".resources."+getClass().getSimpleName();
bundle = ResourceBundle.getBundle(bundleName);
}
try {
value = bundle != null? bundle.getString(key) : fallback;
} catch (MissingResourceException e) {
logger.log(Level.WARNING, "missing String resource " + key +
"; using fallback \"" +fallback + "\"");
}
return value;
}
protected void initActions() {
firstSnippetAction = new FirstSnippetAction();
nextSnippetAction = new NextSnippetAction();
previousSnippetAction = new PreviousSnippetAction();
lastSnippetAction = new LastSnippetAction();
firstSnippetAction.setEnabled(false);
nextSnippetAction.setEnabled(false);
previousSnippetAction.setEnabled(false);
lastSnippetAction.setEnabled(false);
getActionMap().put("NextSnippet", nextSnippetAction);
getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ctrl N"),"NextSnippet");
getActionMap().put("PreviousSnippet", previousSnippetAction);
getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ctrl P"),"PreviousSnippet");
}
public void setHighlightColor(Color highlight) {
if (!highlight.equals(highlightColor)) {
highlightColor = highlight;
snippetPainter = new SnippetHighlighter.SnippetHighlightPainter(highlightColor);
if (getCurrentSnippetKey() != null) {
repaint();
}
}
}
public Color getHighlightColor() {
return highlightColor;
}
public void setSourceFiles(URL sourceFiles[]) {
if (currentCodeFilesInfo != null && additionalSourceFiles != null && sourceFiles != null &&
currentCodeFilesInfo.size() + additionalSourceFiles.size() == sourceFiles.length) {
List<URL> list = Arrays.asList(sourceFiles);
if (list.containsAll(currentCodeFilesInfo.keySet()) && list.containsAll(additionalSourceFiles)) {
// already loaded
return;
}
}
// clear everything
clearAllSnippetHighlights();
snippetMap.clear();
if (sourceFiles == null) {
// being reset to having no source files; need to clear everything
currentCodeFilesInfo = null;
additionalSourceFiles = null;
configureCodePane(false);
configureSnippetSetsComboBox();
} else {
// Use LinkedHashMap to save source order
currentCodeFilesInfo = new LinkedHashMap<URL, CodeFileInfo>();
additionalSourceFiles = new ArrayList<URL>();
boolean needProcessing = false;
for (URL sourceFile : sourceFiles) {
if (sourceFile.getFile().matches(SOURCES_JAVA)) {
// look in cache first to avoid unnecessary processing
CodeFileInfo cachedFilesInfo = codeCache.get(sourceFile);
currentCodeFilesInfo.put(sourceFile, cachedFilesInfo);
if (cachedFilesInfo == null) {
needProcessing = true;
}
} else {
additionalSourceFiles.add(sourceFile);
}
}
configureCodePane(true);
if (needProcessing) {
// Do it on a separate thread
new SourceProcessor(currentCodeFilesInfo).execute();
} else {
for (CodeFileInfo codeFileInfo : currentCodeFilesInfo.values()) {
registerSnippets(codeFileInfo);
createCodeFileTab(codeFileInfo);
}
createAdditionalTabs();
configureSnippetSetsComboBox();
}
}
}
private void createAdditionalTabs() {
JPanel pnImages = null;
for (URL sourceFile : additionalSourceFiles) {
String sourcePath = sourceFile.getPath();
int i = sourcePath.indexOf('!');
if (i >= 0) {
sourcePath = sourcePath.substring(i + 1);
}
if (sourceFile.getFile().matches(SOURCES_IMAGES)) {
if (pnImages == null) {
pnImages = new JPanel();
pnImages.setLayout(new BoxLayout(pnImages, BoxLayout.Y_AXIS));
}
JLabel label = new JLabel();
label.setIcon(new ImageIcon(sourceFile));
label.setBorder(new EmptyBorder(10, 0, 40, 0));
pnImages.add(new JLabel(sourcePath));
pnImages.add(label);
}
if (sourceFile.getFile().matches(SOURCES_TEXT)) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(sourceFile.openStream()));
StringBuilder content = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
content.append(line).append('\n');
}
JTextArea textArea = new JTextArea(content.toString());
Font font = textArea.getFont();
textArea.setEditable(false);
textArea.setFont(new Font("Monospaced", font.getStyle(), font.getSize()));
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setBorder(null);
codeTabbedPane.addTab(Utilities.getURLFileName(sourceFile), scrollPane);
} catch (IOException e) {
System.err.println(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
}
}
if (pnImages != null) {
JScrollPane scrollPane = new JScrollPane(pnImages);
scrollPane.setBorder(null);
codeTabbedPane.addTab(getString("CodeViewer.images", "Images"), scrollPane);
}
}
private class SourceProcessor extends SwingWorker<Void, CodeFileInfo> {
private final Map<URL, CodeFileInfo> codeFilesInfo;
public SourceProcessor(Map<URL, CodeFileInfo> codeFilesInfo) {
this.codeFilesInfo = codeFilesInfo;
}
public Void doInBackground() {
for (Map.Entry<URL, CodeFileInfo> entry : codeFilesInfo.entrySet()) {
// if not already fetched from cache, then process source code
if (entry.getValue() == null) {
entry.setValue(initializeCodeFileInfo(entry.getKey()));
}
// We don't publish intermediate to avoid tab mixing
codeCache.put(entry.getKey(), entry.getValue());
}
return null;
}
private CodeFileInfo initializeCodeFileInfo(URL sourceFile) {
CodeFileInfo codeFileInfo = new CodeFileInfo();
codeFileInfo.url = sourceFile;
codeFileInfo.styled = loadSourceCode(sourceFile);
codeFileInfo.textPane = new JEditorPane();
codeFileInfo.textPane.setHighlighter(new SnippetHighlighter());
makeSelectionTransparent(codeFileInfo.textPane, 180);
codeFileInfo.veneer = new CodeVeneer(codeFileInfo);
Stacker layers = new Stacker(codeFileInfo.textPane);
layers.add(codeFileInfo.veneer, JLayeredPane.POPUP_LAYER);
codeFileInfo.textPane.setContentType("text/html");
codeFileInfo.textPane.setEditable(false); // HTML won't display correctly without this!
codeFileInfo.textPane.setText(codeFileInfo.styled);
codeFileInfo.textPane.setCaretPosition(0);
// MUST parse AFTER textPane Document has been created to ensure
// snippet offsets are relative to the editor pane's Document model
codeFileInfo.snippets = SnippetParser.parse(codeFileInfo.textPane.getDocument());
return codeFileInfo;
}
protected void done() {
try {
// It's possible that by now another set of source files has been loaded.
// so check first before adding the source tab;'
if (currentCodeFilesInfo == codeFilesInfo) {
for (CodeFileInfo codeFileInfo : currentCodeFilesInfo.values()) {
registerSnippets(codeFileInfo);
createCodeFileTab(codeFileInfo);
}
} else {
logger.log(Level.FINEST, "source files changed before sources was processed.");
}
createAdditionalTabs();
configureSnippetSetsComboBox();
} catch (Exception ex) {
System.err.println(ex);
}
}
} // SourceProcessor
// Called from Source Processing Thread in SwingWorker
private void configureCodePane(boolean hasCodeFiles) {
if (hasCodeFiles) {
if (codeTabbedPane == null) {
codeTabbedPane = new JTabbedPane();
codePanel.remove(noCodeLabel);
codePanel.add(codeTabbedPane);
revalidate();
} else {
codeTabbedPane.removeAll();
}
} else {
// No code files
if (codeTabbedPane != null) {
codePanel.remove(codeTabbedPane);
codeTabbedPane = null;
codePanel.add(noCodeLabel);
revalidate();
}
}
}
private void createCodeFileTab(CodeFileInfo codeFileInfo) {
JLayeredPane layeredPane = JLayeredPane.getLayeredPaneAbove(codeFileInfo.textPane);
JScrollPane scrollPane = new JScrollPane(layeredPane);
scrollPane.setBorder(null);
JPanel tabPanel = new JPanel();
tabPanel.setLayout(new BorderLayout());
tabPanel.add(scrollPane, BorderLayout.CENTER);
codeTabbedPane.addTab(Utilities.getURLFileName(codeFileInfo.url), tabPanel);
}
private void registerSnippets(CodeFileInfo codeFileInfo) {
for(String snippetKey: codeFileInfo.snippets.keySet()) {
List<Snippet> snippetCodeList = codeFileInfo.snippets.get(snippetKey);
for(Snippet snippet: snippetCodeList) {
snippetMap.add(snippetKey, codeFileInfo.url, snippet);
}
}
}
private void configureSnippetSetsComboBox() {
TreeSet sortedSnippets = new TreeSet(snippetMap.keySet());
String snippetSetKeys[] = (String[])sortedSnippets.toArray(new String[0]);
DefaultComboBoxModel snippetModel = new DefaultComboBoxModel();
for(String snippetKey : snippetSetKeys) {
snippetModel.addElement(snippetKey);
}
snippetModel.insertElementAt(NO_SNIPPET_SELECTED, 0);
snippetModel.setSelectedItem(NO_SNIPPET_SELECTED);
snippetComboBox.setModel(snippetModel);
codeHighlightBar.setVisible(snippetModel.getSize() > 1);
}
/**
* Reads the java source file at the specified URL and returns an
* HTML version stylized for display
*/
protected String loadSourceCode(URL sourceUrl) {
InputStreamReader isr = null;
CodeStyler cv = new CodeStyler();
String styledCode = "<html><body bgcolor=\"#ffffff\"><pre>";
try {
isr = new InputStreamReader(sourceUrl.openStream(), "UTF-8");
BufferedReader reader = new BufferedReader(isr);
// Read one line at a time, htmlizing using super-spiffy
// html java code formating utility from www.CoolServlets.com
String line = reader.readLine();
while(line != null) {
styledCode += cv.syntaxHighlight(line) + " \n ";
line = reader.readLine();
}
styledCode += "</pre></body></html>";
} catch (Exception ex) {
ex.printStackTrace();
return "Could not load file from: " + sourceUrl;
} finally {
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
return styledCode;
}
public void clearAllSnippetHighlights() {
if (currentCodeFilesInfo != null) {
snippetMap.setCurrentSet(null);
for(CodeFileInfo code : currentCodeFilesInfo.values()) {
if (code != null && code.textPane != null) {
Highlighter highlighter = code.textPane.getHighlighter();
highlighter.removeAllHighlights();
code.textPane.repaint();
code.veneer.repaint();
}
}
}
}
public void highlightSnippetSet(String snippetKey) {
clearAllSnippetHighlights();
snippetMap.setCurrentSet(snippetKey);
URL files[] = snippetMap.getFilesForSet(snippetKey);
CodeFileInfo firstCodeFileInfo = null;
Snippet firstSnippet = null;
for(URL file : files) {
CodeFileInfo codeFileInfo = codeCache.get(file);
Highlighter highlighter = codeFileInfo.textPane.getHighlighter();
// now add highlight for each snippet in this file associated
// with the key
Snippet snippets[] = snippetMap.getSnippetsForFile(snippetKey, file);
if (firstCodeFileInfo == null) {
firstCodeFileInfo = codeFileInfo;
firstSnippet = snippets[0];
}
for (Snippet snippet : snippets) {
try {
highlighter.addHighlight(snippet.startLine,
snippet.endLine, snippetPainter );
codeFileInfo.veneer.repaint();
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
scrollToSnippet(firstCodeFileInfo, firstSnippet);
snippetComboBox.setSelectedItem(snippetKey);
}
protected void scrollToSnippet(CodeFileInfo codeFileInfo, Snippet snippet) {
if (!codeFileInfo.textPane.isShowing()) {
// Need to switch tabs to source file with first snippet
// remind: too brittle - need to find component some other way
codeTabbedPane.setSelectedComponent(
JLayeredPane.getLayeredPaneAbove(codeFileInfo.textPane).getParent().getParent().getParent());
}
try {
Rectangle r1 = codeFileInfo.textPane.modelToView(snippet.startLine);
Rectangle r2 = codeFileInfo.textPane.modelToView(snippet.endLine);
codeFileInfo.textPane.scrollRectToVisible(
SwingUtilities.computeUnion(r1.x, r1.y,
r1.width, r1.height, r2));
} catch (BadLocationException e) {
System.err.println(e);
}
nextSnippetAction.setEnabled(snippetMap.nextSnippetExists());
previousSnippetAction.setEnabled(snippetMap.previousSnippetExists());
}
protected String getCurrentSnippetKey() {
String key = snippetMap.getCurrentSet();
return key != null? key : NO_SNIPPET_SELECTED;
}
protected Snippet getCurrentSnippet() {
return snippetMap.getCurrentSnippet();
}
protected void moveToFirstSnippet() {
Snippet firstSnippet = snippetMap.firstSnippet();
if (firstSnippet != null) {
CodeFileInfo codeFileInfo = codeCache.get(snippetMap.getFileForSnippet(firstSnippet));
scrollToSnippet(codeFileInfo, firstSnippet);
} else {
Toolkit.getDefaultToolkit().beep();
}
}
protected void moveToNextSnippet() {
Snippet nextSnippet = snippetMap.nextSnippet();
if (nextSnippet != null) {
CodeFileInfo codeFileInfo = codeCache.get(snippetMap.getFileForSnippet(nextSnippet));
scrollToSnippet(codeFileInfo, nextSnippet);
} else {
Toolkit.getDefaultToolkit().beep();
}
}
protected void moveToPreviousSnippet() {
Snippet previousSnippet = snippetMap.previousSnippet();
if (previousSnippet != null) {
CodeFileInfo codeFileInfo = codeCache.get(snippetMap.getFileForSnippet(previousSnippet));
scrollToSnippet(codeFileInfo, previousSnippet);
} else {
Toolkit.getDefaultToolkit().beep();
}
}
protected void moveToLastSnippet() {
Snippet lastSnippet = snippetMap.lastSnippet();
if (lastSnippet != null) {
CodeFileInfo codeFileInfo = codeCache.get(snippetMap.getFileForSnippet(lastSnippet));
scrollToSnippet(codeFileInfo, lastSnippet);
} else {
Toolkit.getDefaultToolkit().beep();
}
}
private class SnippetActivator implements ActionListener {
public void actionPerformed(ActionEvent e) {
String snippetKey = (String)snippetComboBox.getSelectedItem();
if (!snippetKey.equals(NO_SNIPPET_SELECTED)) {
logger.log(Level.FINEST, "highlighting new snippet:"+snippetKey+".");
highlightSnippetSet(snippetKey);
} else {
clearAllSnippetHighlights();
}
}
}
private abstract class SnippetAction extends AbstractAction {
public SnippetAction(String name, String shortDescription) {
super(name);
putValue(AbstractAction.SHORT_DESCRIPTION, shortDescription);
}
}
private class FirstSnippetAction extends SnippetAction {
public FirstSnippetAction() {
super("FirstSnippet",
getString("CodeViewer.snippets.navigateFirst",
"move to first code snippet within highlighted set"));
}
public void actionPerformed(ActionEvent e) {
moveToFirstSnippet();
}
}
private class NextSnippetAction extends SnippetAction {
public NextSnippetAction() {
super("NextSnippet",
getString("CodeViewer.snippets.navigateNext",
"move to next code snippet within highlighted set"));
}
@Override
public void actionPerformed(ActionEvent e) {
moveToNextSnippet();
}
}
private class PreviousSnippetAction extends SnippetAction {
public PreviousSnippetAction() {
super("PreviousSnippet",
getString("CodeViewer.snippets.navigatePrevious",
"move to previous code fragment within highlighted set"));
}
@Override
public void actionPerformed(ActionEvent e) {
moveToPreviousSnippet();
}
}
private class LastSnippetAction extends SnippetAction {
public LastSnippetAction() {
super("LastSnippet",
getString("CodeViewer.snippets.navigateLast",
"move to last code snippet within highlighted set"));
}
public void actionPerformed(ActionEvent e) {
moveToLastSnippet();
}
}
private class SnippetCellRenderer implements ListCellRenderer {
private JLabel delegate;
public SnippetCellRenderer(ListCellRenderer delegate) {
this.delegate = (JLabel)delegate;
}
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
JLabel renderer = (JLabel)((ListCellRenderer)delegate).getListCellRendererComponent(list,
value, index, isSelected, cellHasFocus);
int count = snippetMap.getSnippetCountForSet((String)value);
Color foreground = renderer.getForeground();
Color countForeground = Utilities.deriveColorHSB(foreground,
0, 0, isSelected? .5f : .4f);
String text = "<html><font color=\"" +
Utilities.getHTMLColorString(foreground) + "\">" + value +
"</font>" +
"<font color=\"" +
Utilities.getHTMLColorString(countForeground) + "\">" +
(count > 0? " (" + count + (count > 1? " snippets)" : " snippet)") : "") +
"</font></html>";
renderer.setText(text);
return renderer;
}
}
private static class CodeFileInfo {
public URL url;
public String styled;
public HashMap<String, List<Snippet>> snippets = new HashMap<String, List<Snippet>>();
public JEditorPane textPane;
public JPanel veneer;
}
private static class Stacker extends JLayeredPane {
private Component master; // dictates sizing, scrolling
public Stacker(Component master) {
this.master = master;
setLayout(null);
add(master, JLayeredPane.DEFAULT_LAYER);
}
public Dimension getPreferredSize() {
return master.getPreferredSize();
}
public void doLayout() {
// ensure all layers are sized the same
Dimension size = getSize();
Component layers[] = getComponents();
for(Component layer : layers) {
layer.setBounds(0, 0, size.width, size.height);
}
}
}
private class CodeVeneer extends JPanel {
private CodeFileInfo codeFileInfo;
public CodeVeneer(CodeFileInfo codeFileInfo) {
this.codeFileInfo = codeFileInfo;
setOpaque(false);
setLayout(null);
}
@Override
protected void paintComponent(Graphics g) {
String snippetKey = getCurrentSnippetKey();
if (snippetKey != NO_SNIPPET_SELECTED) {
// Count total number of snippets for key
int snippetTotal = 0;
int snippetIndex = 0;
List<Snippet> snippetList = null;
URL files[] = snippetMap.getFilesForSet(snippetKey);
for(URL file : files) {
CodeFileInfo codeFileInfo = codeCache.get(file);
if (this.codeFileInfo == codeFileInfo) {
snippetList = codeFileInfo.snippets.get(snippetKey);
snippetIndex = snippetTotal + 1;
}
snippetTotal += (codeFileInfo.snippets.get(snippetKey).size());
}
if (snippetList != null) {
Snippet currentSnippet = snippetMap.getCurrentSnippet();
CodeFileInfo currentSnippetCodeFileInfo = codeCache.get(
snippetMap.getFileForSnippet(currentSnippet));
Font font = g.getFont();
g.setFont(font.deriveFont(10f));
FontMetrics metrics = g.getFontMetrics();
g.setColor(getHighlightColor());
Graphics2D g2Alpha = null; // cache composite
for(Snippet snippet : snippetList) {
Graphics2D g2 = (Graphics2D)g;
try {
if (currentSnippetCodeFileInfo != codeFileInfo ||
currentSnippet != snippet) {
// if not painting the "current" snippet, then fade the glyph
if (g2Alpha == null) {
// first time, so create composite
g2Alpha = (Graphics2D)g2.create();
g2Alpha.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.6f));
}
g2 = g2Alpha;
}
Rectangle snipRect = codeFileInfo.textPane.modelToView(snippet.startLine);
//String glyphLabel = snippetIndex++ + "/" + snippetTotal;
String glyphLabel = "" + snippetIndex++;
Rectangle labelRect = metrics.getStringBounds(glyphLabel, g2).getBounds();
g2.drawImage(SNIPPET_GLYPH, 0, snipRect.y, this);
g2.setColor(Color.black);
g2.drawString(glyphLabel,
(SNIPPET_GLYPH.getWidth(this) - labelRect.width)/2,
snipRect.y +
(SNIPPET_GLYPH.getHeight(this) - labelRect.height)/2 +
metrics.getAscent());
} catch (BadLocationException e) {
System.err.println(e);
}
}
}
}
}
}
}

51
swingset3/com/sun/swingset3/codeview/Snippet.java

@ -0,0 +1,51 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.codeview;
import javax.swing.text.Document;
/**
*
* @author aim
*/
public class Snippet {
Document document;
String key = null;
int startLine = -1;
int endLine = -1;
public Snippet(Document document, String key, int startLine) {
this.document = document;
this.key = key;
this.startLine = startLine;
}
}

661
swingset3/com/sun/swingset3/codeview/SnippetHighlighter.java

@ -0,0 +1,661 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.codeview;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.*;
import javax.swing.SwingUtilities;
import javax.swing.plaf.TextUI;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.LayeredHighlighter;
import javax.swing.text.Position;
import javax.swing.text.View;
/**
* Implements the Highlighter interfaces. Implements a simple highlight
* painter that renders in a solid color.
*
* @see Highlighter
*/
public class SnippetHighlighter extends LayeredHighlighter {
/**
* Creates a new DefaultHighlighther object.
*/
public SnippetHighlighter() {
drawsLayeredHighlights = true;
}
// ---- Highlighter methods ----------------------------------------------
/**
* Renders the highlights.
*
* @param g the graphics context
*/
public void paint(Graphics g) {
// PENDING(prinz) - should cull ranges not visible
int len = highlights.size();
for (int i = 0; i < len; i++) {
HighlightInfo info = highlights.elementAt(i);
if (!(info instanceof LayeredHighlightInfo)) {
// Avoid allocing unless we need it.
Rectangle a = component.getBounds();
Insets insets = component.getInsets();
a.x = insets.left;
a.y = insets.top;
a.width -= insets.left + insets.right;
a.height -= insets.top + insets.bottom;
for (; i < len; i++) {
info = highlights.elementAt(i);
if (!(info instanceof LayeredHighlightInfo)) {
Highlighter.HighlightPainter p = info.getPainter();
p.paint(g, info.getStartOffset(), info.getEndOffset(),
a, component);
}
}
}
}
}
/**
* Called when the UI is being installed into the
* interface of a JTextComponent. Installs the editor, and
* removes any existing highlights.
*
* @param c the editor component
* @see Highlighter#install
*/
public void install(JTextComponent c) {
component = c;
removeAllHighlights();
}
/**
* Called when the UI is being removed from the interface of
* a JTextComponent.
*
* @param c the component
* @see Highlighter#deinstall
*/
public void deinstall(JTextComponent c) {
component = null;
}
/**
* Adds a highlight to the view. Returns a tag that can be used
* to refer to the highlight.
*
* @param p0 the start offset of the range to highlight >= 0
* @param p1 the end offset of the range to highlight >= p0
* @param p the painter to use to actually render the highlight
* @return an object that can be used as a tag
* to refer to the highlight
* @exception BadLocationException if the specified location is invalid
*/
public Object addHighlight(int p0, int p1, Highlighter.HighlightPainter p) throws BadLocationException {
Document doc = component.getDocument();
HighlightInfo i = (getDrawsLayeredHighlights() &&
(p instanceof LayeredHighlighter.LayerPainter)) ?
new LayeredHighlightInfo() : new HighlightInfo();
i.painter = p;
i.p0 = doc.createPosition(p0);
i.p1 = doc.createPosition(p1);
// For snippets, we want to make sure selection is layered ON TOP
// since we add transparency to the selection color; so rather
// than append the highlight, we insert it in the front.
highlights.insertElementAt(i, 0);
safeDamageRange(p0, p1);
return i;
}
/**
* Removes a highlight from the view.
*
* @param tag the reference to the highlight
*/
public void removeHighlight(Object tag) {
if (tag instanceof LayeredHighlightInfo) {
LayeredHighlightInfo lhi = (LayeredHighlightInfo)tag;
if (lhi.width > 0 && lhi.height > 0) {
component.repaint(lhi.x, lhi.y, lhi.width, lhi.height);
}
}
else {
HighlightInfo info = (HighlightInfo) tag;
safeDamageRange(info.p0, info.p1);
}
highlights.removeElement(tag);
}
/**
* Removes all highlights.
*/
public void removeAllHighlights() {
TextUI mapper = component.getUI();
if (getDrawsLayeredHighlights()) {
int len = highlights.size();
if (len != 0) {
int minX = 0;
int minY = 0;
int maxX = 0;
int maxY = 0;
int p0 = -1;
int p1 = -1;
for (int i = 0; i < len; i++) {
HighlightInfo hi = highlights.elementAt(i);
if (hi instanceof LayeredHighlightInfo) {
LayeredHighlightInfo info = (LayeredHighlightInfo)hi;
minX = Math.min(minX, info.x);
minY = Math.min(minY, info.y);
maxX = Math.max(maxX, info.x + info.width);
maxY = Math.max(maxY, info.y + info.height);
}
else {
if (p0 == -1) {
p0 = hi.p0.getOffset();
p1 = hi.p1.getOffset();
}
else {
p0 = Math.min(p0, hi.p0.getOffset());
p1 = Math.max(p1, hi.p1.getOffset());
}
}
}
if (minX != maxX && minY != maxY) {
component.repaint(minX, minY, maxX - minX, maxY - minY);
}
if (p0 != -1) {
try {
safeDamageRange(p0, p1);
} catch (BadLocationException e) {}
}
highlights.removeAllElements();
}
}
else if (mapper != null) {
int len = highlights.size();
if (len != 0) {
int p0 = Integer.MAX_VALUE;
int p1 = 0;
for (int i = 0; i < len; i++) {
HighlightInfo info = highlights.elementAt(i);
p0 = Math.min(p0, info.p0.getOffset());
p1 = Math.max(p1, info.p1.getOffset());
}
try {
safeDamageRange(p0, p1);
} catch (BadLocationException e) {}
highlights.removeAllElements();
}
}
}
/**
* Changes a highlight.
*
* @param tag the highlight tag
* @param p0 the beginning of the range >= 0
* @param p1 the end of the range >= p0
* @exception BadLocationException if the specified location is invalid
*/
public void changeHighlight(Object tag, int p0, int p1) throws BadLocationException {
Document doc = component.getDocument();
if (tag instanceof LayeredHighlightInfo) {
LayeredHighlightInfo lhi = (LayeredHighlightInfo)tag;
if (lhi.width > 0 && lhi.height > 0) {
component.repaint(lhi.x, lhi.y, lhi.width, lhi.height);
}
// Mark the highlights region as invalid, it will reset itself
// next time asked to paint.
lhi.width = lhi.height = 0;
lhi.p0 = doc.createPosition(p0);
lhi.p1 = doc.createPosition(p1);
safeDamageRange(Math.min(p0, p1), Math.max(p0, p1));
}
else {
HighlightInfo info = (HighlightInfo) tag;
int oldP0 = info.p0.getOffset();
int oldP1 = info.p1.getOffset();
if (p0 == oldP0) {
safeDamageRange(Math.min(oldP1, p1),
Math.max(oldP1, p1));
} else if (p1 == oldP1) {
safeDamageRange(Math.min(p0, oldP0),
Math.max(p0, oldP0));
} else {
safeDamageRange(oldP0, oldP1);
safeDamageRange(p0, p1);
}
info.p0 = doc.createPosition(p0);
info.p1 = doc.createPosition(p1);
}
}
/**
* Makes a copy of the highlights. Does not actually clone each highlight,
* but only makes references to them.
*
* @return the copy
* @see Highlighter#getHighlights
*/
public Highlighter.Highlight[] getHighlights() {
int size = highlights.size();
if (size == 0) {
return noHighlights;
}
Highlighter.Highlight[] h = new Highlighter.Highlight[size];
highlights.copyInto(h);
return h;
}
/**
* When leaf Views (such as LabelView) are rendering they should
* call into this method. If a highlight is in the given region it will
* be drawn immediately.
*
* @param g Graphics used to draw
* @param p0 starting offset of view
* @param p1 ending offset of view
* @param viewBounds Bounds of View
* @param editor JTextComponent
* @param view View instance being rendered
*/
public void paintLayeredHighlights(Graphics g, int p0, int p1,
Shape viewBounds,
JTextComponent editor, View view) {
for (int counter = highlights.size() - 1; counter >= 0; counter--) {
Object tag = highlights.elementAt(counter);
if (tag instanceof LayeredHighlightInfo) {
LayeredHighlightInfo lhi = (LayeredHighlightInfo)tag;
int start = lhi.getStartOffset();
int end = lhi.getEndOffset();
if ((p0 < start && p1 > start) ||
(p0 >= start && p0 < end)) {
lhi.paintLayeredHighlights(g, p0, p1, viewBounds,
editor, view);
}
}
}
}
/**
* Queues damageRange() call into event dispatch thread
* to be sure that views are in consistent state.
*/
private void safeDamageRange(final Position p0, final Position p1) {
safeDamager.damageRange(p0, p1);
}
/**
* Queues damageRange() call into event dispatch thread
* to be sure that views are in consistent state.
*/
private void safeDamageRange(int a0, int a1) throws BadLocationException {
Document doc = component.getDocument();
safeDamageRange(doc.createPosition(a0), doc.createPosition(a1));
}
/**
* If true, highlights are drawn as the Views draw the text. That is
* the Views will call into <code>paintLayeredHighlight</code> which
* will result in a rectangle being drawn before the text is drawn
* (if the offsets are in a highlighted region that is). For this to
* work the painter supplied must be an instance of
* LayeredHighlightPainter.
*/
public void setDrawsLayeredHighlights(boolean newValue) {
drawsLayeredHighlights = newValue;
}
public boolean getDrawsLayeredHighlights() {
return drawsLayeredHighlights;
}
// ---- member variables --------------------------------------------
private final static Highlighter.Highlight[] noHighlights =
new Highlighter.Highlight[0];
private final Vector<HighlightInfo> highlights = new Vector<HighlightInfo>();
private JTextComponent component;
private boolean drawsLayeredHighlights;
private final SafeDamager safeDamager = new SafeDamager();
/**
* Default implementation of LayeredHighlighter.LayerPainter that can
* be used for painting highlights.
* <p>
* As of 1.4 this field is final.
*/
public static LayeredHighlighter.LayerPainter SnippetPainter = new SnippetHighlightPainter(null);
/**
* Simple highlight painter that fills a highlighted area with
* a solid color.
*/
public static class SnippetHighlightPainter extends LayeredHighlighter.LayerPainter {
/**
* Constructs a new highlight painter. If <code>c</code> is null,
* the JTextComponent will be queried for its selection color.
*
* @param c the color for the highlight
*/
public SnippetHighlightPainter(Color c) {
color = c;
}
/**
* Returns the color of the highlight.
*
* @return the color
*/
public Color getColor() {
return color;
}
// --- HighlightPainter methods ---------------------------------------
/**
* Paints a highlight.
*
* @param g the graphics context
* @param offs0 the starting model offset >= 0
* @param offs1 the ending model offset >= offs1
* @param bounds the bounding box for the highlight
* @param c the editor
*/
public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) {
Rectangle alloc = bounds.getBounds();
try {
// --- determine locations ---
TextUI mapper = c.getUI();
Rectangle p0 = mapper.modelToView(c, offs0);
Rectangle p1 = mapper.modelToView(c, offs1);
// --- render ---
Color color = getColor();
if (color == null) {
g.setColor(c.getSelectionColor());
}
else {
g.setColor(color);
}
if (p0.y == p1.y) {
// same line, render a rectangle
Rectangle r = p0.union(p1);
g.fillRect(r.x, r.y, r.width, r.height);
} else {
// different lines
int p0ToMarginWidth = alloc.x + alloc.width - p0.x;
g.fillRect(p0.x, p0.y, p0ToMarginWidth, p0.height);
if ((p0.y + p0.height) != p1.y) {
g.fillRect(alloc.x, p0.y + p0.height, alloc.width,
p1.y - (p0.y + p0.height));
}
g.fillRect(alloc.x, p1.y, (p1.x - alloc.x), p1.height);
}
} catch (BadLocationException e) {
// can't render
}
}
// --- LayerPainter methods ----------------------------
/**
* Paints a portion of a highlight.
*
* @param g the graphics context
* @param offs0 the starting model offset >= 0
* @param offs1 the ending model offset >= offs1
* @param bounds the bounding box of the view, which is not
* necessarily the region to paint.
* @param c the editor
* @param view View painting for
* @return region drawing occured in
*/
public Shape paintLayer(Graphics g, int offs0, int offs1,
Shape bounds, JTextComponent c, View view) {
Color base = getColor();
// use transparency so selection isn't clobbered
Color color = base != null?
new Color(base.getRed(), base.getGreen(), base.getBlue(),
255) : null;
if (color == null) {
g.setColor(c.getSelectionColor());
}
else {
g.setColor(color);
}
if (offs0 == view.getStartOffset() &&
offs1 == view.getEndOffset()) {
// Contained in view, can just use bounds.
Rectangle alloc;
if (bounds instanceof Rectangle) {
alloc = (Rectangle)bounds;
}
else {
alloc = bounds.getBounds();
}
// For CodeViewer Snippet painting, this is the paint block that is called.
// We want to paint the highlight on the full width of the text pane,
// so we only need to do this when the region is the beginning of a new
// line.
//g.fillRect(alloc.x, alloc.y, alloc.width, alloc.height);
g.fillRect(alloc.x, alloc.y, c.getWidth() - alloc.x, alloc.height);
}
else {
// Should only render part of View.
try {
// --- determine locations ---
Shape shape = view.modelToView(offs0, Position.Bias.Forward,
offs1,Position.Bias.Backward,
bounds);
Rectangle r = (shape instanceof Rectangle) ?
(Rectangle)shape : shape.getBounds();
g.fillRect(0, r.y, c.getWidth(), r.height);
return r;
} catch (BadLocationException e) {
// can't render
}
}
// Only if exception
return null;
}
private Color color;
}
private static class HighlightInfo implements Highlighter.Highlight {
public int getStartOffset() {
return p0.getOffset();
}
public int getEndOffset() {
return p1.getOffset();
}
public Highlighter.HighlightPainter getPainter() {
return painter;
}
Position p0;
Position p1;
Highlighter.HighlightPainter painter;
}
/**
* LayeredHighlightPainter is used when a drawsLayeredHighlights is
* true. It maintains a rectangle of the region to paint.
*/
private static class LayeredHighlightInfo extends HighlightInfo {
void union(Shape bounds) {
if (bounds == null)
return;
Rectangle alloc;
if (bounds instanceof Rectangle) {
alloc = (Rectangle)bounds;
}
else {
alloc = bounds.getBounds();
}
if (width == 0 || height == 0) {
x = alloc.x;
y = alloc.y;
width = alloc.width;
height = alloc.height;
}
else {
width = Math.max(x + width, alloc.x + alloc.width);
height = Math.max(y + height, alloc.y + alloc.height);
x = Math.min(x, alloc.x);
width -= x;
y = Math.min(y, alloc.y);
height -= y;
}
}
/**
* Restricts the region based on the receivers offsets and messages
* the painter to paint the region.
*/
void paintLayeredHighlights(Graphics g, int p0, int p1,
Shape viewBounds, JTextComponent editor,
View view) {
int start = getStartOffset();
int end = getEndOffset();
// Restrict the region to what we represent
p0 = Math.max(start, p0);
p1 = Math.min(end, p1);
// Paint the appropriate region using the painter and union
// the effected region with our bounds.
union(((LayeredHighlighter.LayerPainter)painter).paintLayer
(g, p0, p1, viewBounds, editor, view));
}
int x;
int y;
int width;
int height;
}
/**
* This class invokes <code>mapper.damageRange</code> in
* EventDispatchThread. The only one instance per Highlighter
* is cretaed. When a number of ranges should be damaged
* it collects them into queue and damages
* them in consecutive order in <code>run</code>
* call.
*/
class SafeDamager implements Runnable {
private final List<Position> p0 = new ArrayList<Position>();
private final List<Position> p1 = new ArrayList<Position>();
private Document lastDoc = null;
/**
* Executes range(s) damage and cleans range queue.
*/
public synchronized void run() {
if (component != null) {
TextUI mapper = component.getUI();
if (mapper != null && lastDoc == component.getDocument()) {
// the Document should be the same to properly
// display highlights
int len = p0.size();
for (int i = 0; i < len; i++){
mapper.damageRange(component,
p0.get(i).getOffset(),
p1.get(i).getOffset());
}
}
}
p0.clear();
p1.clear();
// release reference
lastDoc = null;
}
/**
* Adds the range to be damaged into the range queue. If the
* range queue is empty (the first call or run() was already
* invoked) then adds this class instance into EventDispatch
* queue.
*
* The method also tracks if the current document changed or
* component is null. In this case it removes all ranges added
* before from range queue.
*/
private synchronized void damageRange(Position pos0, Position pos1) {
if (component == null) {
p0.clear();
lastDoc = null;
return;
}
boolean addToQueue = p0.isEmpty();
Document curDoc = component.getDocument();
if (curDoc != lastDoc) {
if (!p0.isEmpty()) {
p0.clear();
p1.clear();
}
lastDoc = curDoc;
}
p0.add(pos0);
p1.add(pos1);
if (addToQueue) {
SwingUtilities.invokeLater(this);
}
}
}
}

339
swingset3/com/sun/swingset3/codeview/SnippetMap.java

@ -0,0 +1,339 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.codeview;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.net.URL;
import java.util.*;
/**
* Data structure to support maintaining Snippet information across a
* set of source code files:
*
* SnippetMap
* |
* ---------------------------------------
* | | |
* snippet key "A" Snippet key "B" Snippet key "C"
* | | |
* ---------------- ------ -------------
* | | | |
* File1.java File3.java File2.java File3.java
* | | | |
* ---------- --- --- -----
* | | | | |
* snipA-1 snipA-2 snipA-3 snipB-1 snipC-1
*
*
* This class also maintains a pointer to a &quot;current&quot; snippet within
* a selected set.
*
*
* @author aim
*/
public class SnippetMap {
private final HashMap<String, List<FileSnippets>> snippetSets = new HashMap<String, List<FileSnippets>>();
private String currentKey;
private List<FileSnippets> currentSet;
private FileSnippets currentFileSnippets;
private int currentFileSnippetsIndex;
private int currentSnippetIndex;
private Snippet currentSnippet;
private PropertyChangeSupport pcs;
/** Creates a new instance of SnippetMap */
public SnippetMap() {
pcs = new PropertyChangeSupport(this);
}
public void addPropertyChangeListener(PropertyChangeListener pcl) {
pcs.addPropertyChangeListener(pcl);
}
public void add(String key, URL codeFile, Snippet snippet) {
List<FileSnippets> fileSnippetList = snippetSets.get(key);
if (fileSnippetList == null) {
// new key! so create new set...
fileSnippetList = new ArrayList<FileSnippets>();
snippetSets.put(key, fileSnippetList);
}
FileSnippets fileSnippets = findFileSnippetsForFile(fileSnippetList, codeFile);
if (fileSnippets == null) {
// found first snippet in this file
fileSnippets = new FileSnippets(key, codeFile);
fileSnippetList.add(fileSnippets);
}
if (!fileSnippets.snippets.contains(snippet)) {
fileSnippets.snippets.add(snippet);
}
}
public Set<String> keySet() {
return snippetSets.keySet();
}
public int getSnippetCountForSet(String key) {
int count = 0;
URL files[] = getFilesForSet(key);
for(URL file : files) {
Snippet snippets[] = getSnippetsForFile(key, file);
count += snippets.length;
}
return count;
}
public URL[] getFilesForSet(String key) {
List<FileSnippets> fileSnippetList = snippetSets.get(key);
URL files[];
if (fileSnippetList != null) {
files = new URL[fileSnippetList.size()];
int i = 0;
for(FileSnippets fileSnippets : fileSnippetList) {
files[i++] = fileSnippets.file;
}
} else {
files = new URL[0];
}
return files;
}
public Snippet[] getSnippetsForFile(String key, URL file) {
List<FileSnippets> fileSnippetList = snippetSets.get(key);
FileSnippets fileSnippets = findFileSnippetsForFile(fileSnippetList, file);
if (fileSnippets != null) {
if (fileSnippets.snippets != null) {
return fileSnippets.snippets.toArray(new Snippet[0]);
}
}
return new Snippet[0];
}
public int getIndexForSnippet(Snippet snippet) {
List<FileSnippets> fileSnippetList = snippetSets.get(snippet.key);
if (fileSnippetList != null) {
int index = 1;
for(FileSnippets fileSnippets : fileSnippetList) {
for(Snippet snippetInFile : fileSnippets.snippets) {
if (snippetInFile == snippet) {
return index;
} else {
index++;
}
}
}
}
return -1;
}
public URL getFileForSnippet(Snippet snippet) {
List<FileSnippets> fileSnippetList = snippetSets.get(snippet.key);
if (fileSnippetList != null) {
for(FileSnippets fileSnippets : fileSnippetList) {
for(Snippet snippetInFile : fileSnippets.snippets) {
if (snippetInFile == snippet) {
return fileSnippets.file;
}
}
}
}
return null;
}
public boolean isEmpty() {
return snippetSets.isEmpty();
}
public int getSize() {
return snippetSets.size();
}
public void clear() {
snippetSets.clear();
setCurrentSnippet(null);
setCurrentSet(null);
}
public void setCurrentSet(String key) {
String oldKey = currentKey;
if (key == null) {
// current snippet being cleared
currentKey = null;
currentSet = null;
currentFileSnippets = null;
currentFileSnippetsIndex = -1;
currentSnippetIndex = -1;
} else {
List<FileSnippets> fileSnippetList = snippetSets.get(key);
if (fileSnippetList == null) {
throw new IllegalArgumentException("snippet key " + key + " does not exist.");
}
currentKey = key;
currentSet = fileSnippetList;
currentFileSnippetsIndex = 0;
currentFileSnippets = currentSet.get(currentFileSnippetsIndex);
currentSnippetIndex = 0;
currentSnippet = currentFileSnippets.snippets.get(currentSnippetIndex);
}
pcs.firePropertyChange("currentSet", oldKey, currentKey);
pcs.firePropertyChange("currentSnippet", null, currentSnippet);
}
public String getCurrentSet() {
return currentKey;
}
public Snippet getCurrentSnippet() {
return currentSnippet;
}
protected void setCurrentSnippet(Snippet snippet) {
Snippet oldCurrentSnippet = currentSnippet;
currentSnippet = snippet;
pcs.firePropertyChange("currentSnippet", oldCurrentSnippet, snippet);
}
public Snippet firstSnippet() {
if (currentKey != null) {
currentFileSnippetsIndex = 0;
currentFileSnippets = currentSet.get(currentFileSnippetsIndex);
currentSnippetIndex = 0;
Snippet firstSnippet = currentFileSnippets.snippets.get(currentSnippetIndex);
setCurrentSnippet(firstSnippet);
return getCurrentSnippet();
}
return null;
}
public boolean nextSnippetExists() {
if (currentKey != null) {
if (currentSnippetIndex+1 < currentFileSnippets.snippets.size()) {
// There is a next snippet in the current file
return true;
}
if (currentFileSnippetsIndex+1 < currentSet.size()) {
// There is another file containing the next snippet
return true;
}
}
return false;
}
public Snippet nextSnippet() {
if (currentKey != null) {
if (currentSnippetIndex+1 < currentFileSnippets.snippets.size()) {
// There is a next snippet in the current file
setCurrentSnippet(currentFileSnippets.snippets.get(++currentSnippetIndex));
return getCurrentSnippet();
}
if (currentFileSnippetsIndex+1 < currentSet.size()) {
// The next snippet is contained in the next file
currentFileSnippets = currentSet.get(++currentFileSnippetsIndex);
currentSnippetIndex = 0;
setCurrentSnippet(currentFileSnippets.snippets.get(currentSnippetIndex));
return getCurrentSnippet();
}
}
return null;
}
public boolean previousSnippetExists() {
if (currentKey != null) {
if (currentSnippetIndex-1 >= 0) {
// There is a previous snippet in the current file
return true;
}
if (currentFileSnippetsIndex-1 >= 0) {
// There is a previous file containing the previous snippet
return true;
}
}
return false;
}
public Snippet previousSnippet() {
if (currentKey != null) {
if (currentSnippetIndex-1 >= 0) {
// There is a previous snippet in the current file
setCurrentSnippet(currentFileSnippets.snippets.get(--currentSnippetIndex));
return getCurrentSnippet();
}
if (currentFileSnippetsIndex-1 >= 0) {
// The previous snippet is contained in the previous file
currentFileSnippets = currentSet.get(--currentFileSnippetsIndex);
currentSnippetIndex = currentFileSnippets.snippets.size() - 1;
setCurrentSnippet(currentFileSnippets.snippets.get(currentSnippetIndex));
return getCurrentSnippet();
}
}
return null;
}
public Snippet lastSnippet() {
if (currentKey != null) {
currentFileSnippetsIndex = currentSet.size() - 1;
currentFileSnippets = currentSet.get(currentFileSnippetsIndex);
currentSnippetIndex = currentFileSnippets.snippets.size() - 1;
setCurrentSnippet(currentFileSnippets.snippets.get(currentSnippetIndex));
return getCurrentSnippet();
}
return null;
}
private static FileSnippets findFileSnippetsForFile(List<FileSnippets> fileSnippetList, URL file) {
for(FileSnippets fileSnippets : fileSnippetList) {
if (fileSnippets.file == file) {
return fileSnippets;
}
}
return null;
}
// data structure for keeping track of a particular snippet set's snippets within one file'
private static class FileSnippets {
public final String key;
public final URL file;
public final ArrayList<Snippet> snippets;
public FileSnippets(String key, URL file) {
this.key = key;
this.file = file;
snippets = new ArrayList<Snippet>();
}
}
}

322
swingset3/com/sun/swingset3/codeview/SnippetNavigator.java

@ -0,0 +1,322 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.codeview;
import com.sun.swingset3.utilities.ArrowIcon;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.Border;
import org.jdesktop.swingx.graphics.GraphicsUtilities;
/**
*
* @author Amy Fowler
*/
// This is more complicated thn it needs to be because it was an attempt to
// create a seamless control where the label was integrated into the buttons;
// this integration is temporarily turned off due to visual problems with focus
// and enabled state of the buttons
public class SnippetNavigator extends JPanel {
private String NO_SNIPPET;
private SnippetMap snippetMap;
private JLabel statusLabel;
private JButton prevButton;
private JButton nextButton;
private int arrowSize = 8;
private int overlap = 0;
private int labelPad = 6;
private boolean needLabelBorder = true;
public SnippetNavigator(SnippetMap snippetMap) {
this.snippetMap = snippetMap;
snippetMap.addPropertyChangeListener(new SnippetHighlightListener());
setLayout(null);
NO_SNIPPET = getString("CodeViewer.snippets.noCodeHighlighted",
"No Code highlight selected");
statusLabel = new JLabel(NO_SNIPPET);
statusLabel.setHorizontalAlignment(JLabel.CENTER);
add(statusLabel);
prevButton = (JButton) add(new NavButton());
prevButton.setDefaultCapable(false);
prevButton.setVisible(false);
nextButton = (JButton) add(new NavButton());
nextButton.setDefaultCapable(false);
nextButton.setVisible(false);
applyDefaults();
}
protected String getString(String key, String fallback) {
String value = fallback;
String bundleName = getClass().getPackage().getName()+".resources.CodeViewer";
ResourceBundle bundle = ResourceBundle.getBundle(bundleName);
try {
value = bundle != null? bundle.getString(key) : fallback;
} catch (MissingResourceException e) {
CodeViewer.logger.log(Level.WARNING, "missing String resource " + key +
"; using fallback \"" +fallback + "\"");
}
return value;
}
@Override
public void doLayout() {
Dimension size = getSize();
Insets insets = getInsets();
Dimension labelSize = statusLabel.getPreferredSize();
if (prevButton.isVisible()) {
if (needLabelBorder) {
matchLabelBorderToButtons();
}
Dimension buttonSize = prevButton.getPreferredSize();
prevButton.setBounds(insets.left, insets.top,
buttonSize.width, size.height - insets.top - insets.bottom);
statusLabel.setBounds(insets.left + buttonSize.width - overlap,
insets.top,
labelSize.width + (2 * overlap) + labelPad,
size.height - insets.top - insets.bottom);
nextButton.setBounds(size.width - buttonSize.width,
insets.top,
buttonSize.width, size.height - insets.top - insets.bottom);
} else {
statusLabel.setBounds(insets.left, insets.top,
size.width - insets.left - insets.right,
size.height - insets.top - insets.bottom);
}
}
@Override
public Dimension getPreferredSize() {
Dimension prefSize;
Insets insets = getInsets();
Dimension buttonSize = prevButton.getPreferredSize();
Dimension labelSize = statusLabel.getPreferredSize();
if (prevButton.isVisible()) {
prefSize = new Dimension(buttonSize.width * 2 + labelSize.width +
labelPad +
insets.left + insets.right,
buttonSize.height + insets.top + insets.bottom);
} else {
prefSize = new Dimension(labelSize.width + insets.left + insets.right,
buttonSize.height + insets.top + insets.bottom);
}
return prefSize;
}
@Override
public void updateUI() {
super.updateUI();
applyDefaults();
}
protected void applyDefaults() {
if (prevButton != null) {
Color arrowColor = UIManager.getColor("Label.foreground");
Color inactiveColor = UIManager.getColor("Label.disabledText");
Dimension buttonSize = new Dimension(arrowSize + 12 + overlap,
arrowSize + 12);
prevButton.setIcon(new ArrowIcon(ArrowIcon.WEST, arrowSize, arrowColor));
prevButton.setDisabledIcon(new ArrowIcon(ArrowIcon.WEST, arrowSize, inactiveColor));
prevButton.setPreferredSize(buttonSize);
nextButton.setIcon(new ArrowIcon(ArrowIcon.EAST, arrowSize, arrowColor));
nextButton.setDisabledIcon(new ArrowIcon(ArrowIcon.EAST, arrowSize, inactiveColor));
nextButton.setPreferredSize(buttonSize);
statusLabel.setOpaque(true);
statusLabel.setFont(UIManager.getFont("Label.font").deriveFont(12f));
//needLabelBorder = true;
needLabelBorder = false;
}
}
// this doesn't get called because label integration is disabled
private void matchLabelBorderToButtons() {
Insets insets = new Insets(4, 6, 4, 6);
Dimension buttonSize = prevButton.getPreferredSize();
prevButton.setSize(buttonSize);
BufferedImage image = GraphicsUtilities.
createCompatibleTranslucentImage(
buttonSize.width, buttonSize.height);
prevButton.paint(image.getGraphics());
BufferedImage labelTopImage = GraphicsUtilities.
createCompatibleTranslucentImage(
buttonSize.width - insets.left - insets.right,
insets.top);
labelTopImage.getGraphics().drawImage(image, 0, 0,
buttonSize.width - insets.left - insets.right,
insets.top,
insets.left, 0,
buttonSize.width - insets.right, insets.top,
null,
null);
BufferedImage labelBottomImage = GraphicsUtilities.createCompatibleTranslucentImage(buttonSize.width - insets.left - insets.right,
insets.bottom);
labelBottomImage.getGraphics().drawImage(image, 0, 0,
buttonSize.width - insets.left - insets.right, insets.top,
insets.left, buttonSize.height - insets.bottom,
buttonSize.width - insets.right, buttonSize.height,
null,
null);
statusLabel.setBorder(new CenterLabelBorder(labelTopImage, labelBottomImage));
needLabelBorder = false;
}
public void setNavigatePreviousAction(Action action) {
setButtonAction(prevButton, action);
}
public void setNavigateNextAction(Action action) {
setButtonAction(nextButton, action);
}
private void setButtonAction(JButton button, Action action) {
Icon icon = button.getIcon();
button.setAction(action);
button.setHideActionText(true);
button.setIcon(icon); // icon gets obliterated when action set!
}
private class SnippetHighlightListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if (propertyName.equals("currentSet")) {
String key = (String) e.getNewValue();
setComponentState(key);
} else if (propertyName.equals("currentSnippet")) {
setComponentState(snippetMap.getCurrentSet());
}
}
private void setComponentState(String currentKey) {
if (currentKey == null) {
statusLabel.setText(NO_SNIPPET);
} else {
String place = "<html><b>" +
snippetMap.getIndexForSnippet(snippetMap.getCurrentSnippet()) +
"</b>" +
" of " + snippetMap.getSnippetCountForSet(currentKey) + "</html>";
statusLabel.setText(place);
}
boolean moreThanOne = snippetMap.getSnippetCountForSet(currentKey) > 1;
prevButton.setVisible(moreThanOne);
nextButton.setVisible(moreThanOne);
}
}
private class NavButton extends JButton {
public NavButton() {
super();
}
protected void paintComponent(Graphics g) {
// need to make sure overlapping label paints after buttons otherwise
// the buttons paint over the label when they gain focus (which is really
// a Swing bug, as the clip should be properly set based on zorder
// within the container)
super.paintComponent(g);
statusLabel.repaint();
}
}
private class CenterLabelBorder implements Border {
private Image topImage;
private Image bottomImage;
public CenterLabelBorder(Image topImage, Image bottomImage) {
this.topImage = topImage;
this.bottomImage = bottomImage;
}
public Insets getBorderInsets(Component c) {
return new Insets(topImage.getHeight(null),
0, bottomImage.getHeight(null), 0);
}
public boolean isBorderOpaque() {
return false;
}
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
if (prevButton.isVisible()) {
int xx = x;
int imageWidth = topImage.getWidth(c);
while (xx < x + w) {
g.drawImage(topImage, xx, y, c);
xx += imageWidth;
}
xx = x;
imageWidth = bottomImage.getWidth(c);
while (xx < x + w) {
g.drawImage(bottomImage, xx, y + h - bottomImage.getHeight(c), c);
xx += imageWidth;
}
}
}
}
}

143
swingset3/com/sun/swingset3/codeview/SnippetParser.java

@ -0,0 +1,143 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.codeview;
import java.text.CharacterIterator;
import java.util.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Segment;
/**
* Parses a source code document, looking for blocks of code
* bracketed by comments including start and ending &quot;snippet&quot; markers.
*
* @author aim
*/
public class SnippetParser {
private final static String START_MARKER = "<snip>";
private final static String END_MARKER = "</snip>";
protected SnippetParser() {
// never instantiate
}
public static HashMap<String,List<Snippet>> parse(Document document) {
return parse(document, START_MARKER, END_MARKER);
}
private static HashMap<String,List<Snippet>> parse(Document document,
String startMarker, String endMarker) {
HashMap<String,List<Snippet>> snippetMap = new HashMap<String,List<Snippet>>();
Stack<Snippet> stack = new Stack<Snippet>(); // snippets may be nested
char startMarkerChars[] = startMarker.toCharArray();
char endMarkerChars[] = endMarker.toCharArray();
int nleft = document.getLength();
Segment segment = new Segment();
int offset = 0;
int lineStart = 0;
int charCount = 0;
int startMarkerIndex = 0;
int endMarkerIndex = 0;
StringBuffer keyBuf = new StringBuffer();
segment.setPartialReturn(true);
try {
while (nleft > 0) {
document.getText(offset, nleft, segment);
for(char c = segment.first(); c != CharacterIterator.DONE;
c = segment.next()) {
if (!stack.isEmpty()) {
// already found a begin marker, so looking for end marker
if (c == endMarkerChars[endMarkerIndex]) {
endMarkerIndex++;
if (endMarkerIndex == endMarkerChars.length) {
// found end marker, so register snippet
Snippet snippet = stack.pop();
if (snippet.key.equals("tempkey")) {
// haven't stored key yet
snippet.key = keyBuf.toString().trim();
}
snippet.endLine = charCount + 1;
List<Snippet> snippetList = snippetMap.get(snippet.key);
if (snippetList == null) {
snippetList = new ArrayList<Snippet>();
snippetMap.put(snippet.key, snippetList);
}
snippetList.add(snippet);
endMarkerIndex = 0;
}
} else {
endMarkerIndex = 0;
if (stack.peek().startLine == lineStart){
// build snippet key
keyBuf.append(c);
}
}
}
if (c == startMarkerChars[startMarkerIndex]) {
startMarkerIndex++;
if (startMarkerIndex == startMarkerChars.length) {
// found new begin marker
if (!stack.isEmpty()) {
// nested snippet, save previous key before pushing new one
Snippet snippet = stack.peek();
snippet.key = keyBuf.toString().trim();
}
stack.push(new Snippet(document, "tempkey", lineStart));
keyBuf.setLength(0);
startMarkerIndex = 0;
}
} else {
startMarkerIndex = 0;
}
charCount++;
if (c == '\n') {
lineStart = charCount;
}
}
nleft -= segment.count;
offset += segment.count;
}
} catch (BadLocationException e) {
System.err.println(e);
}
return snippetMap;
}
}

16
swingset3/com/sun/swingset3/codeview/resources/CodeViewer.properties

@ -0,0 +1,16 @@
# CodeViewer ResourceBundle properties file
CodeViewer.images=Images
CodeViewer.noCodeLoaded=no code loaded
CodeViewer.noCodeAvailable=no code available
CodeViewer.snippets.highlightCode=Highlight code to:
CodeViewer.snippets.selectOne=Select One
CodeViewer.snippets.navigateFirst=move to first code snippet within highlighted set
CodeViewer.snippets.navigateNext=move to next code snippet within highlighted set
CodeViewer.snippets.navigatePrevious=move to previous code fragment within highlighted set
CodeViewer.snippets.navigateLast=move to last code snippet within highlighted set
CodeViewer.snippets.noCodeHighlighted=No highlight selected

BIN
swingset3/com/sun/swingset3/codeview/resources/images/snippetglyph.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
swingset3/com/sun/swingset3/codeview/resources/images/snippetglyph.psd

Binary file not shown.

129
swingset3/com/sun/swingset3/demos/DemoUtilities.java

@ -0,0 +1,129 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.demos;
import java.awt.*;
import java.net.URI;
import java.io.IOException;
import javax.swing.*;
import javax.jnlp.*;
/**
* @author Pavel Porvatov
*/
public class DemoUtilities {
private DemoUtilities() {
// Hide constructor
}
public static void setToplevelLocation(Window toplevel, Component component,
int relativePosition) {
Rectangle compBounds = component.getBounds();
// Convert component location to screen coordinates
Point p = new Point();
SwingUtilities.convertPointToScreen(p, component);
int x;
int y;
// Set frame location to be centered on panel
switch (relativePosition) {
case SwingConstants.NORTH: {
x = (p.x + (compBounds.width / 2)) - (toplevel.getWidth() / 2);
y = p.y - toplevel.getHeight();
break;
}
case SwingConstants.EAST: {
x = p.x + compBounds.width;
y = (p.y + (compBounds.height / 2)) - (toplevel.getHeight() / 2);
break;
}
case SwingConstants.SOUTH: {
x = (p.x + (compBounds.width / 2)) - (toplevel.getWidth() / 2);
y = p.y + compBounds.height;
break;
}
case SwingConstants.WEST: {
x = p.x - toplevel.getWidth();
y = (p.y + (compBounds.height / 2)) - (toplevel.getHeight() / 2);
break;
}
case SwingConstants.NORTH_EAST: {
x = p.x + compBounds.width;
y = p.y - toplevel.getHeight();
break;
}
case SwingConstants.NORTH_WEST: {
x = p.x - toplevel.getWidth();
y = p.y - toplevel.getHeight();
break;
}
case SwingConstants.SOUTH_EAST: {
x = p.x + compBounds.width;
y = p.y + compBounds.height;
break;
}
case SwingConstants.SOUTH_WEST: {
x = p.x - toplevel.getWidth();
y = p.y + compBounds.height;
break;
}
default:
case SwingConstants.CENTER: {
x = (p.x + (compBounds.width / 2)) - (toplevel.getWidth() / 2);
y = (p.y + (compBounds.height / 2)) - (toplevel.getHeight() / 2);
}
}
toplevel.setLocation(x, y);
}
public static boolean browse(URI uri) throws IOException, UnavailableServiceException {
// Try using the Desktop api first
try {
Desktop desktop = Desktop.getDesktop();
desktop.browse(uri);
return true;
} catch (SecurityException e) {
// Running in sandbox, try using WebStart service
BasicService basicService =
(BasicService) ServiceManager.lookup("javax.jnlp.BasicService");
if (basicService.isWebBrowserSupported()) {
return basicService.showDocument(uri.toURL());
}
}
return false;
}
}

238
swingset3/com/sun/swingset3/demos/JGridPanel.java

@ -0,0 +1,238 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.demos;
import java.awt.*;
import javax.swing.*;
/**
* JGridPanel
*
* @author Pavel Porvatov
*/
public class JGridPanel extends JPanel {
public static final int DEFAULT_GAP = 5;
public enum Layout {
FIRST,
CENTER,
LAST,
FILL
}
private enum ComponentType {
NO_RESIZABLE,
HORIZONTAL_FILL,
FULL
}
private final int cols;
private int bigCol = -1;
private int bigRow = -1;
private int vGap = -1;
private int hGap = -1;
public JGridPanel(int cols) {
this(cols, -1, -1);
}
public JGridPanel(int cols, int bigCol) {
this(cols, bigCol, -1);
}
public JGridPanel(int cols, int bigCol, int bigRow) {
super(new GridBagLayout());
assert cols > 0;
assert bigCol >= -1 && bigCol < cols;
assert bigRow >= -1;
this.cols = cols;
this.bigCol = bigCol;
this.bigRow = bigRow;
}
public void setVGap(int vGap) {
this.vGap = vGap;
}
public void setHGap(int hGap) {
this.hGap = hGap;
}
public JGridPanel cell() {
return cell(null, getHLayout(null), getVLayout(null), null);
}
public JGridPanel cell(Component component) {
return cell(component, getHLayout(component), getVLayout(component), null);
}
public JGridPanel cell(Component component, Layout hLayout) {
return cell(component, hLayout, getVLayout(component), null);
}
public JGridPanel cell(Component component, Layout hLayout, Layout vLayout) {
return cell(component, hLayout, vLayout, null);
}
public JGridPanel cell(Component component, Insets insets) {
assert insets != null;
return cell(component, getHLayout(component), getVLayout(component), insets);
}
private JGridPanel cell(Component component, Layout hLayout, Layout vLayout, Insets insets) {
int componentCount = getComponentCount();
int x = componentCount % cols;
int y = componentCount / cols;
int weightx = x == bigCol || (bigCol < 0 && hLayout == Layout.FILL) ? 1 : 0;
int weighty = y == bigRow || (bigRow < 0 && vLayout == Layout.FILL) ? 1 : 0;
if (insets == null) {
int topGap = y == 0 ? 0 : vGap;
int leftGap = x == 0 ? 0 : hGap;
insets = new Insets(topGap < 0 ? DEFAULT_GAP : topGap,
leftGap < 0 ? DEFAULT_GAP : leftGap, 0, 0);
}
add(component == null ? createSeparator() : component,
new GridBagConstraints(x, y,
1, 1,
weightx, weighty,
getAnchor(hLayout, vLayout), getFill(hLayout, vLayout),
insets, 0, 0));
return this;
}
public void setComponent(Component component, int col, int row) {
assert col >= 0 && col < cols;
assert row >= 0;
GridBagLayout layout = (GridBagLayout) getLayout();
for (int i = 0; i < getComponentCount(); i++) {
Component oldComponent = getComponent(i);
GridBagConstraints constraints = layout.getConstraints(oldComponent);
if (constraints.gridx == col && constraints.gridy == row) {
remove(i);
add(component == null ? createSeparator() : component, constraints);
validate();
repaint();
return;
}
}
// Cell not found
assert false;
}
private static JComponent createSeparator() {
return new JLabel();
}
private static int getFill(Layout hLayout, Layout vLayout) {
if (hLayout == Layout.FILL) {
return vLayout == Layout.FILL ? GridBagConstraints.BOTH : GridBagConstraints.HORIZONTAL;
}
return vLayout == Layout.FILL ? GridBagConstraints.VERTICAL : GridBagConstraints.NONE;
}
private static ComponentType getComponentType(Component component) {
if (component == null ||
component instanceof JLabel ||
component instanceof JRadioButton ||
component instanceof JCheckBox ||
component instanceof JButton) {
return ComponentType.NO_RESIZABLE;
}
if (component instanceof JComboBox ||
component instanceof JTextField) {
return ComponentType.HORIZONTAL_FILL;
}
return ComponentType.FULL;
}
private static Layout getHLayout(Component component) {
if (getComponentType(component) == ComponentType.NO_RESIZABLE) {
return Layout.FIRST;
} else {
return Layout.FILL;
}
}
private static Layout getVLayout(Component component) {
if (getComponentType(component) == ComponentType.FULL) {
return Layout.FILL;
} else {
return Layout.CENTER;
}
}
private static final int[][] ANCHORS = new int[][]{
{GridBagConstraints.NORTHWEST, GridBagConstraints.NORTH, GridBagConstraints.NORTHEAST},
{GridBagConstraints.WEST, GridBagConstraints.CENTER, GridBagConstraints.EAST},
{GridBagConstraints.SOUTHWEST, GridBagConstraints.SOUTH, GridBagConstraints.SOUTHEAST}
};
private static int getAnchorIndex(Layout layout) {
if (layout == Layout.CENTER) {
return 1;
} else if (layout == Layout.LAST) {
return 2;
} else {
return 0;
}
}
private static int getAnchor(Layout hLayout, Layout vLayout) {
return ANCHORS[getAnchorIndex(vLayout)][getAnchorIndex(hLayout)];
}
public void setBorderEqual(int border) {
setBorder(BorderFactory.createEmptyBorder(border, border, border, border));
}
}

244
swingset3/com/sun/swingset3/demos/JHyperlink.java

@ -0,0 +1,244 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.demos;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.net.URI;
import java.net.URISyntaxException;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
*
* @author aim
*/
//<snip>Create HTML hyperlink
//<snip>Create HTML image hyperlink
public class JHyperlink extends JButton {
private static final BrowseAction defaultBrowseAction = new BrowseAction();
private URI targetURI;
private boolean visited;
private final transient Rectangle viewRect = new Rectangle();
private final transient Rectangle iconRect = new Rectangle();
private final transient Rectangle textRect = new Rectangle();
//remind(aim): lookup colors instead of hardcoding them
private Color normalForeground;
private Color activeForeground;
private Color visitedForeground;
private boolean drawUnderline = true;
static {
UIManager.put("Hyperlink.foreground", Color.blue);
UIManager.put("Hyperlink.activeForeground", Color.red);
UIManager.put("Hyperlink.visitedForeground", new Color(85, 145, 90));
}
/**
* Creates a new instance of JHyperlink
*/
public JHyperlink() {
super();
normalForeground = UIManager.getColor("Hyperlink.foreground");
activeForeground = UIManager.getColor("Hyperlink.activeForeground");
visitedForeground = UIManager.getColor("Hyperlink.visitedForeground");
setBorderPainted(false);
setContentAreaFilled(false);
setForeground(normalForeground);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
setMargin(new Insets(0,0,0,0));
setAction(defaultBrowseAction);
}
/**
* Creates a new instance of JHyperlink
*/
public JHyperlink(String text) {
this();
setText(text); // override the inheritence of the action's name
}
public JHyperlink(String text, String targetURI) throws URISyntaxException {
this(text, new URI(targetURI));
}
public JHyperlink(String text, URI target) {
this(text);
setTarget(target);
}
public JHyperlink(String text, Action action) {
this(text);
setAction(action); // replaces default browse action
setText(text); // override the inheritence of the action's name
}
public JHyperlink(String text, Icon icon) {
this(text);
setIcon(icon);
}
public JHyperlink(Icon icon, String targetURI) throws URISyntaxException {
this(null, icon, targetURI);
}
public JHyperlink(String text, Icon icon, String targetURI) throws URISyntaxException {
this(text, new URI(targetURI));
setIcon(icon);
}
public JHyperlink(String text, Icon icon, URI target) {
this(text);
setIcon(icon);
setTarget(target);
}
public void setTarget(URI target) {
this.targetURI = target;
setToolTipText(target.toASCIIString());
}
public URI getTarget() {
return targetURI;
}
public void setVisited(boolean visited) {
this.visited = visited;
}
public boolean isVisited() {
return visited;
}
@Override
public void setForeground(Color foreground) {
normalForeground = foreground;
super.setForeground(foreground);
}
public void setVisitedForeground(Color visited) {
visitedForeground = visited;
}
public void setDrawUnderline(boolean drawUnderline) {
this.drawUnderline = drawUnderline;
}
public boolean getDrawUnderline() {
return drawUnderline;
}
@Override
protected void paintComponent(Graphics g) {
// Set the foreground on the fly to ensure the text is painted
// with the proper color in super.paintComponent
ButtonModel model = getModel();
if (model.isArmed()) {
super.setForeground(activeForeground);
} else if (visited) {
super.setForeground(visitedForeground);
} else {
super.setForeground(normalForeground);
}
super.paintComponent(g);
if (drawUnderline) {
Insets insets = getInsets();
viewRect.x = insets.left;
viewRect.y = insets.top;
viewRect.width = getWidth() - insets.left - insets.right;
viewRect.height = getHeight() - insets.top - insets.bottom;
int baseline = getBaseline(viewRect.width, viewRect.height);
iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
textRect.x = textRect.y = textRect.width = textRect.height = 0;
SwingUtilities.layoutCompoundLabel(g.getFontMetrics(), getText(),
getIcon(), getVerticalAlignment(), getHorizontalAlignment(),
getVerticalTextPosition(), getHorizontalTextPosition(),
viewRect, iconRect, textRect, getIconTextGap());
// getBaseline not returning correct results, so workaround for now
if (UIManager.getLookAndFeel().getName().equals("Nimbus")) {
baseline += 7;
} else {
baseline += 3;
}
g.setColor(getForeground());
g.drawLine(textRect.x,
baseline,
textRect.x + textRect.width,
baseline);
}
}
// This action is stateless and hence can be shared across hyperlinks
private static class BrowseAction extends AbstractAction {
public BrowseAction() {
super();
}
public void actionPerformed(ActionEvent e) {
JHyperlink hyperlink = (JHyperlink)e.getSource();
URI targetURI = hyperlink.getTarget();
if (targetURI != null) {
try {
DemoUtilities.browse(targetURI);
hyperlink.setVisited(true);
} catch (Exception ex) {
ex.printStackTrace();
System.err.println(ex);
}
}
}
}
//</snip>
//</snip>
}

84
swingset3/com/sun/swingset3/demos/ResourceManager.java

@ -0,0 +1,84 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.demos;
import java.net.URL;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
/**
* @author Pavel Porvatov
*/
public class ResourceManager {
private static final Logger logger = Logger.getLogger(ResourceManager.class.getName());
private final Class demoClass;
// Resource bundle for internationalized and accessible text
private ResourceBundle bundle = null;
public ResourceManager(Class demoClass) {
this.demoClass = demoClass;
String bundleName = demoClass.getPackage().getName() + ".resources." + demoClass.getSimpleName();
try {
bundle = ResourceBundle.getBundle(bundleName);
} catch (MissingResourceException e) {
logger.log(Level.SEVERE, "Couldn't load bundle: " + bundleName);
}
}
public String getString(String key) {
return bundle != null ? bundle.getString(key) : key;
}
public char getMnemonic(String key) {
return (getString(key)).charAt(0);
}
public ImageIcon createImageIcon(String filename, String description) {
String path = "resources/images/" + filename;
URL imageURL = demoClass.getResource(path);
if (imageURL == null) {
logger.log(Level.SEVERE, "unable to access image file: " + path);
return null;
} else {
return new ImageIcon(imageURL, description);
}
}
}

132
swingset3/com/sun/swingset3/demos/Stacker.java

@ -0,0 +1,132 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.demos;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.timing.interpolation.PropertySetter;
import org.jdesktop.swingx.JXPanel;
/**
* Container class which extends JLayeredPane to ensure its sizing
* tracks its "master" child component and supported fading a message
* component in/out of the top layer
* @author Amy Fowler
*/
public class Stacker extends JLayeredPane {
private Component master; // dictates sizing, scrolling
private JPanel messageLayer;
private JXPanel messageAlpha;
public Stacker(Component master) {
this.master = master;
setLayout(null);
add(master, JLayeredPane.DEFAULT_LAYER);
}
@Override
public Dimension getPreferredSize() {
return master.getPreferredSize();
}
@Override
public void doLayout() {
// ensure all layers are sized the same
Dimension size = getSize();
Component layers[] = getComponents();
for (Component layer : layers) {
layer.setBounds(0, 0, size.width, size.height);
}
}
/**
* Fades in the specified message component in the top layer of this
* layered pane.
* @param message the component to be displayed in the message layer
* @param finalAlpha the alpha value of the component when fade in is complete
*/
public void showMessageLayer(JComponent message, final float finalAlpha) {
messageLayer = new JPanel();
messageLayer.setOpaque(false);
GridBagLayout gridbag = new GridBagLayout();
messageLayer.setLayout(gridbag);
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.CENTER;
messageAlpha = new JXPanel();
messageAlpha.setOpaque(false);
messageAlpha.setAlpha(0.0f);
gridbag.addLayoutComponent(messageAlpha, c);
messageLayer.add(messageAlpha);
messageAlpha.add(message);
add(messageLayer, JLayeredPane.POPUP_LAYER);
revalidate();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Animator animator = new Animator(2000,
new PropertySetter(messageAlpha, "alpha", 0.0f, finalAlpha));
animator.setStartDelay(200);
animator.setAcceleration(.2f);
animator.setDeceleration(.5f);
animator.start();
}
});
}
/**
* Fades out and removes the current message component
*/
public void hideMessageLayer() {
if (messageLayer != null && messageLayer.isShowing()) {
Animator animator = new Animator(500,
new PropertySetter(messageAlpha, "alpha", messageAlpha.getAlpha(), 0.0f) {
public void end() {
remove(messageLayer);
revalidate();
}
});
animator.setStartDelay(300);
animator.setAcceleration(.2f);
animator.setDeceleration(.5f);
animator.start();
}
}
}

226
swingset3/com/sun/swingset3/demos/button/ButtonDemo.java

@ -0,0 +1,226 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.demos.button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URISyntaxException;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.sun.swingset3.DemoProperties;
import com.sun.swingset3.demos.JHyperlink;
/**
*
* @author aim
*/
@DemoProperties(
value = "JButton Demo",
category = "Controls",
description = "Demonstrates the many uses of JButton, Swing's push button component.",
sourceFiles = {
"com/sun/swingset3/demos/button/ButtonDemo.java",
"com/sun/swingset3/demos/JHyperlink.java",
"com/sun/swingset3/demos/button/resources/ButtonDemo.html",
"com/sun/swingset3/demos/button/resources/images/blogs.png",
"com/sun/swingset3/demos/button/resources/images/ButtonDemo.gif",
"com/sun/swingset3/demos/button/resources/images/document-print.png",
"com/sun/swingset3/demos/button/resources/images/earth_day.gif",
"com/sun/swingset3/demos/button/resources/images/earth_night.gif",
"com/sun/swingset3/demos/button/resources/images/edit-find.png",
"com/sun/swingset3/demos/button/resources/images/redbutton.png",
"com/sun/swingset3/demos/button/resources/images/redbutton_dark.png",
"com/sun/swingset3/demos/button/resources/images/redbutton_glow.png"
}
)
public class ButtonDemo extends JPanel {
public ButtonDemo() {
setToolTipText("Demonstrates JButton, Swing's push button component.");
initComponents();
setOpaque(false);
}
protected void initComponents() {
setLayout(new GridLayout(0, 1));
add(createSimpleButtonPanel());
add(createCreativeButtonPanel());
}
protected JPanel createSimpleButtonPanel() {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 8));
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(),
"Simple Buttons"));
//<snip>Create simple button
final JButton simpleButton = new JButton("Do it");
simpleButton.setToolTipText("simple button");
//</snip>
//<snip>Add action listener using anonymous inner class
// This style is useful when the action code is tied to a
// single button instance and it's useful for simplicity
// sake to keep the action code located near the button.
// More global application actions should be implemented
// using Action classes instead.
simpleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
simpleButton.setText("Do it again");
// Need to force toplevel to relayout to accommodate new button size
SwingUtilities.getWindowAncestor(simpleButton).validate();
}
});
//</snip>
simpleButton.putClientProperty("snippetKey", "Create simple button");
panel.add(simpleButton);
//<snip>Create image button
// Image is from the Java Look and Feel Graphics Repository:
// http://java.sun.com/developer/techDocs/hi/repository
JButton button = new JButton(new ImageIcon(getClass().
getResource("resources/images/document-print.png")));
button.setToolTipText("image button");
//</snip>
button.putClientProperty("snippetKey", "Create image button");
panel.add(button);
//<snip>Create button with text and image
// Image is from the Java Look and Feel Graphics Repository:
// http://java.sun.com/developer/techDocs/hi/repository
button = new JButton("Find",
new ImageIcon(getClass().
getResource("resources/images/edit-find.png")));
button.setToolTipText("button with text and image");
button.setHorizontalTextPosition(JButton.LEADING);
button.setIconTextGap(6);
//</snip>
button.putClientProperty("snippetKey", "Create button with text and image");
panel.add(button);
//<snip>Create button with background color
button = new JButton("Go");
button.setBackground(Color.green);
button.setContentAreaFilled(true);
button.setOpaque(false);
button.setToolTipText("button with background color");
//</snip>
button.putClientProperty("snippetKey", "Create button with background color");
panel.add(button);
return panel;
}
protected JPanel createCreativeButtonPanel() {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.CENTER, 16, 8));
panel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(),
"More Interesting Buttons"));
//<snip>Create button with no border
JButton button = new JButton();
button.setText("Connect");
button.setIcon(new ImageIcon(getClass().getResource("resources/images/earth_day.gif")));
button.setPressedIcon(new ImageIcon(getClass().getResource("resources/images/earth_night.gif")));
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setVerticalTextPosition(JButton.BOTTOM);
button.setHorizontalTextPosition(JButton.CENTER);
button.setIconTextGap(0);
button.setToolTipText("button with no border");
//</snip>
button.putClientProperty("snippetKey", "Create button with no border");
panel.add(button);
//<snip>Create image button with rollover image
button = new JButton();
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setIcon(new ImageIcon(getClass().getResource("resources/images/redbutton.png")));
button.setRolloverEnabled(true);
button.setRolloverIcon(new ImageIcon(getClass().getResource("resources/images/redbutton_glow.png")));
button.setPressedIcon(new ImageIcon(getClass().getResource("resources/images/redbutton_dark.png")));
button.setToolTipText("button with rollover image");
//</snip>
button.putClientProperty("snippetKey", "Create image button with rollover image");
panel.add(button);
//<snip>Create HTML hyperlink
JHyperlink hyperlink;
try {
hyperlink = new JHyperlink("Get More Info", "http://java.sun.com/j2se");
} catch (URISyntaxException use) {
use.printStackTrace();
hyperlink = new JHyperlink("Get More Info");
}
//</snip>
hyperlink.putClientProperty("snippetKey", "Create HTML hyperlink");
panel.add(hyperlink);
//<snip>Create HTML image hyperlink
try {
hyperlink = new JHyperlink(
new ImageIcon(getClass().getResource("resources/images/blogs.png")),
"http://weblogs.java.net");
} catch (URISyntaxException use) {
use.printStackTrace();
}
//</snip>
button.putClientProperty("snippetKey", "Create HTML image hyperlink");
panel.add(hyperlink);
return panel;
}
public static void main(String args[]) {
final ButtonDemo buttonDemo = new ButtonDemo();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("JButton Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(buttonDemo);
frame.pack();
frame.setVisible(true);
}
});
}
}

1
swingset3/com/sun/swingset3/demos/button/resources/ButtonDemo.html

@ -0,0 +1 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <body> <p> Today's modern GUIs often use buttons which don't look like the traditional &quot;push&quot; button. Swing's button component, <a href="http://java.sun.com/javase/6/docs/api/javax/swing/JButton.html">javax.swing.JButton</a>, can be used to create both ordinary and more creative button visuals. In the end, they all perform an action when clicked. </p> <p> To highlight the source code used to create a particular button, popup the context menu over that button. </p> </body> </html>

BIN
swingset3/com/sun/swingset3/demos/button/resources/images/ButtonDemo.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
swingset3/com/sun/swingset3/demos/button/resources/images/blogs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
swingset3/com/sun/swingset3/demos/button/resources/images/document-print.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
swingset3/com/sun/swingset3/demos/button/resources/images/earth_day.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
swingset3/com/sun/swingset3/demos/button/resources/images/earth_night.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
swingset3/com/sun/swingset3/demos/button/resources/images/edit-find.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
swingset3/com/sun/swingset3/demos/button/resources/images/redbutton.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
swingset3/com/sun/swingset3/demos/button/resources/images/redbutton_dark.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
swingset3/com/sun/swingset3/demos/button/resources/images/redbutton_glow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

270
swingset3/com/sun/swingset3/demos/colorchooser/BezierAnimationPanel.java

@ -0,0 +1,270 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.demos.colorchooser;
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;
import java.util.Hashtable;
import java.util.Map;
import javax.swing.*;
import static com.sun.swingset3.demos.colorchooser.BezierAnimationPanel.BezierColor.*;
/**
* BezierAnimationPanel
*
* @author Jim Graham
* @author Jeff Dinkins (removed dynamic setting changes, made swing friendly)
* @version 1.16 11/17/05
*/
class BezierAnimationPanel extends JPanel implements Runnable {
public enum BezierColor {
BACKGROUND,
OUTER,
GRADIENT_A,
GRADIENT_B
}
private final Map<BezierColor, Color> colors = new Hashtable<BezierColor, Color>();
private GradientPaint gradient = null;
private static final int NUMPTS = 6;
private final float[] animpts = new float[NUMPTS * 2];
private final float[] deltas = new float[NUMPTS * 2];
private BufferedImage img;
private Thread anim;
private final Object lock = new Object();
/**
* BezierAnimationPanel Constructor
*/
public BezierAnimationPanel() {
setOpaque(true);
colors.put(BACKGROUND, new Color(0, 0, 153));
colors.put(OUTER, new Color(255, 255, 255));
colors.put(GRADIENT_A, new Color(255, 0, 101));
colors.put(GRADIENT_B, new Color(255, 255, 0));
addHierarchyListener(new HierarchyListener() {
public void hierarchyChanged(HierarchyEvent e) {
if (isShowing()) {
start();
} else {
stop();
}
}
}
);
}
public Color getBezierColor(BezierColor bezierColor) {
return colors.get(bezierColor);
}
public void setBezierColor(BezierColor bezierColor, Color value) {
if (value != null) {
colors.put(bezierColor, value);
}
}
public void start() {
Dimension size = getSize();
for (int i = 0; i < animpts.length; i += 2) {
animpts[i] = (float) (Math.random() * size.width);
animpts[i + 1] = (float) (Math.random() * size.height);
deltas[i] = (float) (Math.random() * 4.0 + 2.0);
deltas[i + 1] = (float) (Math.random() * 4.0 + 2.0);
if (animpts[i] > size.width / 6.0f) {
deltas[i] = -deltas[i];
}
if (animpts[i + 1] > size.height / 6.0f) {
deltas[i + 1] = -deltas[i + 1];
}
}
anim = new Thread(this);
anim.setPriority(Thread.MIN_PRIORITY);
anim.start();
}
public synchronized void stop() {
anim = null;
notify();
}
private static void animate(float[] pts, float[] deltas, int index, int limit) {
float newpt = pts[index] + deltas[index];
if (newpt <= 0) {
newpt = -newpt;
deltas[index] = (float) (Math.random() * 3.0 + 2.0);
} else if (newpt >= (float) limit) {
newpt = 2.0f * limit - newpt;
deltas[index] = -(float) (Math.random() * 3.0 + 2.0);
}
pts[index] = newpt;
}
public void run() {
Thread me = Thread.currentThread();
while (getSize().width <= 0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
return;
}
}
Graphics2D g2d = null;
Graphics2D bufferG2D = null;
BasicStroke solid = new BasicStroke(9.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 9.0f);
GeneralPath gp = new GeneralPath(GeneralPath.WIND_NON_ZERO);
int rule = AlphaComposite.SRC_OVER;
AlphaComposite opaque = AlphaComposite.SrcOver;
AlphaComposite blend = AlphaComposite.getInstance(rule, 0.9f);
AlphaComposite set = AlphaComposite.Src;
Dimension oldSize = getSize();
Shape clippath = null;
while (anim == me) {
Dimension size = getSize();
if (size.width != oldSize.width || size.height != oldSize.height) {
img = null;
clippath = null;
if (bufferG2D != null) {
bufferG2D.dispose();
bufferG2D = null;
}
}
oldSize = size;
if (img == null) {
img = (BufferedImage) createImage(size.width, size.height);
}
if (bufferG2D == null) {
bufferG2D = img.createGraphics();
bufferG2D.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_DEFAULT);
bufferG2D.setClip(clippath);
}
g2d = bufferG2D;
float[] ctrlpts;
for (int i = 0; i < animpts.length; i += 2) {
animate(animpts, deltas, i, size.width);
animate(animpts, deltas, i + 1, size.height);
}
ctrlpts = animpts;
int len = ctrlpts.length;
gp.reset();
float prevx = ctrlpts[len - 2];
float prevy = ctrlpts[len - 1];
float curx = ctrlpts[0];
float cury = ctrlpts[1];
float midx = (curx + prevx) / 2.0f;
float midy = (cury + prevy) / 2.0f;
gp.moveTo(midx, midy);
for (int i = 2; i <= ctrlpts.length; i += 2) {
float x1 = (midx + curx) / 2.0f;
float y1 = (midy + cury) / 2.0f;
prevx = curx;
prevy = cury;
if (i < ctrlpts.length) {
curx = ctrlpts[i];
cury = ctrlpts[i + 1];
} else {
curx = ctrlpts[0];
cury = ctrlpts[1];
}
midx = (curx + prevx) / 2.0f;
midy = (cury + prevy) / 2.0f;
float x2 = (prevx + midx) / 2.0f;
float y2 = (prevy + midy) / 2.0f;
gp.curveTo(x1, y1, x2, y2, midx, midy);
}
gp.closePath();
synchronized (lock) {
g2d.setComposite(set);
g2d.setBackground(getBezierColor(BACKGROUND));
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
// g2d.clearRect(bounds.x-5, bounds.y-5, bounds.x + bounds.width + 5, bounds.y + bounds.height + 5);
g2d.clearRect(0, 0, getWidth(), getHeight());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(getBezierColor(OUTER));
g2d.setComposite(opaque);
g2d.setStroke(solid);
g2d.draw(gp);
g2d.setPaint(gradient);
Rectangle bounds = gp.getBounds();
gradient = new GradientPaint(bounds.x, bounds.y, getBezierColor(GRADIENT_A),
bounds.x + bounds.width, bounds.y + bounds.height,
getBezierColor(GRADIENT_B), true);
g2d.setComposite(blend);
g2d.fill(gp);
}
repaint();
Thread.yield();
}
if (g2d != null) {
g2d.dispose();
}
}
public void paint(Graphics g) {
synchronized (lock) {
Graphics2D g2d = (Graphics2D) g;
if (img != null) {
g2d.setComposite(AlphaComposite.Src);
g2d.drawImage(img, null, 0, 0);
}
}
}
}

186
swingset3/com/sun/swingset3/demos/colorchooser/ColorChooserDemo.java

@ -0,0 +1,186 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.demos.colorchooser;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import com.sun.swingset3.demos.JGridPanel;
import com.sun.swingset3.demos.ResourceManager;
import com.sun.swingset3.DemoProperties;
/**
* JColorChooserDemo
*
* @author Jeff Dinkins
* @version 1.1 07/16/99
*/
@DemoProperties(
value = "JColorChooser Demo",
category = "Choosers",
description = "Demonstrates JColorChooser, a component which allows the user to pick a color.",
sourceFiles = {
"com/sun/swingset3/demos/colorchooser/ColorChooserDemo.java",
"com/sun/swingset3/demos/colorchooser/BezierAnimationPanel.java",
"com/sun/swingset3/demos/JGridPanel.java",
"com/sun/swingset3/demos/ResourceManager.java",
"com/sun/swingset3/demos/colorchooser/resources/ColorChooserDemo.properties",
"com/sun/swingset3/demos/colorchooser/resources/images/ColorChooserDemo.gif"
}
)
public class ColorChooserDemo extends JPanel {
private final ResourceManager resourceManager = new ResourceManager(this.getClass());
private final BezierAnimationPanel bezAnim = new BezierAnimationPanel();
private final JButton outerColorButton = new JButton(resourceManager.getString("ColorChooserDemo.outer_line"));
private final JButton backgroundColorButton = new JButton(resourceManager.getString("ColorChooserDemo.background"));
private final JButton gradientAButton = new JButton(resourceManager.getString("ColorChooserDemo.grad_a"));
private final JButton gradientBButton = new JButton(resourceManager.getString("ColorChooserDemo.grad_b"));
/**
* main method allows us to run as a standalone demo.
*/
public static void main(String[] args) {
JFrame frame = new JFrame(ColorChooserDemo.class.getAnnotation(DemoProperties.class).value());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ColorChooserDemo());
frame.setPreferredSize(new Dimension(800, 600));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
/**
* ColorChooserDemo Constructor
*/
public ColorChooserDemo() {
setLayout(new BorderLayout());
outerColorButton.setIcon(new ColorSwatch(BezierAnimationPanel.BezierColor.OUTER));
backgroundColorButton.setIcon(new ColorSwatch(BezierAnimationPanel.BezierColor.BACKGROUND));
gradientAButton.setIcon(new ColorSwatch(BezierAnimationPanel.BezierColor.GRADIENT_A));
gradientBButton.setIcon(new ColorSwatch(BezierAnimationPanel.BezierColor.GRADIENT_B));
ActionListener l = new ActionListener() {
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
final BezierAnimationPanel.BezierColor bezierColor =
((ColorSwatch) button.getIcon()).getBezierColor();
Color current = bezAnim.getBezierColor(bezierColor);
final JColorChooser chooser = new JColorChooser(current != null ?
current :
Color.WHITE);
ActionListener colorChooserListener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
bezAnim.setBezierColor(bezierColor, chooser.getColor());
}
};
JDialog dialog = JColorChooser.createDialog(ColorChooserDemo.this,
resourceManager.getString("ColorChooserDemo.chooser_title"),
true,
chooser,
colorChooserListener,
null);
dialog.setVisible(true);
}
};
outerColorButton.addActionListener(l);
backgroundColorButton.addActionListener(l);
gradientAButton.addActionListener(l);
gradientBButton.addActionListener(l);
// Add control buttons
JPanel buttonPanel = new JPanel(new GridLayout(1, 4, 15, 0));
buttonPanel.add(backgroundColorButton);
buttonPanel.add(gradientAButton);
buttonPanel.add(gradientBButton);
buttonPanel.add(outerColorButton);
// Add everything to the panel
JGridPanel pnContent = new JGridPanel(1, 0, 1);
pnContent.cell(buttonPanel, JGridPanel.Layout.CENTER).
cell(bezAnim);
pnContent.setBorder(new EmptyBorder(10, 0, 0, 0));
add(pnContent);
}
private class ColorSwatch implements Icon {
private final BezierAnimationPanel.BezierColor bezierColor;
public ColorSwatch(BezierAnimationPanel.BezierColor bezierColor) {
this.bezierColor = bezierColor;
}
public int getIconWidth() {
return 11;
}
public int getIconHeight() {
return 11;
}
public BezierAnimationPanel.BezierColor getBezierColor() {
return bezierColor;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.black);
g.fillRect(x, y, getIconWidth(), getIconHeight());
g.setColor(bezAnim.getBezierColor(bezierColor));
g.fillRect(x + 2, y + 2, getIconWidth() - 4, getIconHeight() - 4);
}
}
}

11
swingset3/com/sun/swingset3/demos/colorchooser/resources/ColorChooserDemo.properties

@ -0,0 +1,11 @@
### ColorChooser Demo ###
ColorChooserDemo.accessible_description=The ColorChooser allows a user to pick a color either from a pallete or by choosing RGB or HSB values
ColorChooserDemo.tooltip=JColorChooser demo
ColorChooserDemo.name=ColorChooser Demo
ColorChooserDemo.chooser_title=Choose a Color
ColorChooserDemo.background=Background
ColorChooserDemo.grad_a=Gradient 1
ColorChooserDemo.grad_b=Gradient 2
ColorChooserDemo.outer_line=Perimeter
ColorChooserDemo.cup=Image of the Java Trademark Coffee Cup

BIN
swingset3/com/sun/swingset3/demos/colorchooser/resources/images/ColorChooserDemo.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

445
swingset3/com/sun/swingset3/demos/combobox/ComboBoxDemo.java

@ -0,0 +1,445 @@
/*
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sun.swingset3.demos.combobox;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.accessibility.AccessibleRelation;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import com.sun.swingset3.demos.ResourceManager;
import com.sun.swingset3.DemoProperties;
/**
* JComboBox Demo
*
* @author Jeff Dinkins
* @version 1.13 11/17/05
*/
@DemoProperties(
value = "JComboBox Demo",
category = "Controls",
description = "Demonstrates JComboBox, a control which allows the user to make a selection from a popup list",
sourceFiles = {
"com/sun/swingset3/demos/combobox/ComboBoxDemo.java",
"com/sun/swingset3/demos/ResourceManager.java",
"com/sun/swingset3/demos/combobox/resources/ComboBoxDemo.properties",
"com/sun/swingset3/demos/combobox/resources/images/brenteyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/brenthair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/brentmouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/ComboBoxDemo.gif",
"com/sun/swingset3/demos/combobox/resources/images/georgeseyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/georgeshair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/georgesmouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/hanseyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/hanshair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/hansmouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/howardeyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/howardhair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/howardmouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/jameseyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/jameshair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/jamesmouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/jeffeyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/jeffhair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/jeffmouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/joneyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/jonhair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/jonmouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/laraeyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/larahair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/laramouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/larryeyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/larryhair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/larrymouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/lisaeyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/lisahair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/lisamouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/michaeleyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/michaelhair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/michaelmouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/philipeyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/philiphair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/philipmouth.jpg",
"com/sun/swingset3/demos/combobox/resources/images/scotteyes.jpg",
"com/sun/swingset3/demos/combobox/resources/images/scotthair.jpg",
"com/sun/swingset3/demos/combobox/resources/images/scottmouth.jpg"
}
)
public class ComboBoxDemo extends JPanel implements ActionListener {
private static final Dimension VGAP15 = new Dimension(1, 15);
private static final Dimension HGAP20 = new Dimension(20, 1);
private static final Dimension VGAP20 = new Dimension(1, 20);
private static final Dimension HGAP30 = new Dimension(30, 1);
private static final Dimension VGAP30 = new Dimension(1, 30);
private final ResourceManager resourceManager = new ResourceManager(this.getClass());
private Face face;
private JLabel faceLabel;
private JComboBox hairCB;
private JComboBox eyesCB;
private JComboBox mouthCB;
private JComboBox presetCB;
private final Map<String, Object> parts = new HashMap<String, Object>();
/**
* main method allows us to run as a standalone demo.
*/
public static void main(String[] args) {
JFrame frame = new JFrame(ComboBoxDemo.class.getAnnotation(DemoProperties.class).value());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ComboBoxDemo());
frame.setPreferredSize(new Dimension(800, 600));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
/**
* ComboBoxDemo Constructor
*/
public ComboBoxDemo() {
createComboBoxDemo();
}
private void createComboBoxDemo() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JPanel innerPanel = new JPanel();
innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.X_AXIS));
add(Box.createRigidArea(VGAP20));
add(innerPanel);
add(Box.createRigidArea(VGAP20));
innerPanel.add(Box.createRigidArea(HGAP20));
// Create a panel to hold buttons
JPanel comboBoxPanel = new JPanel() {
public Dimension getMaximumSize() {
return new Dimension(getPreferredSize().width, super.getMaximumSize().height);
}
};
comboBoxPanel.setLayout(new BoxLayout(comboBoxPanel, BoxLayout.Y_AXIS));
comboBoxPanel.add(Box.createRigidArea(VGAP15));
JLabel l = (JLabel) comboBoxPanel.add(new JLabel(resourceManager.getString("ComboBoxDemo.presets")));
l.setAlignmentX(JLabel.LEFT_ALIGNMENT);
presetCB = (JComboBox) comboBoxPanel.add(createPresetComboBox());
presetCB.setAlignmentX(JComboBox.LEFT_ALIGNMENT);
l.setLabelFor(presetCB);
comboBoxPanel.add(Box.createRigidArea(VGAP30));
l = (JLabel) comboBoxPanel.add(new JLabel(resourceManager.getString("ComboBoxDemo.hair_description")));
l.setAlignmentX(JLabel.LEFT_ALIGNMENT);
hairCB = (JComboBox) comboBoxPanel.add(createHairComboBox());
hairCB.setAlignmentX(JComboBox.LEFT_ALIGNMENT);
l.setLabelFor(hairCB);
comboBoxPanel.add(Box.createRigidArea(VGAP15));
l = (JLabel) comboBoxPanel.add(new JLabel(resourceManager.getString("ComboBoxDemo.eyes_description")));
l.setAlignmentX(JLabel.LEFT_ALIGNMENT);
eyesCB = (JComboBox) comboBoxPanel.add(createEyesComboBox());
eyesCB.setAlignmentX(JComboBox.LEFT_ALIGNMENT);
l.setLabelFor(eyesCB);
comboBoxPanel.add(Box.createRigidArea(VGAP15));
l = (JLabel) comboBoxPanel.add(new JLabel(resourceManager.getString("ComboBoxDemo.mouth_description")));
l.setAlignmentX(JLabel.LEFT_ALIGNMENT);
mouthCB = (JComboBox) comboBoxPanel.add(createMouthComboBox());
mouthCB.setAlignmentX(JComboBox.LEFT_ALIGNMENT);
l.setLabelFor(mouthCB);
comboBoxPanel.add(Box.createRigidArea(VGAP15));
// Fill up the remaining space
comboBoxPanel.add(new JPanel(new BorderLayout()));
// Create and place the Face.
face = new Face();
JPanel facePanel = new JPanel();
facePanel.setLayout(new BorderLayout());
facePanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
faceLabel = new JLabel(face);
facePanel.add(faceLabel, BorderLayout.CENTER);
// Indicate that the face panel is controlled by the hair, eyes and
// mouth combo boxes.
Object[] controlledByObjects = new Object[3];
controlledByObjects[0] = hairCB;
controlledByObjects[1] = eyesCB;
controlledByObjects[2] = mouthCB;
AccessibleRelation controlledByRelation =
new AccessibleRelation(AccessibleRelation.CONTROLLED_BY_PROPERTY,
controlledByObjects);
facePanel.getAccessibleContext().getAccessibleRelationSet().add(controlledByRelation);
// Indicate that the hair, eyes and mouth combo boxes are controllers
// for the face panel.
AccessibleRelation controllerForRelation =
new AccessibleRelation(AccessibleRelation.CONTROLLER_FOR_PROPERTY,
facePanel);
hairCB.getAccessibleContext().getAccessibleRelationSet().add(controllerForRelation);
eyesCB.getAccessibleContext().getAccessibleRelationSet().add(controllerForRelation);
mouthCB.getAccessibleContext().getAccessibleRelationSet().add(controllerForRelation);
// add buttons and image panels to inner panel
innerPanel.add(comboBoxPanel);
innerPanel.add(Box.createRigidArea(HGAP30));
innerPanel.add(facePanel);
innerPanel.add(Box.createRigidArea(HGAP20));
// load up the face parts
addFace("brent", resourceManager.getString("ComboBoxDemo.brent"));
addFace("georges", resourceManager.getString("ComboBoxDemo.georges"));
addFace("hans", resourceManager.getString("ComboBoxDemo.hans"));
addFace("howard", resourceManager.getString("ComboBoxDemo.howard"));
addFace("james", resourceManager.getString("ComboBoxDemo.james"));
addFace("jeff", resourceManager.getString("ComboBoxDemo.jeff"));
addFace("jon", resourceManager.getString("ComboBoxDemo.jon"));
addFace("lara", resourceManager.getString("ComboBoxDemo.lara"));
addFace("larry", resourceManager.getString("ComboBoxDemo.larry"));
addFace("lisa", resourceManager.getString("ComboBoxDemo.lisa"));
addFace("michael", resourceManager.getString("ComboBoxDemo.michael"));
addFace("philip", resourceManager.getString("ComboBoxDemo.philip"));
addFace("scott", resourceManager.getString("ComboBoxDemo.scott"));
// set the default face
presetCB.setSelectedIndex(0);
}
private void addFace(String name, String i18n_name) {
ImageIcon i;
String i18n_hair = resourceManager.getString("ComboBoxDemo.hair");
String i18n_eyes = resourceManager.getString("ComboBoxDemo.eyes");
String i18n_mouth = resourceManager.getString("ComboBoxDemo.mouth");
parts.put(i18n_name, name); // i18n name lookup
parts.put(name, i18n_name); // reverse name lookup
i = resourceManager.createImageIcon(name + "hair.jpg", i18n_name + i18n_hair);
parts.put(name + "hair", i);
i = resourceManager.createImageIcon(name + "eyes.jpg", i18n_name + i18n_eyes);
parts.put(name + "eyes", i);
i = resourceManager.createImageIcon(name + "mouth.jpg", i18n_name + i18n_mouth);
parts.put(name + "mouth", i);
}
private JComboBox createHairComboBox() {
JComboBox cb = new JComboBox();
fillComboBox(cb);
cb.addActionListener(this);
return cb;
}
private JComboBox createEyesComboBox() {
JComboBox cb = new JComboBox();
fillComboBox(cb);
cb.addActionListener(this);
return cb;
}
private JComboBox createMouthComboBox() {
JComboBox cb = new JComboBox();
fillComboBox(cb);
cb.addActionListener(this);
return cb;
}
private JComboBox createPresetComboBox() {
JComboBox cb = new JComboBox();
cb.addItem(resourceManager.getString("ComboBoxDemo.preset1"));
cb.addItem(resourceManager.getString("ComboBoxDemo.preset2"));
cb.addItem(resourceManager.getString("ComboBoxDemo.preset3"));
cb.addItem(resourceManager.getString("ComboBoxDemo.preset4"));
cb.addItem(resourceManager.getString("ComboBoxDemo.preset5"));
cb.addItem(resourceManager.getString("ComboBoxDemo.preset6"));
cb.addItem(resourceManager.getString("ComboBoxDemo.preset7"));
cb.addItem(resourceManager.getString("ComboBoxDemo.preset8"));
cb.addItem(resourceManager.getString("ComboBoxDemo.preset9"));
cb.addItem(resourceManager.getString("ComboBoxDemo.preset10"));
cb.addActionListener(this);
return cb;
}
private void fillComboBox(JComboBox cb) {
cb.addItem(resourceManager.getString("ComboBoxDemo.brent"));
cb.addItem(resourceManager.getString("ComboBoxDemo.georges"));
cb.addItem(resourceManager.getString("ComboBoxDemo.hans"));
cb.addItem(resourceManager.getString("ComboBoxDemo.howard"));
cb.addItem(resourceManager.getString("ComboBoxDemo.james"));
cb.addItem(resourceManager.getString("ComboBoxDemo.jeff"));
cb.addItem(resourceManager.getString("ComboBoxDemo.jon"));
cb.addItem(resourceManager.getString("ComboBoxDemo.lara"));
cb.addItem(resourceManager.getString("ComboBoxDemo.larry"));
cb.addItem(resourceManager.getString("ComboBoxDemo.lisa"));
cb.addItem(resourceManager.getString("ComboBoxDemo.michael"));
cb.addItem(resourceManager.getString("ComboBoxDemo.philip"));
cb.addItem(resourceManager.getString("ComboBoxDemo.scott"));
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == hairCB) {
String name = (String) parts.get((String) hairCB.getSelectedItem());
face.setHair((ImageIcon) parts.get(name + "hair"));
faceLabel.repaint();
} else if (e.getSource() == eyesCB) {
String name = (String) parts.get((String) eyesCB.getSelectedItem());
face.setEyes((ImageIcon) parts.get(name + "eyes"));
faceLabel.repaint();
} else if (e.getSource() == mouthCB) {
String name = (String) parts.get((String) mouthCB.getSelectedItem());
face.setMouth((ImageIcon) parts.get(name + "mouth"));
faceLabel.repaint();
} else if (e.getSource() == presetCB) {
String hair = null;
String eyes = null;
String mouth = null;
switch (presetCB.getSelectedIndex()) {
case 0:
hair = (String) parts.get("philip");
eyes = (String) parts.get("howard");
mouth = (String) parts.get("jeff");
break;
case 1:
hair = (String) parts.get("jeff");
eyes = (String) parts.get("larry");
mouth = (String) parts.get("philip");
break;
case 2:
hair = (String) parts.get("howard");
eyes = (String) parts.get("scott");
mouth = (String) parts.get("hans");
break;
case 3:
hair = (String) parts.get("philip");
eyes = (String) parts.get("jeff");
mouth = (String) parts.get("hans");
break;
case 4:
hair = (String) parts.get("brent");
eyes = (String) parts.get("jon");
mouth = (String) parts.get("scott");
break;
case 5:
hair = (String) parts.get("lara");
eyes = (String) parts.get("larry");
mouth = (String) parts.get("lisa");
break;
case 6:
hair = (String) parts.get("james");
eyes = (String) parts.get("philip");
mouth = (String) parts.get("michael");
break;
case 7:
hair = (String) parts.get("philip");
eyes = (String) parts.get("lisa");
mouth = (String) parts.get("brent");
break;
case 8:
hair = (String) parts.get("james");
eyes = (String) parts.get("philip");
mouth = (String) parts.get("jon");
break;
case 9:
hair = (String) parts.get("lara");
eyes = (String) parts.get("jon");
mouth = (String) parts.get("scott");
break;
}
if (hair != null) {
hairCB.setSelectedItem(hair);
eyesCB.setSelectedItem(eyes);
mouthCB.setSelectedItem(mouth);
faceLabel.repaint();
}
}
}
private static class Face implements Icon {
private ImageIcon hair;
private ImageIcon eyes;
private ImageIcon mouth;
void setHair(ImageIcon i) {
hair = i;
}
void setEyes(ImageIcon i) {
eyes = i;
}
void setMouth(ImageIcon i) {
mouth = i;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
int height = y;
x = c.getWidth() / 2 - getIconWidth() / 2;
if (hair != null) {
hair.paintIcon(c, g, x, height);
height += hair.getIconHeight();
}
if (eyes != null) {
eyes.paintIcon(c, g, x, height);
height += eyes.getIconHeight();
}
if (mouth != null) {
mouth.paintIcon(c, g, x, height);
}
}
public int getIconWidth() {
return 344;
}
public int getIconHeight() {
return 455;
}
}
}

42
swingset3/com/sun/swingset3/demos/combobox/resources/ComboBoxDemo.properties

@ -0,0 +1,42 @@
### ComboBox Demo ###
ComboBoxDemo.accessible_description=This demo shows an example of using the JComboBox component.
ComboBoxDemo.tooltip=JComboBox demo
ComboBoxDemo.name=ComboBox Demo
ComboBoxDemo.hair=hair
ComboBoxDemo.eyes=eyes
ComboBoxDemo.mouth=mouth
ComboBoxDemo.presets=Presets:
ComboBoxDemo.preset1=Philip, Howard, Jeff
ComboBoxDemo.preset2=Jeff, Larry, Philip
ComboBoxDemo.preset3=Howard, Scott, Hans
ComboBoxDemo.preset4=Philip, Jeff, Hans
ComboBoxDemo.preset5=Brent, Jon, Scott
ComboBoxDemo.preset6=Lara, Larry, Lisa
ComboBoxDemo.preset7=James, Philip, Michael
ComboBoxDemo.preset8=Philip, Lisa, Brent
ComboBoxDemo.preset9=James, Philip, Jon
ComboBoxDemo.preset10=Lara, Jon, Scott
ComboBoxDemo.hair_description=Hair:
ComboBoxDemo.eyes_description=Eyes & Nose:
ComboBoxDemo.mouth_description=Mouth:
ComboBoxDemo.amy=Amy
ComboBoxDemo.brent=Brent
ComboBoxDemo.georges=Georges
ComboBoxDemo.hans=Hans
ComboBoxDemo.howard=Howard
ComboBoxDemo.james=James
ComboBoxDemo.jeff=Jeff
ComboBoxDemo.jon=Jon
ComboBoxDemo.lara=Lara
ComboBoxDemo.larry=Larry
ComboBoxDemo.lisa=Lisa
ComboBoxDemo.michael=Michael
ComboBoxDemo.philip=Philip
ComboBoxDemo.scott=Scott

BIN
swingset3/com/sun/swingset3/demos/combobox/resources/images/ComboBoxDemo.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

BIN
swingset3/com/sun/swingset3/demos/combobox/resources/images/brenteyes.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
swingset3/com/sun/swingset3/demos/combobox/resources/images/brenthair.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

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

Loading…
Cancel
Save