Java tutorial
/******************************************************************************* * Copyright (c) 2014 Mentor Graphics 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: * Mentor Graphics - initial API and implementation *******************************************************************************/ package com.codesourcery.installer.ui; import java.util.ArrayList; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.FontMetrics; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import com.codesourcery.installer.IInstallConsoleProvider; import com.codesourcery.installer.Installer; import com.codesourcery.installer.console.ConsoleListPrompter; import com.codesourcery.internal.installer.IInstallerImages; import com.codesourcery.installer.ui.InfoButton; import com.codesourcery.installer.ui.InfoButton.ElementColor; /** * A dialog that displays a list of choices. This dialog also provides * console support. */ public class ChoiceDialog extends Dialog implements IInstallConsoleProvider { /** Dialog element colors */ private Color[] colors = new Color[ElementColor.values().length]; /** Dialog background color */ private Color backgroundColor; /** Prompt foreground color*/ private Color promptColor; /** Dialog title font */ private Font titleFont; /** Choices to display */ private ArrayList<Option> options = new ArrayList<Option>(); /** Dialog title */ private String title; /** Dialog title text */ private String titleText; /** Dialog prompt text */ private String promptText; /** Default option or <code>null</code>*/ private Option defaultOption; /** Identifier of currently selected option or <code>null</code>*/ private String selectedOption; /** Console list prompter */ private ConsoleListPrompter<String> consoleList; /** Choice widths */ private int width = -1; /** * Constructor * * @param parentShell Parent shell or <code>null</code> to use for console * @param title Title for dialog */ public ChoiceDialog(Shell parentShell, String title) { super(parentShell); this.title = title; setShellStyle(getShellStyle() | SWT.RESIZE); } /** * Sets the text displayed in the title. * * @param titleText Title text or <code>null</code> */ public void setTitleText(String titleText) { this.titleText = titleText; } /** * Returns the text displayed in the title. * * @return Title text or <code>null</code> */ public String getTitleText() { return titleText; } /** * Sets the prompt text. * * @param promptText Prompt text */ public void setPromptText(String promptText) { this.promptText = promptText; } /** * Returns the prompt text. * * @return Prompt text */ public String getPromptText() { return promptText; } /** * Sets the maximum width of the dialog. * * @param width Width */ public void setWidth(int width) { this.width = width; } /** * Returns the maximum width of the dialog. * * @return Width */ public int getWidth() { return width; } /** * Adds a new option to display on the dialog. * * @param id Identifier for the option * @param image Image for the option or <code>null</code> * @param label Label for the option or <code>null</code> * @param description Description for the option or <code>null</code> */ public void addOption(String id, Image image, String label, String description) { options.add(new Option(id, image, label, description)); } /** * Returns an option. * * @param id Option identifier * @return Option or <code>null</code> */ private Option getOption(String id) { Option foundOption = null; for (Option option : options) { if (option.getId().equals(id)) { foundOption = option; break; } } return foundOption; } /** * Sets the default option. * * @param id Identifier of option to set as default */ public void setDefaultOption(String id) { defaultOption = getOption(id); } /** * Returns the selected option. * * @return Option identifier or <code>null</code> */ public String getSelection() { return selectedOption; } @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); // Set dialog icon newShell.setImage(Installer.getDefault().getImageRegistry().get(IInstallerImages.TITLE_ICON)); // Set title newShell.setText(title); } @Override protected Control createContents(Composite parent) { GridLayout layout; GridData data; if (width == -1) { GC gc = new GC(parent); gc.setFont(JFaceResources.getDialogFont()); FontMetrics fontMetrics = gc.getFontMetrics(); gc.dispose(); width = convertHorizontalDLUsToPixels(fontMetrics, 185); } // Initialize element colors initColors(); // Main area Composite area = new Composite(parent, SWT.NONE); layout = new GridLayout(1, true); layout.marginHeight = 5; layout.marginWidth = 0; layout.verticalSpacing = 0; area.setLayout(layout); area.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // Title text if (getTitleText() != null) { // Title text font FontData fontData = JFaceResources.getDialogFont().getFontData()[0]; fontData.setHeight(fontData.getHeight() + 2); titleFont = new Font(getShell().getDisplay(), fontData); // Title text area Composite titleArea = new Composite(area, SWT.NONE); layout = new GridLayout(1, true); titleArea.setLayout(layout); titleArea.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); // Title text label Label label = new Label(titleArea, SWT.WRAP); data = new GridData(SWT.FILL, SWT.CENTER, true, false); data.widthHint = getWidth(); label.setLayoutData(data); label.setText(getTitleText()); label.setFont(titleFont); // Separator label = new Label(titleArea, SWT.NONE); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); // Prompt if (getPromptText() != null) { label = new Label(titleArea, SWT.WRAP); label.setForeground(promptColor); data = new GridData(SWT.FILL, SWT.CENTER, true, false); data.widthHint = getWidth(); label.setLayoutData(data); label.setText(getPromptText()); label.setFont(titleFont); label.setForeground(promptColor); } } // Add choices for (Option option : options) { InfoButton button = new InfoButton(area, SWT.RADIO); button.setData(option); button.setImage(option.getImage()); button.setText(option.getLabel()); button.setDescription(option.getDescription()); data = new GridData(SWT.FILL, SWT.CENTER, true, false); data.widthHint = getWidth(); button.setLayoutData(data); // Set label colors for (int index = 0; index < colors.length; index++) { button.setColor(ElementColor.values()[index], colors[index]); } // Default option if (option.equals(defaultOption)) { button.setSelection(true); selectedOption = option.getId(); } // Selected option listener button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { InfoButton button = (InfoButton) e.widget; selectedOption = ((Option) button.getData()).getId(); updateButtons(); } }); // Close dialog on option double-click button.addMouseListener(new MouseAdapter() { @Override public void mouseDoubleClick(MouseEvent e) { InfoButton button = (InfoButton) e.widget; selectedOption = ((Option) button.getData()).getId(); updateButtons(); okPressed(); } }); } applyDialogFont(area); // Set dialog background color Composite contents = (Composite) super.createContents(parent); setBackground(parent, backgroundColor); return contents; } @Override protected void createButtonsForButtonBar(Composite parent) { super.createButtonsForButtonBar(parent); if (getSelection() != null) { // Select OK by default getButton(IDialogConstants.OK_ID).setFocus(); } else { // Select Cancel by default getButton(IDialogConstants.CANCEL_ID).setFocus(); } updateButtons(); } /** * Updates the state of buttons. */ private void updateButtons() { // Set OK enabled only if an option is selected getButton(IDialogConstants.OK_ID).setEnabled(getSelection() != null); } /** * Initializes dialog colors. */ private void initColors() { promptColor = new Color(getShell().getDisplay(), new RGB(45, 137, 239)); // Background backgroundColor = getShell().getDisplay().getSystemColor(SWT.COLOR_WHITE); Color selectBackground = new Color(getShell().getDisplay(), blendRGB(new RGB(45, 137, 239), backgroundColor.getRGB(), 20)); // Option selection colors[ElementColor.selectBackground.ordinal()] = selectBackground; // Option hover colors[ElementColor.hoverBackground.ordinal()] = new Color(getShell().getDisplay(), blendRGB(selectBackground.getRGB(), backgroundColor.getRGB(), 15)); // Option label Color foreground = new Color(getShell().getDisplay(), new RGB(0, 0, 0)); colors[ElementColor.label.ordinal()] = foreground; colors[ElementColor.selectedLabel.ordinal()] = foreground; // Option description Color descriptionForeground = new Color(getShell().getDisplay(), blendRGB(foreground.getRGB(), backgroundColor.getRGB(), 50)); colors[ElementColor.description.ordinal()] = descriptionForeground; colors[ElementColor.selectedDescription.ordinal()] = descriptionForeground; } @Override public boolean close() { // Dispose of element colors if (colors != null) { for (Color color : colors) { color.dispose(); } colors = null; } // Dispose of title color if (promptColor != null) { promptColor.dispose(); promptColor = null; } // Dispose of title font if (titleFont != null) { titleFont.dispose(); titleFont = null; } return super.close(); } /** * Blends two RGB values using the provided ratio. * * @param c1 First RGB value * @param c2 Second RGB value * @param ratio Percentage of the first RGB to blend with * second RGB (0-100) * * @return The RGB value of the blended color */ public static RGB blendRGB(RGB c1, RGB c2, int ratio) { ratio = Math.max(0, Math.min(255, ratio)); int r = Math.max(0, Math.min(255, (ratio * c1.red + (100 - ratio) * c2.red) / 100)); int g = Math.max(0, Math.min(255, (ratio * c1.green + (100 - ratio) * c2.green) / 100)); int b = Math.max(0, Math.min(255, (ratio * c1.blue + (100 - ratio) * c2.blue) / 100)); return new RGB(r, g, b); } @Override protected Control createButtonBar(Composite parent) { Composite bar = (Composite) super.createButtonBar(parent); // Change bar to center on dialog bar.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_CENTER)); return bar; } /** * Sets the background color for a composite and it's children. * * @param area Composite * @param color Background color */ private void setBackground(Control area, Color color) { area.setBackground(color); if (area instanceof Composite) { Control[] children = ((Composite) area).getChildren(); for (Control child : children) { setBackground(child, color); } } } /** * Dialog option */ private class Option { /** Option identifier */ private String id; /** Image for the option */ private Image image; /** Label for the option */ private String label; /** Description for the label */ private String description; /** * Constructor * * @param id Option identifier * @param image Option image * @param label Option label * @param description Option description */ public Option(String id, Image image, String label, String description) { this.id = id; this.image = image; this.label = label; this.description = description; } /** * Returns the option identifier. * * @return Identifier */ public String getId() { return id; } /** * Returns the option image. * * @return Image */ public Image getImage() { return image; } /** * Return the option label. * * @return Label */ public String getLabel() { return label; } /** * Returns the option description. * * @return Description */ public String getDescription() { return description; } } @Override public String getConsoleResponse(String input) throws IllegalArgumentException { String response = null; // Initial prompt if (input == null) { consoleList = new ConsoleListPrompter<String>(getTitleText(), true); // Add options for (Option option : options) { StringBuffer itemName = new StringBuffer(); if (option.getLabel() != null) itemName.append(option.getLabel()); if (option.getDescription() != null) { if (itemName.length() > 0) itemName.append(" - "); itemName.append(option.getDescription()); } consoleList.addItem(itemName.toString(), option.getId()); } } // Get response response = consoleList.getConsoleResponse(input); // Handle selection if (response == null) { ArrayList<String> selection = new ArrayList<String>(); consoleList.getSelectedData(selection); if (selection.size() > 0) { selectedOption = selection.get(0); } } return response; } }