Java tutorial
/* * Copyright (C) 2015 The Android Open Source Project * * 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.android.tools.idea.structure.services.view; import com.android.tools.idea.structure.EditorPanel; import com.android.tools.idea.structure.services.DeveloperService; import com.android.tools.idea.structure.services.DeveloperServiceMetadata; import com.android.tools.idea.structure.services.ServiceContext; import com.android.tools.idea.ui.properties.BindingsManager; import com.android.tools.idea.ui.properties.InvalidationListener; import com.android.tools.idea.ui.properties.ObservableValue; import com.android.tools.idea.ui.properties.swing.SelectedProperty; import com.android.tools.idea.ui.properties.swing.VisibleProperty; import com.android.utils.HtmlBuilder; import com.google.common.base.Joiner; import com.intellij.openapi.ui.Messages; import com.intellij.ui.HyperlinkAdapter; import com.intellij.ui.HyperlinkLabel; import com.intellij.util.IconUtil; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.event.HyperlinkEvent; import java.awt.*; import java.io.IOException; import java.net.URI; import java.util.List; import static com.android.tools.idea.ui.properties.expressions.bool.BooleanExpressions.not; /** * Panel that provides a UI view onto a {@link DeveloperServiceMetadata}. */ public final class DeveloperServicePanel extends EditorPanel { public static final String DELETE_SERVICE_TITLE = "Confirm Uninstall Service"; public static final String DELETE_SERVICE_MESSAGE = "You are about to uninstall the %1$s service. This will remove the following dependencies:\n" + "\n" + "%2$s\n" + "\n" + "This may cause compile errors that you'll have to fix manually. Continue?"; private JPanel myRootPanel; private JLabel myHeaderLabel; private JPanel myDetailsPanel; private JLabel myIcon; private JPanel myLinksPanel; private JPanel mySummaryPanel; private JPanel myOverviewPanel; private JCheckBox myEnabledCheckbox; private JPanel myCheckboxBorder; @NotNull private DeveloperService myService; @NotNull private BindingsManager myBindings = new BindingsManager(); public DeveloperServicePanel(@NotNull DeveloperService service) { super(new BorderLayout()); myService = service; ServiceContext context = service.getContext(); DeveloperServiceMetadata developerServiceMetadata = service.getMetadata(); initializeHeaderPanel(developerServiceMetadata); myDetailsPanel.add(service.getPanel()); initializeFooterPanel(developerServiceMetadata); final SelectedProperty enabledCheckboxSelected = new SelectedProperty(myEnabledCheckbox); myBindings.bind(new VisibleProperty(myDetailsPanel), enabledCheckboxSelected.and(not(context.installed()))); // This definition might be modified from the user interacting with the service earlier but not // yet committing to install it. myBindings.bind(enabledCheckboxSelected, context.installed().or(context.modified())); myEnabledCheckbox.setName("enableService"); enabledCheckboxSelected.addListener(new InvalidationListener() { @Override public void onInvalidated(@NotNull ObservableValue<?> sender) { if (enabledCheckboxSelected.get()) { if (!myService.getContext().installed().get()) { // User just selected a service which was previously uninstalled. This means we are // ready to edit it. myService.getContext().beginEditing(); } } else { if (myService.getContext().installed().get()) { // User just deselected a service which was previous installed String message = String.format(DELETE_SERVICE_MESSAGE, myService.getMetadata().getName(), Joiner.on('\n').join(myService.getMetadata().getDependencies())); int answer = Messages.showYesNoDialog(myService.getModule().getProject(), message, DELETE_SERVICE_TITLE, null); if (answer == Messages.YES) { myService.uninstall(); } else { enabledCheckboxSelected.set(true); } } else { // User just deselected a service they were editing but hadn't installed yet myService.getContext().cancelEditing(); } } } }); add(myRootPanel); } private void initializeHeaderPanel(@NotNull DeveloperServiceMetadata developerServiceMetadata) { HtmlBuilder htmlBuilder = new HtmlBuilder(); htmlBuilder.openHtmlBody(); htmlBuilder.addBold(developerServiceMetadata.getName()).newline(); htmlBuilder.add(developerServiceMetadata.getDescription()); htmlBuilder.closeHtmlBody(); myHeaderLabel.setText(htmlBuilder.getHtml()); myIcon.setIcon(IconUtil.toSize(developerServiceMetadata.getIcon(), myIcon.getWidth(), myIcon.getHeight())); URI learnMoreLink = developerServiceMetadata.getLearnMoreLink(); if (learnMoreLink != null) { addToLinkPanel("Learn More", learnMoreLink); } URI apiLink = developerServiceMetadata.getApiLink(); if (apiLink != null) { addToLinkPanel("API Documentation", apiLink); } } private void initializeFooterPanel(@NotNull DeveloperServiceMetadata developerServiceMetadata) { boolean panelHasContent = false; JPanel verticalFlowPanel = new JPanel(); verticalFlowPanel.setLayout(new BoxLayout(verticalFlowPanel, BoxLayout.PAGE_AXIS)); verticalFlowPanel.add(Box.createRigidArea(new Dimension(0, JBUI.scale(30)))); final HtmlBuilder htmlBuilder = new HtmlBuilder(); htmlBuilder.openHtmlBody(); htmlBuilder.add("Enabling this service will..."); htmlBuilder.beginList(); List<String> dependencies = developerServiceMetadata.getDependencies(); if (!dependencies.isEmpty()) { htmlBuilder.listItem().add("Add dependencies: ").addItalic(Joiner.on(", ").join(dependencies)); panelHasContent = true; } List<String> permissions = developerServiceMetadata.getPermissions(); if (!permissions.isEmpty()) { htmlBuilder.listItem().add("Add permissions: ").addItalic(Joiner.on(", ").join(permissions)); panelHasContent = true; } List<String> modifiedFiles = developerServiceMetadata.getModifiedFiles(); if (!modifiedFiles.isEmpty()) { htmlBuilder.listItem().add("Create/modify files: ").addItalic(Joiner.on(", ").join(modifiedFiles)); panelHasContent = true; } htmlBuilder.endList(); htmlBuilder.closeHtmlBody(); if (panelHasContent) { verticalFlowPanel.add(new JLabel(htmlBuilder.getHtml())); mySummaryPanel.add(verticalFlowPanel); } } private void addToLinkPanel(@NotNull String text, @NotNull final URI uri) { HyperlinkLabel hyperlinkLabel = new HyperlinkLabel(text); hyperlinkLabel.addHyperlinkListener(new HyperlinkAdapter() { @Override protected void hyperlinkActivated(HyperlinkEvent e) { try { Desktop.getDesktop().browse(uri); } catch (IOException ex) { // Don't care } } }); // Setting the padding on myLinksPanel puts in ugly leading space, so we instead space links // apart using invisible rigid areas instead. if (myLinksPanel.getComponentCount() > 0) { myLinksPanel.add(Box.createRigidArea(new Dimension(JBUI.scale(10), 0))); } myLinksPanel.add(hyperlinkLabel); } @Override public void apply() { myService.getContext().finishEditing(); if (!isModified()) { return; } myService.install(); } @Override public boolean isModified() { return myService.getContext().modified().get(); } public void dispose() { myDetailsPanel.removeAll(); } }