Java tutorial
/************************************************************************************* * Copyright (c) 2008-2011 Red Hat, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * JBoss by Red Hat - Initial implementation. ************************************************************************************/ package org.jboss.tools.central.editors; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringEscapeUtils; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IContributor; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.InvalidRegistryObjectException; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.IJobChangeListener; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.ToolBarManager; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceColors; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; import org.eclipse.ui.forms.IFormColors; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.events.HyperlinkAdapter; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Hyperlink; import org.eclipse.ui.forms.widgets.ImageHyperlink; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.forms.widgets.TableWrapData; import org.eclipse.ui.forms.widgets.TableWrapLayout; import org.eclipse.ui.ide.IDEActionFactory; import org.eclipse.ui.internal.forms.widgets.FormFonts; import org.eclipse.ui.menus.CommandContributionItem; import org.eclipse.ui.part.PageBook; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.jboss.tools.central.JBossCentralActivator; import org.jboss.tools.central.jobs.AbstractRefreshJob; import org.jboss.tools.central.jobs.RefreshBlogsJob; import org.jboss.tools.central.jobs.RefreshNewsJob; import org.jboss.tools.central.jobs.RefreshTutorialsJob; import org.jboss.tools.central.model.FeedsEntry; import org.jboss.tools.project.examples.ProjectExamplesActivator; import org.jboss.tools.project.examples.model.ProjectExample; import org.jboss.tools.project.examples.model.ProjectExampleCategory; import org.jboss.tools.project.examples.wizard.NewProjectExamplesWizard2; import org.osgi.framework.Bundle; /** * * @author snjeza * */ public class GettingStartedPage extends AbstractJBossCentralPage { private static final String NEWS_WARNING_ID = "org.jboss.tools.central.newsWarning"; private static final String BLOGS_WARNING_ID = "org.jboss.tools.central.blogsWarning"; private static final String CLASS_ATTRIBUTE = "class"; public static final String ID = ID_PREFIX + "GettingStartedPage"; protected static final long TIME_DELAY = 2000L; private IWorkbenchAction newWizardDropDownAction; private ScrolledForm form; private PageBook blogsPageBook; private ScrolledComposite blogsScrollComposite; private RefreshBlogsJobChangeListener refreshBlogsJobChangeListener; private FormText blogsNoteText; private FormText tutorialsNoteText; private Composite blogsLoadingComposite; private Composite tutorialsLoadingComposite; private FormText blogsExceptionText; private FormText tutorialsExceptionText; private Composite blogsComposite; private Composite tutorialsComposite; private FormToolkit toolkit; private ScrolledComposite tutorialScrollComposite; private PageBook tutorialPageBook; private RefreshTutorialsJobChangeListener refreshTutorialsJobChangeListener; private Section blogsSection; private Section tutorialsSection; private Section documentationSection; private Section projectsSection; private Composite projectsComposite; private Composite documentationComposite; private Set<ProjectExampleCategory> expandedCategories = new HashSet<ProjectExampleCategory>(); private Section newsSection; private ScrolledComposite newsScrollComposite; private PageBook newsPageBook; private FormText newsNoteText; private Composite newsLoadingComposite; private FormText newsExceptionText; private Composite newsComposite; private RefreshNewsJobChangeListener refreshNewsJobChangeListener; private Section settingsSection; private Composite settingsComposite; private Point oldSize; private Font categoryFont; private Action newsWarning; private ToolBarManager newsToolBarManager; private ToolBarManager blogsToolBarManager; private Action blogsWarning; private ToolBarManager tutorialsToolBarManager; public GettingStartedPage(FormEditor editor) { super(editor, ID, "Getting Started"); } @Override protected void createFormContent(IManagedForm managedForm) { super.createFormContent(managedForm); toolkit = managedForm.getToolkit(); form = managedForm.getForm(); Composite body = form.getBody(); GridLayout gridLayout = new GridLayout(2, true); gridLayout.horizontalSpacing = 7; body.setLayout(gridLayout); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); body.setLayoutData(gd); toolkit.paintBordersFor(body); Composite left = createComposite(toolkit, body); createProjectsSection(toolkit, left); createTutorialsSection(toolkit, left); createDocumentationSection(toolkit, left); createSettingsSection(toolkit, left); toolkit.paintBordersFor(left); Composite right = createComposite(toolkit, body); createNewsSection(toolkit, right); createBlogsSection(toolkit, right); toolkit.paintBordersFor(right); final ControlAdapter controlAdapter = new ControlAdapter() { @Override public void controlResized(ControlEvent e) { resize(); } }; form.addControlListener(controlAdapter); form.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { form.removeControlListener(controlAdapter); form.removeDisposeListener(this); } }); resize(); } private void createBlogsSection(FormToolkit toolkit, Composite parent) { blogsSection = createSection(toolkit, parent, "Blogs", ExpandableComposite.TITLE_BAR | ExpandableComposite.EXPANDED | ExpandableComposite.TWISTIE); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false); blogsSection.setLayoutData(gd); createBlogsToolbar(toolkit, blogsSection); blogsScrollComposite = new ScrolledComposite(blogsSection, SWT.V_SCROLL); gd = new GridData(SWT.FILL, SWT.FILL, true, false); blogsScrollComposite.setLayoutData(gd); blogsScrollComposite.setLayout(new GridLayout()); blogsPageBook = new PageBook(blogsScrollComposite, SWT.WRAP); gd = new GridData(SWT.FILL, SWT.FILL, true, false); blogsPageBook.setLayoutData(gd); blogsScrollComposite.setContent(blogsPageBook); blogsScrollComposite.setExpandVertical(true); blogsScrollComposite.setExpandHorizontal(true); blogsScrollComposite.setAlwaysShowScrollBars(false); blogsNoteText = createNoteText(toolkit, blogsPageBook); blogsLoadingComposite = createLoadingComposite(toolkit, blogsPageBook); blogsExceptionText = createExceptionText(toolkit, blogsPageBook); blogsComposite = toolkit.createComposite(blogsPageBook, SWT.NONE); blogsComposite.setLayout(new TableWrapLayout()); GridDataFactory.fillDefaults().grab(true, false).applyTo(blogsComposite); blogsSection.setClient(blogsScrollComposite); blogsSection.addExpansionListener(new ExpansionAdapter() { @Override public void expansionStateChanged(ExpansionEvent e) { resize(true); } }); showLoading(blogsPageBook, blogsLoadingComposite, blogsScrollComposite); blogsPageBook.pack(true); RefreshBlogsJob job = RefreshBlogsJob.INSTANCE; job.setException(null); if (job.getEntries().size() > 0) { job.setNeedsRefresh(true); refreshBlogs(); job.setNeedsRefresh(false); } refreshBlogsJobChangeListener = new RefreshBlogsJobChangeListener(); job.addJobChangeListener(refreshBlogsJobChangeListener); job.schedule(); } private void createNewsSection(FormToolkit toolkit, Composite parent) { newsSection = createSection(toolkit, parent, "News", ExpandableComposite.TITLE_BAR | ExpandableComposite.EXPANDED | ExpandableComposite.TWISTIE); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false); newsSection.setLayoutData(gd); createNewsToolbar(toolkit, newsSection); newsScrollComposite = new ScrolledComposite(newsSection, SWT.V_SCROLL); gd = new GridData(SWT.FILL, SWT.FILL, true, false); newsScrollComposite.setLayoutData(gd); newsScrollComposite.setLayout(new GridLayout()); newsPageBook = new PageBook(newsScrollComposite, SWT.WRAP); gd = new GridData(SWT.FILL, SWT.FILL, true, false); newsPageBook.setLayoutData(gd); newsScrollComposite.setContent(newsPageBook); newsScrollComposite.setExpandVertical(true); newsScrollComposite.setExpandHorizontal(true); newsScrollComposite.setAlwaysShowScrollBars(false); newsNoteText = createNoteText(toolkit, newsPageBook); newsLoadingComposite = createLoadingComposite(toolkit, newsPageBook); newsExceptionText = createExceptionText(toolkit, newsPageBook); newsComposite = toolkit.createComposite(newsPageBook, SWT.NONE); newsComposite.setLayout(new TableWrapLayout()); GridDataFactory.fillDefaults().grab(true, false).applyTo(newsComposite); newsSection.setClient(newsScrollComposite); newsSection.addExpansionListener(new ExpansionAdapter() { @Override public void expansionStateChanged(ExpansionEvent e) { resize(true); } }); showLoading(newsPageBook, newsLoadingComposite, newsScrollComposite); newsPageBook.pack(true); AbstractRefreshJob job = RefreshNewsJob.INSTANCE; job.setException(null); if (job.getEntries().size() > 0) { job.setNeedsRefresh(true); refreshNews(); job.setNeedsRefresh(false); } refreshNewsJobChangeListener = new RefreshNewsJobChangeListener(); job.addJobChangeListener(refreshNewsJobChangeListener); job.schedule(); } private FormText createExceptionText(FormToolkit toolkit, Composite parent) { FormText formText = toolkit.createFormText(parent, true); GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false); formText.setLayoutData(gd); return formText; } private FormText createNoteText(FormToolkit toolkit, Composite parent) { FormText formText = toolkit.createFormText(parent, true); GridData gd = new GridData(GridData.FILL, GridData.FILL, false, false); formText.setLayoutData(gd); formText.setText("<form><p>" + "<img href=\"image\"/>" + " No entries found." + "</p></form>", true, false); Image image = JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING); formText.setImage("image", image); return formText; } private void createBlogsToolbar(FormToolkit toolkit, Section section) { Composite headerComposite = toolkit.createComposite(section, SWT.NONE); RowLayout rowLayout = new RowLayout(); rowLayout.marginTop = 0; rowLayout.marginBottom = 0; headerComposite.setLayout(rowLayout); headerComposite.setBackground(null); blogsToolBarManager = new ToolBarManager(SWT.FLAT | SWT.HORIZONTAL); blogsToolBarManager.createControl(headerComposite); blogsWarning = new Action("Warning", JBossCentralActivator.getImageDescriptor("/icons/nwarning.gif")) { }; blogsWarning.setId(BLOGS_WARNING_ID); blogsWarning.setActionDefinitionId(BLOGS_WARNING_ID); blogsToolBarManager.add(blogsWarning); setItemVisible(blogsToolBarManager, BLOGS_WARNING_ID, false); CommandContributionItem item = JBossCentralActivator.createContributionItem(getSite(), "org.jboss.tools.central.openJBossBlogs"); blogsToolBarManager.add(item); item = JBossCentralActivator.createContributionItem(getSite(), "org.jboss.tools.central.refreshJBossBlogs"); blogsToolBarManager.add(item); blogsToolBarManager.update(true); section.setTextClient(headerComposite); } private void createNewsToolbar(FormToolkit toolkit, Section section) { Composite headerComposite = toolkit.createComposite(section, SWT.NONE); RowLayout rowLayout = new RowLayout(); rowLayout.marginTop = 0; rowLayout.marginBottom = 0; headerComposite.setLayout(rowLayout); headerComposite.setBackground(null); newsToolBarManager = new ToolBarManager(SWT.FLAT | SWT.HORIZONTAL); newsToolBarManager.createControl(headerComposite); newsWarning = new Action("Warning", JBossCentralActivator.getImageDescriptor("/icons/nwarning.gif")) { }; newsWarning.setId(NEWS_WARNING_ID); newsWarning.setActionDefinitionId(NEWS_WARNING_ID); newsToolBarManager.add(newsWarning); setItemVisible(newsToolBarManager, NEWS_WARNING_ID, false); CommandContributionItem item = JBossCentralActivator.createContributionItem(getSite(), "org.jboss.tools.central.openJBossNews"); newsToolBarManager.add(item); item = JBossCentralActivator.createContributionItem(getSite(), "org.jboss.tools.central.openJBossToolsTwitter"); newsToolBarManager.add(item); item = JBossCentralActivator.createContributionItem(getSite(), "org.jboss.tools.central.refreshJBossNews"); newsToolBarManager.add(item); newsToolBarManager.update(true); section.setTextClient(headerComposite); } protected void setItemVisible(ToolBarManager toolBarManager, String id, boolean value) { IContributionItem[] items = toolBarManager.getItems(); for (IContributionItem item : items) { if (id.equals(item.getId())) { item.setVisible(value); } } } private void createTutorialsSection(FormToolkit toolkit, Composite parent) { tutorialsSection = createSection(toolkit, parent, "Project Examples", ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED); GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false); tutorialsSection.setLayoutData(gd); createTutorialsToolbar(toolkit, tutorialsSection); tutorialScrollComposite = new ScrolledComposite(tutorialsSection, SWT.V_SCROLL); gd = new GridData(SWT.FILL, SWT.FILL, false, false); tutorialScrollComposite.setLayoutData(gd); tutorialScrollComposite.setLayout(new GridLayout()); toolkit.adapt(tutorialScrollComposite); tutorialPageBook = new PageBook(tutorialScrollComposite, SWT.WRAP); gd = new GridData(SWT.FILL, SWT.FILL, false, false); tutorialPageBook.setLayoutData(gd); tutorialScrollComposite.setContent(tutorialPageBook); tutorialScrollComposite.setExpandVertical(true); tutorialScrollComposite.setExpandHorizontal(true); tutorialScrollComposite.setAlwaysShowScrollBars(false); tutorialsNoteText = createNoteText(toolkit, tutorialPageBook); tutorialsLoadingComposite = createLoadingComposite(toolkit, tutorialPageBook); tutorialsExceptionText = createExceptionText(toolkit, tutorialPageBook); tutorialsComposite = toolkit.createComposite(tutorialPageBook, SWT.NONE); tutorialsComposite.setLayout(new GridLayout()); gd = new GridData(SWT.FILL, SWT.FILL, false, false); tutorialsComposite.setLayoutData(gd); tutorialsSection.setClient(tutorialScrollComposite); tutorialsSection.addExpansionListener(new ExpansionAdapter() { @Override public void expansionStateChanged(ExpansionEvent e) { resize(true); } }); showLoading(tutorialPageBook, tutorialsLoadingComposite, tutorialScrollComposite); tutorialPageBook.pack(true); RefreshTutorialsJob refreshTutorialsJob = RefreshTutorialsJob.INSTANCE; refreshTutorialsJobChangeListener = new RefreshTutorialsJobChangeListener(); refreshTutorialsJob.addJobChangeListener(refreshTutorialsJobChangeListener); refreshTutorialsJob.schedule(); } private void createTutorialsToolbar(FormToolkit toolkit, Section section) { Composite headerComposite = toolkit.createComposite(section, SWT.NONE); RowLayout rowLayout = new RowLayout(); rowLayout.marginTop = 0; rowLayout.marginBottom = 0; headerComposite.setLayout(rowLayout); headerComposite.setBackground(null); tutorialsToolBarManager = new ToolBarManager(SWT.FLAT | SWT.HORIZONTAL); tutorialsToolBarManager.createControl(headerComposite); CommandContributionItem item = JBossCentralActivator.createContributionItem(getSite(), "org.jboss.tools.central.newProjectExamplesWizard"); tutorialsToolBarManager.add(item); item = JBossCentralActivator.createContributionItem(getSite(), "org.jboss.tools.runtime.preferences"); tutorialsToolBarManager.add(item); item = JBossCentralActivator.createContributionItem(getSite(), "org.jboss.tools.wtp.runtime.preferences"); tutorialsToolBarManager.add(item); item = JBossCentralActivator.createContributionItem(getSite(), "org.jboss.tools.central.refreshJBossTutorials"); tutorialsToolBarManager.add(item); //Action action = new DownloadRuntimeAction("Download and Install JBoss AS 7.0.1", JBossCentralActivator.imageDescriptorFromPlugin(JBossCentralActivator.PLUGIN_ID, "/icons/jbossas7.png"), "org.jboss.tools.runtime.core.as.701"); //toolBarManager.add(action); tutorialsToolBarManager.update(true); section.setTextClient(headerComposite); } public void createProjectsSection(FormToolkit toolkit, Composite parent) { projectsSection = createSection(toolkit, parent, "Create Projects", ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED); projectsSection.setText("Create Projects"); projectsSection.setLayout(new GridLayout()); GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false); projectsSection.setLayoutData(gd); Composite headerComposite = toolkit.createComposite(projectsSection, SWT.NONE); RowLayout rowLayout = new RowLayout(); rowLayout.marginTop = 0; rowLayout.marginBottom = 0; headerComposite.setLayout(rowLayout); headerComposite.setBackground(null); ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT | SWT.HORIZONTAL); toolBarManager.createControl(headerComposite); IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); newWizardDropDownAction = IDEActionFactory.NEW_WIZARD_DROP_DOWN.create(window); toolBarManager.add(newWizardDropDownAction); toolBarManager.update(true); projectsSection.setTextClient(headerComposite); projectsSection.addExpansionListener(new ExpansionAdapter() { @Override public void expansionStateChanged(ExpansionEvent e) { resize(true); } }); projectsComposite = toolkit.createComposite(projectsSection); GridLayout layout = new GridLayout(2, true); layout.horizontalSpacing = 10; projectsComposite.setLayout(layout); GridDataFactory.fillDefaults().grab(true, true).applyTo(projectsComposite); IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry(); IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint("org.eclipse.ui.newWizards"); IExtension[] extensions = extensionPoint.getExtensions(); List<String> sortedWizardIds = ProjectExamplesActivator.getDefault().getConfigurator().getWizardIds(); Map<String, IConfigurationElement> wizards = new HashMap<String, IConfigurationElement>( sortedWizardIds.size()); for (IExtension extension : extensions) { IConfigurationElement[] elements = extension.getConfigurationElements(); for (IConfigurationElement element : elements) { String id = element.getAttribute("id"); if (sortedWizardIds.contains(id) && wizards.get(id) == null) { wizards.put(id, element); } } } for (String wid : sortedWizardIds) { IConfigurationElement element = wizards.get(wid); if (element != null) { createProjectLink(toolkit, projectsComposite, element); } } projectsSection.setClient(projectsComposite); } private void createProjectLink(FormToolkit toolkit, Composite composite, final IConfigurationElement element) { if (element == null) { return; } String name = element.getAttribute("name"); String id = element.getAttribute("id"); if (name == null || id == null) { return; } String iconPath = element.getAttribute("icon"); Image image = null; if (iconPath != null) { IContributor contributor = element.getContributor(); String pluginId = contributor.getName(); ImageDescriptor imageDescriptor = AbstractUIPlugin.imageDescriptorFromPlugin(pluginId, iconPath); if (imageDescriptor != null) { image = JBossCentralActivator.getDefault().getImage(imageDescriptor); } } ImageHyperlink link = toolkit.createImageHyperlink(composite, SWT.NONE); link.setText(name); if (image != null) { link.setImage(image); } GridDataFactory.fillDefaults().grab(true, false).applyTo(link); link.addHyperlinkListener(new HyperlinkAdapter() { @Override public void linkActivated(HyperlinkEvent e) { try { Object object = createExtension(element); if (object instanceof INewWizard) { INewWizard wizard = (INewWizard) object; ISelection selection = getSite().getSelectionProvider().getSelection(); if (selection instanceof IStructuredSelection) { wizard.init(PlatformUI.getWorkbench(), (IStructuredSelection) selection); } WizardDialog dialog = new WizardDialog(getSite().getShell(), wizard); dialog.open(); } } catch (CoreException e1) { JBossCentralActivator.log(e1); } } }); } public static Object createExtension(final IConfigurationElement element) throws CoreException { if (element == null) { return null; } try { Bundle bundle = Platform.getBundle(element.getContributor().getName()); if (isActive(bundle)) { return element.createExecutableExtension(CLASS_ATTRIBUTE); } final Object[] ret = new Object[1]; final CoreException[] exc = new CoreException[1]; BusyIndicator.showWhile(null, new Runnable() { public void run() { try { ret[0] = element.createExecutableExtension(CLASS_ATTRIBUTE); } catch (CoreException e) { exc[0] = e; } } }); if (exc[0] != null) { throw exc[0]; } return ret[0]; } catch (InvalidRegistryObjectException e) { throw new CoreException(new Status(IStatus.ERROR, JBossCentralActivator.PLUGIN_ID, IStatus.ERROR, "Cannot create extension", e)); } } private void displayTutorialLinks(final Collection<ProjectExample> tutorials, final Composite composite, boolean addTooltips) { for (final ProjectExample tutorial : tutorials) { FormText tutorialText = toolkit.createFormText(composite, true); configureTutorialText(tutorialText, tutorial); if (addTooltips) { hookTooltip(tutorialText, tutorial); } } } private static boolean isActive(Bundle bundle) { if (bundle == null) { return false; } return bundle.getState() == Bundle.ACTIVE; } public void createDocumentationSection(FormToolkit toolkit, Composite parent) { documentationSection = createSection(toolkit, parent, "Documentation", ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED); GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false); documentationSection.setLayoutData(gd); documentationComposite = toolkit.createComposite(documentationSection); GridLayout layout = new GridLayout(2, true); layout.horizontalSpacing = 30; documentationComposite.setLayout(layout); GridDataFactory.fillDefaults().grab(true, true).applyTo(documentationComposite); addHyperlink(toolkit, documentationComposite, "New and Noteworthy", "http://docs.jboss.org/tools/whatsnew/"); addHyperlink(toolkit, documentationComposite, "User Forum", "http://community.jboss.org/en/tools?view=discussions"); addHyperlink(toolkit, documentationComposite, "Reference", "http://docs.jboss.org/tools/latest/"); addHyperlink(toolkit, documentationComposite, "Developer Forum", "http://community.jboss.org/en/tools/dev?view=discussions"); addHyperlink(toolkit, documentationComposite, "FAQ", "http://www.jboss.org/tools/docs/faq"); addHyperlink(toolkit, documentationComposite, "Wiki", "http://community.jboss.org/wiki/JBossTools"); addHyperlink(toolkit, documentationComposite, "Screencasts", "http://docs.jboss.org/tools/movies/"); addHyperlink(toolkit, documentationComposite, "Issue Tracker", "https://issues.jboss.org/browse/JBIDE"); documentationSection.setClient(documentationComposite); documentationSection.addExpansionListener(new ExpansionAdapter() { @Override public void expansionStateChanged(ExpansionEvent e) { resize(true); } }); } public void createSettingsSection(FormToolkit toolkit, Composite parent) { settingsSection = createSection(toolkit, parent, "Settings", ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED); GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false); settingsSection.setLayoutData(gd); settingsComposite = toolkit.createComposite(settingsSection); GridLayout layout = new GridLayout(1, true); layout.horizontalSpacing = 30; settingsComposite.setLayout(layout); GridDataFactory.fillDefaults().grab(true, true).applyTo(settingsComposite); Button showOnStartup = toolkit.createButton(settingsComposite, "Show on Startup", SWT.CHECK); showOnStartup.setLayoutData(new GridData(SWT.BEGINNING, SWT.BOTTOM, false, false)); showOnStartup.setBackground(settingsComposite.getBackground()); showOnStartup.setSelection(JBossCentralActivator.getDefault().showJBossCentralOnStartup()); showOnStartup.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IEclipsePreferences preferences = JBossCentralActivator.getDefault().getPreferences(); boolean showOnStartup = preferences.getBoolean(JBossCentralActivator.SHOW_JBOSS_CENTRAL_ON_STARTUP, JBossCentralActivator.SHOW_JBOSS_CENTRAL_ON_STARTUP_DEFAULT_VALUE); preferences.putBoolean(JBossCentralActivator.SHOW_JBOSS_CENTRAL_ON_STARTUP, !showOnStartup); JBossCentralActivator.getDefault().savePreferences(); } }); settingsSection.setClient(settingsComposite); } private void addHyperlink(FormToolkit toolkit, Composite composite, String text, final String url) { Hyperlink link = toolkit.createHyperlink(composite, text, SWT.NONE); GridDataFactory.fillDefaults().applyTo(link); link.addHyperlinkListener(new HyperlinkAdapter() { public void linkActivated(HyperlinkEvent e) { JBossCentralActivator.openUrl(url, getSite().getShell()); } }); } @Override public void dispose() { if (newWizardDropDownAction != null) { newWizardDropDownAction.dispose(); newWizardDropDownAction = null; } if (newsToolBarManager != null) { newsToolBarManager.dispose(); newsToolBarManager = null; } if (blogsToolBarManager != null) { blogsToolBarManager.dispose(); blogsToolBarManager = null; } if (tutorialsToolBarManager != null) { tutorialsToolBarManager.dispose(); tutorialsToolBarManager = null; } if (refreshBlogsJobChangeListener != null) { RefreshBlogsJob.INSTANCE.removeJobChangeListener(refreshBlogsJobChangeListener); refreshBlogsJobChangeListener = null; } if (refreshNewsJobChangeListener != null) { RefreshNewsJob.INSTANCE.removeJobChangeListener(refreshNewsJobChangeListener); refreshNewsJobChangeListener = null; } if (refreshTutorialsJobChangeListener != null) { RefreshTutorialsJob.INSTANCE.removeJobChangeListener(refreshTutorialsJobChangeListener); refreshTutorialsJobChangeListener = null; } super.dispose(); } public boolean showLoading(final PageBook pageBook, final Composite composite, final ScrolledComposite scrolledComposite) { if (pageBook.isDisposed()) { return false; } Display display = getDisplay(); display.syncExec(new Runnable() { @Override public void run() { pageBook.showPage(composite); setBusyIndicator(composite, true); form.reflow(true); form.redraw(); if (pageBook != tutorialPageBook) { recomputeScrollComposite(scrolledComposite, pageBook); } } }); return true; } private Image getFeedsImage() { return JBossCentralActivator.getDefault().getImage("/icons/feedsLink.gif"); } private void recomputeScrollComposite(ScrolledComposite composite, PageBook pageBook) { Rectangle r = composite.getClientArea(); composite.setMinSize(pageBook.computeSize(r.width, SWT.DEFAULT)); } public void showNote(final PageBook pageBook, final FormText noteText, final ScrolledComposite scrolledComposite) { if (pageBook.isDisposed()) { return; } Display display = getDisplay(); display.syncExec(new Runnable() { @Override public void run() { pageBook.showPage(noteText); form.reflow(true); form.redraw(); recomputeScrollComposite(scrolledComposite, pageBook); } }); } private void showException(PageBook pageBook, FormText exceptionText, Throwable e) { JBossCentralActivator.log(e); String message = StringEscapeUtils.escapeXml(e.getMessage()); String text = JBossCentralActivator.FORM_START_TAG + "<img href=\"image\"/> " + message + JBossCentralActivator.FORM_END_TAG; exceptionText.setText(text, true, false); Image image = JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING); exceptionText.setImage("image", image); pageBook.showPage(exceptionText); } public void refreshBlogs() { RefreshBlogsJob job = RefreshBlogsJob.INSTANCE; if (job.getState() == Job.NONE) { if (job.getException() != null) { if (job.getEntries().size() <= 0) { showException(blogsPageBook, blogsExceptionText, job.getException()); return; } } List<FeedsEntry> entries = job.getEntries(); if (entries == null || entries.size() == 0) { showNote(blogsPageBook, blogsNoteText, blogsScrollComposite); return; } if (job.needsRefresh()) { showEntries(entries, blogsComposite, blogsPageBook, blogsScrollComposite); } } } public void refreshNews() { AbstractRefreshJob job = RefreshNewsJob.INSTANCE; if (job.getState() == Job.NONE) { if (job.getException() != null) { if (job.getEntries().size() <= 0) { showException(newsPageBook, newsExceptionText, job.getException()); return; } } List<FeedsEntry> entries = job.getEntries(); if (entries.size() == 0) { showNote(newsPageBook, newsNoteText, newsScrollComposite); return; } if (job.needsRefresh()) { showEntries(entries, newsComposite, newsPageBook, newsScrollComposite); } } } public void refreshTutorials() { RefreshTutorialsJob job = RefreshTutorialsJob.INSTANCE; if (job.getException() != null) { showException(tutorialPageBook, tutorialsExceptionText, job.getException()); return; } Map<ProjectExampleCategory, List<ProjectExample>> categories = job.getTutorialCategories(); if (categories == null || categories.size() == 0) { showNote(tutorialPageBook, tutorialsNoteText, tutorialScrollComposite); return; } showTutorials(categories); resize(true); } private void showTutorials(Map<ProjectExampleCategory, List<ProjectExample>> categories) { disposeChildren(tutorialsComposite); List<ProjectExampleCategory> sortedCategories = new ArrayList<ProjectExampleCategory>(categories.keySet()); Collections.sort(sortedCategories); for (final ProjectExampleCategory category : sortedCategories) { int style = ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE; if (expandedCategories.contains(category)) { style |= ExpandableComposite.EXPANDED; } final CategoryExpandableComposite categoryComposite = new CategoryExpandableComposite( tutorialsComposite, toolkit.getOrientation(), style); categoryComposite.setFont(getBoldFont(categoryComposite.getFont())); categoryComposite.setTitleBarForeground(toolkit.getColors().getColor(IFormColors.TB_TOGGLE)); categoryComposite.setText(category.getName()); GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false); categoryComposite.setLayoutData(gd); categoryComposite.setLayout(new GridLayout()); final Composite composite = toolkit.createComposite(categoryComposite); gd = new GridData(SWT.FILL, SWT.FILL, false, false); composite.setLayoutData(gd); composite.setLayout(new GridLayout(1, false)); categoryComposite.addExpansionListener(new ExpansionAdapter() { public void expansionStateChanged(ExpansionEvent e) { if (e.getState()) { expandedCategories.add(category); } else { expandedCategories.remove(category); } resize(true); } }); displayTutorialLinks(categories.get(category), composite, true); categoryComposite.setClient(composite); String description = category.getDescription(); if (description != null && !description.isEmpty() && categoryComposite.getControl() != null && !categoryComposite.getControl().isDisposed()) { final DescriptionToolTip toolTip = new DescriptionToolTip(categoryComposite.getControl(), description); toolTip.activate(); } } tutorialPageBook.showPage(tutorialsComposite); tutorialPageBook.layout(true, true); form.reflow(true); resize(); } private Font getBoldFont(Font font) { if (categoryFont != null) { return categoryFont; } if (font == null || toolkit == null || toolkit.getColors() == null) { return null; } categoryFont = FormFonts.getInstance().getBoldFont(toolkit.getColors().getDisplay(), font); return categoryFont; } private void hookTooltip(FormText tutorialText, ProjectExample tutorial) { final String description = JBossCentralActivator.getDefault().getDescription(tutorial); if (description != null && !description.isEmpty()) { DescriptionToolTip toolTip = new DescriptionToolTip(tutorialText, description); toolTip.activate(); } } protected void configureTutorialText(FormText tutorialText, final ProjectExample tutorial) { StringBuilder buffer = new StringBuilder(); buffer.append(JBossCentralActivator.FORM_START_TAG); buffer.append("<img href=\"image\"/> "); buffer.append("<a href=\"link\">"); buffer.append(tutorial.getShortDescription()); buffer.append("</a> "); buffer.append(JBossCentralActivator.FORM_END_TAG); tutorialText.setText(buffer.toString(), true, false); String iconPath = tutorial.getIconPath(); if (iconPath != null) { Image image = JBossCentralActivator.getDefault().getImage(iconPath); if (image != null) { tutorialText.setImage("image", image); } } tutorialText.addHyperlinkListener(new HyperlinkAdapter() { @Override public void linkActivated(HyperlinkEvent e) { Object object = e.data; if (object instanceof String) { NewProjectExamplesWizard2 wizard = new NewProjectExamplesWizard2(tutorial); WizardDialog dialog = new WizardDialog(getSite().getShell(), wizard); dialog.open(); refreshTutorials(); } } }); } private void disposeChildren(Composite composite) { Control[] children = composite.getChildren(); for (Control child : children) { if (child instanceof Composite) { disposeChildren((Composite) child); child.dispose(); } else { child.dispose(); } } } private void showEntries(List<FeedsEntry> entries, Composite composite, PageBook pageBook, ScrolledComposite scrollable) { int i = 0; disposeChildren(composite); for (final FeedsEntry entry : entries) { if (i++ > JBossCentralActivator.MAX_FEEDS) { return; } String text = entry.getFormString(false); FormText formText = toolkit.createFormText(composite, true); TableWrapData td = new TableWrapData(); td.indent = 2; formText.setLayoutData(td); try { formText.setText(text, true, true); } catch (IllegalArgumentException se) { try { text = entry.getFormString(true); formText.setText(text, true, true); } catch (IllegalArgumentException se2) { formText.dispose(); formText = toolkit.createFormText(composite, false); formText.setLayoutData(td); try { formText.setText( "Problem rendering entry - " + StringEscapeUtils.unescapeHtml(se.getMessage()), false, false); } catch (Exception e1) { JBossCentralActivator.log(se); } } continue; } formText.setFont("default", JFaceResources.getDefaultFont()); formText.setFont("date", JFaceResources.getDefaultFont()); formText.setColor("date", JFaceColors.getHyperlinkText(getDisplay())); formText.setFont("description", JFaceResources.getDefaultFont()); formText.setColor("author", JFaceColors.getHyperlinkText(getDisplay())); formText.setImage("image", getFeedsImage()); if (JBossCentralActivator.isInternalWebBrowserAvailable() && entry.getDescription() != null && !entry.getDescription().isEmpty()) { ToolTip toolTip = new FeedsToolTip(formText, entry.getDate() + " " + entry.getDescription()); toolTip.activate(); } formText.addHyperlinkListener(new HyperlinkAdapter() { @Override public void linkActivated(HyperlinkEvent e) { Object link = e.data; if (link instanceof String) { Shell shell = PlatformUI.getWorkbench().getDisplay().getActiveShell(); JBossCentralActivator.openUrl((String) link, shell); } } }); } pageBook.showPage(composite); pageBook.layout(true, true); form.reflow(true); recomputeScrollComposite(scrollable, pageBook); resize(); } private void resize() { resize(false); } protected void resize(boolean force) { if (blogsSection == null) { return; } Point size; size = form.getSize(); size.y = form.getBody().getSize().y; if (!force && size.equals(oldSize)) { return; } oldSize = size; GridData gd; int widthHint = size.x / 2 - 20; gd = (GridData) newsSection.getLayoutData(); if (newsSection.isExpanded()) { if (blogsSection.isExpanded()) { gd.heightHint = size.y / 2 - 20; } else { gd.heightHint = size.y - 40; } } else { gd.heightHint = 20; } gd.widthHint = widthHint; gd.grabExcessVerticalSpace = false; gd = (GridData) blogsSection.getLayoutData(); if (blogsSection.isExpanded()) { if (newsSection.isExpanded()) { gd.heightHint = size.y / 2 - 20; } else { gd.heightHint = size.y - 40; } } else { gd.heightHint = 20; } gd.widthHint = widthHint; gd.grabExcessVerticalSpace = false; gd = (GridData) documentationSection.getLayoutData(); gd.widthHint = widthHint; gd.grabExcessVerticalSpace = false; gd = (GridData) settingsSection.getLayoutData(); gd.widthHint = widthHint; gd.grabExcessVerticalSpace = false; gd = (GridData) projectsSection.getLayoutData(); gd.widthHint = widthHint; gd.grabExcessVerticalSpace = false; gd = (GridData) tutorialsSection.getLayoutData(); Point computedSize = tutorialPageBook.computeSize(widthHint, SWT.DEFAULT); if (computedSize.y > (size.y / 3)) { gd.heightHint = size.y / 3; } else { gd.heightHint = SWT.DEFAULT; } gd.widthHint = widthHint; gd.grabExcessVerticalSpace = false; computedSize = tutorialPageBook.computeSize(widthHint, SWT.DEFAULT); tutorialScrollComposite.setMinSize(widthHint - 20, computedSize.y); recomputeScrollComposite(blogsScrollComposite, blogsPageBook); recomputeScrollComposite(newsScrollComposite, newsPageBook); form.layout(true, true); form.reflow(true); } private class RefreshBlogsJobChangeListener implements IJobChangeListener { @Override public void aboutToRun(IJobChangeEvent event) { } @Override public void awake(IJobChangeEvent event) { } @Override public void done(IJobChangeEvent event) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { if (blogsLoadingComposite == null || blogsLoadingComposite.isDisposed()) { return; } setBusyIndicator(blogsLoadingComposite, false); refreshBlogs(); setItemVisible(blogsToolBarManager, BLOGS_WARNING_ID, false); RefreshBlogsJob job = RefreshBlogsJob.INSTANCE; if (job.getEntries().size() > 0 && job.getException() != null) { String tooltip = job.getException().getClass().getName() + ": " + job.getException().getLocalizedMessage(); blogsWarning.setToolTipText(tooltip); setItemVisible(blogsToolBarManager, BLOGS_WARNING_ID, true); } blogsToolBarManager.update(true); blogsSection.layout(true, true); } }); } @Override public void running(IJobChangeEvent event) { } @Override public void scheduled(IJobChangeEvent event) { if (RefreshBlogsJob.INSTANCE.getEntries().size() <= 0) { showLoading(blogsPageBook, blogsLoadingComposite, blogsScrollComposite); } } @Override public void sleeping(IJobChangeEvent event) { } } private class RefreshTutorialsJobChangeListener implements IJobChangeListener { @Override public void aboutToRun(IJobChangeEvent event) { } @Override public void awake(IJobChangeEvent event) { } @Override public void done(IJobChangeEvent event) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { if (tutorialsLoadingComposite == null || tutorialsLoadingComposite.isDisposed()) { return; } setBusyIndicator(tutorialsLoadingComposite, false); refreshTutorials(); } }); } @Override public void running(IJobChangeEvent event) { } @Override public void scheduled(IJobChangeEvent event) { RefreshTutorialsJob.INSTANCE.setException(null); showLoading(tutorialPageBook, tutorialsLoadingComposite, tutorialScrollComposite); } @Override public void sleeping(IJobChangeEvent event) { } } private class RefreshNewsJobChangeListener implements IJobChangeListener { @Override public void aboutToRun(IJobChangeEvent event) { } @Override public void awake(IJobChangeEvent event) { } @Override public void done(IJobChangeEvent event) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { if (newsLoadingComposite == null || newsLoadingComposite.isDisposed()) { return; } setBusyIndicator(newsLoadingComposite, false); refreshNews(); setItemVisible(newsToolBarManager, NEWS_WARNING_ID, false); RefreshNewsJob job = RefreshNewsJob.INSTANCE; if (job.getEntries().size() > 0 && job.getException() != null) { String tooltip = job.getException().getClass().getName() + ": " + job.getException().getLocalizedMessage(); newsWarning.setToolTipText(tooltip); setItemVisible(newsToolBarManager, NEWS_WARNING_ID, true); } newsToolBarManager.update(true); newsSection.layout(true, true); } }); } @Override public void running(IJobChangeEvent event) { } @Override public void scheduled(IJobChangeEvent event) { if (RefreshNewsJob.INSTANCE.getEntries().size() <= 0) { showLoading(newsPageBook, newsLoadingComposite, newsScrollComposite); } } @Override public void sleeping(IJobChangeEvent event) { } } private class CategoryExpandableComposite extends ExpandableComposite { public CategoryExpandableComposite(Composite parent, int style, int expansionStyle) { super(parent, style, expansionStyle); setMenu(tutorialsComposite.getMenu()); toolkit.adapt(this, true, true); } public Control getControl() { return textLabel; } } }