Java tutorial
/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package ext.org.eclipse.jdt.internal.ui.preferences; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.ui.PreferenceConstants; import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.layout.PixelConverter; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import patch.org.eclipse.jdt.internal.ui.JavaPlugin; import ext.org.eclipse.jdt.internal.corext.util.Messages; import ext.org.eclipse.jdt.internal.ui.dialogs.StatusInfo; import ext.org.eclipse.jdt.internal.ui.dialogs.StatusUtil; import ext.org.eclipse.jdt.internal.ui.preferences.OverlayPreferenceStore.OverlayKey; import ext.org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor; import ext.org.eclipse.jdt.internal.ui.util.SWTUtil; import ext.org.eclipse.jdt.internal.ui.util.TableLayoutComposite; /** * Configures Java Editor hover preferences. * * @since 2.1 */ class JavaEditorHoverConfigurationBlock implements IPreferenceConfigurationBlock { private static final String DELIMITER = PreferencesMessages.JavaEditorHoverConfigurationBlock_delimiter; private static final int ENABLED_PROP = 0; private static final int MODIFIER_PROP = 1; // Data structure to hold the values which are edited by the user private static class HoverConfig { private String fModifierString; private boolean fIsEnabled; private int fStateMask; private HoverConfig(String modifier, int stateMask, boolean enabled) { fModifierString = modifier; fIsEnabled = enabled; fStateMask = stateMask; } } private class JavaEditorTextHoverDescriptorLabelProvider implements ITableLabelProvider { public Image getColumnImage(Object element, int columnIndex) { return null; } public String getColumnText(Object element, int columnIndex) { switch (columnIndex) { case ENABLED_PROP: return ((JavaEditorTextHoverDescriptor) element).getLabel(); case MODIFIER_PROP: TableItem item = (TableItem) fHoverTableViewer.testFindItem(element); int index = fHoverTable.indexOf(item); return fHoverConfigs[index].fModifierString; default: break; } return null; } public void addListener(ILabelProviderListener listener) { } public void dispose() { } public boolean isLabelProperty(Object element, String property) { return false; } public void removeListener(ILabelProviderListener listener) { } } private class JavaEditorTextHoverDescriptorContentProvider implements IStructuredContentProvider { public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // Do nothing since the viewer listens to resource deltas } public void dispose() { } public Object[] getElements(Object element) { return (Object[]) element; } } private OverlayPreferenceStore fStore; private HoverConfig[] fHoverConfigs; private Text fModifierEditor; private Table fHoverTable; private TableViewer fHoverTableViewer; private TableColumn fNameColumn; private TableColumn fModifierColumn; private Text fDescription; private PreferencePage fMainPreferencePage; private StatusInfo fStatus; private Map<Button, String> fCheckBoxes = new HashMap<Button, String>(); private SelectionListener fCheckBoxListener = new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { Button button = (Button) e.widget; fStore.setValue(fCheckBoxes.get(button), button.getSelection()); } public void widgetSelected(SelectionEvent e) { Button button = (Button) e.widget; fStore.setValue(fCheckBoxes.get(button), button.getSelection()); } }; public JavaEditorHoverConfigurationBlock(PreferencePage mainPreferencePage, OverlayPreferenceStore store) { Assert.isNotNull(mainPreferencePage); Assert.isNotNull(store); fMainPreferencePage = mainPreferencePage; fStore = store; fStore.addKeys(createOverlayStoreKeys()); } private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() { ArrayList<OverlayKey> overlayKeys = new ArrayList<OverlayKey>(); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS)); OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; overlayKeys.toArray(keys); return keys; } /** * Creates page for hover preferences. * * @param parent the parent composite * @return the control for the preference page */ public Control createControl(Composite parent) { ScrolledPageContent scrolled = new ScrolledPageContent(parent, SWT.H_SCROLL | SWT.V_SCROLL); scrolled.setExpandHorizontal(true); scrolled.setExpandVertical(true); Composite hoverComposite = new Composite(scrolled, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 2; layout.marginWidth = 0; layout.marginHeight = 0; hoverComposite.setLayout(layout); String rollOverLabel = PreferencesMessages.JavaEditorHoverConfigurationBlock_annotationRollover; addCheckBox(hoverComposite, rollOverLabel, PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER, 0); addFiller(hoverComposite); Label label = new Label(hoverComposite, SWT.NONE); label.setText(PreferencesMessages.JavaEditorHoverConfigurationBlock_hoverPreferences); GridData gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalAlignment = GridData.BEGINNING; gd.horizontalSpan = 2; label.setLayoutData(gd); TableLayoutComposite layouter = new TableLayoutComposite(hoverComposite, SWT.NONE); addColumnLayoutData(layouter); // Hover table fHoverTable = new Table(layouter, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.CHECK); fHoverTable.setHeaderVisible(true); fHoverTable.setLinesVisible(true); gd = new GridData(GridData.FILL_HORIZONTAL); gd.heightHint = SWTUtil.getTableHeightHint(fHoverTable, 10); gd.horizontalSpan = 2; gd.widthHint = new PixelConverter(parent).convertWidthInCharsToPixels(30); layouter.setLayoutData(gd); fHoverTable.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { handleHoverListSelection(); } public void widgetDefaultSelected(SelectionEvent e) { } }); TableLayout tableLayout = new TableLayout(); fHoverTable.setLayout(tableLayout); fNameColumn = new TableColumn(fHoverTable, SWT.NONE); fNameColumn.setText(PreferencesMessages.JavaEditorHoverConfigurationBlock_nameColumnTitle); fNameColumn.setResizable(true); fModifierColumn = new TableColumn(fHoverTable, SWT.NONE); fModifierColumn.setText(PreferencesMessages.JavaEditorHoverConfigurationBlock_modifierColumnTitle); fModifierColumn.setResizable(true); fHoverTableViewer = new CheckboxTableViewer(fHoverTable); fHoverTableViewer.setUseHashlookup(true); fHoverTableViewer.setContentProvider(new JavaEditorTextHoverDescriptorContentProvider()); fHoverTableViewer.setLabelProvider(new JavaEditorTextHoverDescriptorLabelProvider()); ((CheckboxTableViewer) fHoverTableViewer).addCheckStateListener(new ICheckStateListener() { /* * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent) */ public void checkStateChanged(CheckStateChangedEvent event) { String id = ((JavaEditorTextHoverDescriptor) event.getElement()).getId(); if (id == null) return; JavaEditorTextHoverDescriptor[] descriptors = getContributedHovers(); HoverConfig hoverConfig = null; int i = 0, length = fHoverConfigs.length; while (i < length) { if (id.equals(descriptors[i].getId())) { hoverConfig = fHoverConfigs[i]; hoverConfig.fIsEnabled = event.getChecked(); fModifierEditor.setEnabled(event.getChecked()); fHoverTableViewer.setSelection(new StructuredSelection(descriptors[i])); } i++; } handleHoverListSelection(); updateStatus(hoverConfig); } }); // Text field for modifier string label = new Label(hoverComposite, SWT.LEFT); label.setText(PreferencesMessages.JavaEditorHoverConfigurationBlock_keyModifier); fModifierEditor = new Text(hoverComposite, SWT.BORDER); gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL); fModifierEditor.setLayoutData(gd); fModifierEditor.addKeyListener(new KeyListener() { private boolean isModifierCandidate; public void keyPressed(KeyEvent e) { isModifierCandidate = e.keyCode > 0 && e.character == 0 && e.stateMask == 0; } public void keyReleased(KeyEvent e) { if (isModifierCandidate && e.stateMask > 0 && e.stateMask == e.stateMask && e.character == 0) {// && e.time -time < 1000) { String text = fModifierEditor.getText(); Point selection = fModifierEditor.getSelection(); int i = selection.x - 1; while (i > -1 && Character.isWhitespace(text.charAt(i))) { i--; } boolean needsPrefixDelimiter = i > -1 && !String.valueOf(text.charAt(i)).equals(DELIMITER); i = selection.y; while (i < text.length() && Character.isWhitespace(text.charAt(i))) { i++; } boolean needsPostfixDelimiter = i < text.length() && !String.valueOf(text.charAt(i)).equals(DELIMITER); String insertString; if (needsPrefixDelimiter && needsPostfixDelimiter) insertString = Messages.format( PreferencesMessages.JavaEditorHoverConfigurationBlock_insertDelimiterAndModifierAndDelimiter, new String[] { Action.findModifierString(e.stateMask) }); else if (needsPrefixDelimiter) insertString = Messages.format( PreferencesMessages.JavaEditorHoverConfigurationBlock_insertDelimiterAndModifier, new String[] { Action.findModifierString(e.stateMask) }); else if (needsPostfixDelimiter) insertString = Messages.format( PreferencesMessages.JavaEditorHoverConfigurationBlock_insertModifierAndDelimiter, new String[] { Action.findModifierString(e.stateMask) }); else insertString = Action.findModifierString(e.stateMask); if (insertString != null) fModifierEditor.insert(insertString); } } }); fModifierEditor.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { handleModifierModified(); } }); // Description Label descriptionLabel = new Label(hoverComposite, SWT.LEFT); descriptionLabel.setText(PreferencesMessages.JavaEditorHoverConfigurationBlock_description); gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING); gd.horizontalSpan = 2; descriptionLabel.setLayoutData(gd); fDescription = new Text(hoverComposite, SWT.LEFT | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER); gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 2; fDescription.setLayoutData(gd); initialize(); scrolled.setContent(hoverComposite); final Point size = hoverComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT); scrolled.setMinSize(size.x, size.y); Dialog.applyDialogFont(scrolled); return scrolled; } private void addColumnLayoutData(TableLayoutComposite layouter) { layouter.addColumnData(new ColumnWeightData(40, true)); layouter.addColumnData(new ColumnWeightData(60, true)); } private JavaEditorTextHoverDescriptor[] getContributedHovers() { return JavaPlugin.getDefault().getJavaEditorTextHoverDescriptors(); } public void initialize() { JavaEditorTextHoverDescriptor[] hoverDescs = getContributedHovers(); fHoverConfigs = new HoverConfig[hoverDescs.length]; for (int i = 0; i < hoverDescs.length; i++) fHoverConfigs[i] = new HoverConfig(hoverDescs[i].getModifierString(), hoverDescs[i].getStateMask(), hoverDescs[i].isEnabled()); fHoverTableViewer.setInput(hoverDescs); initializeFields(); } void initializeFields() { fModifierEditor.setEnabled(false); Iterator<Button> e = fCheckBoxes.keySet().iterator(); while (e.hasNext()) { Button b = e.next(); String key = fCheckBoxes.get(b); b.setSelection(fStore.getBoolean(key)); } for (int i = 0; i < fHoverConfigs.length; i++) fHoverTable.getItem(i).setChecked(fHoverConfigs[i].fIsEnabled); fHoverTableViewer.refresh(); } public void performOk() { StringBuffer buf = new StringBuffer(); StringBuffer maskBuf = new StringBuffer(); for (int i = 0; i < fHoverConfigs.length; i++) { buf.append(getContributedHovers()[i].getId()); buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); if (!fHoverConfigs[i].fIsEnabled) buf.append(JavaEditorTextHoverDescriptor.DISABLED_TAG); String modifier = fHoverConfigs[i].fModifierString; if (modifier == null || modifier.length() == 0) modifier = JavaEditorTextHoverDescriptor.NO_MODIFIER; buf.append(modifier); buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); maskBuf.append(getContributedHovers()[i].getId()); maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); maskBuf.append(fHoverConfigs[i].fStateMask); maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); } fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS, buf.toString()); fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS, maskBuf.toString()); JavaPlugin.getDefault().resetJavaEditorTextHoverDescriptors(); } public void performDefaults() { restoreFromPreferences(); initializeFields(); updateStatus(null); } private void restoreFromPreferences() { String compiledTextHoverModifiers = fStore.getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS); StringTokenizer tokenizer = new StringTokenizer(compiledTextHoverModifiers, JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); HashMap<String, String> idToModifier = new HashMap<String, String>(tokenizer.countTokens() / 2); while (tokenizer.hasMoreTokens()) { String id = tokenizer.nextToken(); if (tokenizer.hasMoreTokens()) idToModifier.put(id, tokenizer.nextToken()); } String compiledTextHoverModifierMasks = JavaPlugin.getDefault().getPreferenceStore() .getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS); tokenizer = new StringTokenizer(compiledTextHoverModifierMasks, JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); HashMap<String, String> idToModifierMask = new HashMap<String, String>(tokenizer.countTokens() / 2); while (tokenizer.hasMoreTokens()) { String id = tokenizer.nextToken(); if (tokenizer.hasMoreTokens()) idToModifierMask.put(id, tokenizer.nextToken()); } for (int i = 0; i < fHoverConfigs.length; i++) { String modifierString = idToModifier.get(getContributedHovers()[i].getId()); boolean enabled = true; if (modifierString == null) modifierString = JavaEditorTextHoverDescriptor.DISABLED_TAG; if (modifierString.startsWith(JavaEditorTextHoverDescriptor.DISABLED_TAG)) { enabled = false; modifierString = modifierString.substring(1); } if (modifierString.equals(JavaEditorTextHoverDescriptor.NO_MODIFIER)) modifierString = ""; //$NON-NLS-1$ fHoverConfigs[i].fModifierString = modifierString; fHoverConfigs[i].fIsEnabled = enabled; fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor.computeStateMask(modifierString); if (fHoverConfigs[i].fStateMask == -1) { try { fHoverConfigs[i].fStateMask = Integer .parseInt(idToModifierMask.get(getContributedHovers()[i].getId())); } catch (NumberFormatException ex) { fHoverConfigs[i].fStateMask = -1; } } } } private void handleModifierModified() { int i = fHoverTable.getSelectionIndex(); if (i == -1) return; String modifiers = fModifierEditor.getText(); fHoverConfigs[i].fModifierString = modifiers; fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor.computeStateMask(modifiers); // update table fHoverTableViewer.refresh(getContributedHovers()[i]); updateStatus(fHoverConfigs[i]); } private void handleHoverListSelection() { int i = fHoverTable.getSelectionIndex(); if (i == -1) { if (fHoverTable.getSelectionCount() == 0) fModifierEditor.setEnabled(false); return; } boolean enabled = fHoverConfigs[i].fIsEnabled; fModifierEditor.setEnabled(enabled); fModifierEditor.setText(fHoverConfigs[i].fModifierString); String description = getContributedHovers()[i].getDescription(); if (description == null) description = ""; //$NON-NLS-1$ fDescription.setText(description); } IStatus getStatus() { if (fStatus == null) fStatus = new StatusInfo(); return fStatus; } private void updateStatus(HoverConfig hoverConfig) { if (hoverConfig != null && hoverConfig.fIsEnabled && hoverConfig.fStateMask == -1) fStatus = new StatusInfo(IStatus.ERROR, Messages.format(PreferencesMessages.JavaEditorHoverConfigurationBlock_modifierIsNotValid, hoverConfig.fModifierString)); else fStatus = new StatusInfo(); int i = 0; HashMap<Integer, String> stateMasks = new HashMap<Integer, String>(fHoverConfigs.length); while (fStatus.isOK() && i < fHoverConfigs.length) { if (fHoverConfigs[i].fIsEnabled) { String label = getContributedHovers()[i].getLabel(); Integer stateMask = new Integer(fHoverConfigs[i].fStateMask); if (fHoverConfigs[i].fStateMask == -1) fStatus = new StatusInfo(IStatus.ERROR, Messages.format( PreferencesMessages.JavaEditorHoverConfigurationBlock_modifierIsNotValidForHover, new String[] { fHoverConfigs[i].fModifierString, label })); else if (stateMasks.containsKey(stateMask)) fStatus = new StatusInfo(IStatus.ERROR, Messages.format(PreferencesMessages.JavaEditorHoverConfigurationBlock_duplicateModifier, new String[] { label, stateMasks.get(stateMask) })); else stateMasks.put(stateMask, label); } i++; } fMainPreferencePage.setValid(fStatus.isOK()); StatusUtil.applyToStatusLine(fMainPreferencePage, fStatus); } private Button addCheckBox(Composite parent, String label, String key, int indentation) { Button checkBox = new Button(parent, SWT.CHECK); checkBox.setText(label); GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); gd.horizontalIndent = indentation; gd.horizontalSpan = 2; checkBox.setLayoutData(gd); checkBox.addSelectionListener(fCheckBoxListener); fCheckBoxes.put(checkBox, key); return checkBox; } private void addFiller(Composite composite) { PixelConverter pixelConverter = new PixelConverter(composite); Label filler = new Label(composite, SWT.LEFT); GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL); gd.horizontalSpan = 2; gd.heightHint = pixelConverter.convertHeightInCharsToPixels(1) / 2; filler.setLayoutData(gd); } /* * @see DialogPage#dispose() */ public void dispose() { // nothing to dispose } }