From 70364bc46c5746281cda6c1ddde3fe0d31411688 Mon Sep 17 00:00:00 2001 From: Puyodead1 <23562356riley@gmail.com> Date: Wed, 13 Nov 2019 17:03:29 -0500 Subject: [PATCH] Stable --- .../filedownloader/DownloadDialog.java | 51 +- .../puyodead1/filedownloader/Downloader.java | 123 ++--- .../filedownloader/FileDownloader.java | 50 +- .../eclipse/wb/swt/SWTResourceManager.java | 447 ++++++++++++++++++ 4 files changed, 572 insertions(+), 99 deletions(-) create mode 100644 src/org/eclipse/wb/swt/SWTResourceManager.java diff --git a/src/me/puyodead1/filedownloader/DownloadDialog.java b/src/me/puyodead1/filedownloader/DownloadDialog.java index 94557d7..6c967cf 100644 --- a/src/me/puyodead1/filedownloader/DownloadDialog.java +++ b/src/me/puyodead1/filedownloader/DownloadDialog.java @@ -11,16 +11,19 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; public class DownloadDialog extends Dialog { protected Object result; - protected Shell shell; - private String fileName; - private String savePath; - private URL url; - private Downloader downloader; - + protected Shell shell, parent; + protected String fileName, urlString, savePath; + protected URL url; + protected ProgressBar progressBar; + protected Label lblProgress; + protected Downloader downloader; + /** * Create the dialog. * @param parent @@ -30,14 +33,9 @@ public DownloadDialog(Shell parent, int style, String url, String fileName, Stri super(parent, style); this.fileName = fileName; this.savePath = savePath; + this.urlString = url; + this.parent = parent; setText("Downloading..."); - try { - this.url = new URL(url); - this.downloader = new Downloader(parent, this.url, savePath); - } catch(MalformedURLException e) { - final MessageDialog dialog = new MessageDialog(shell, getStyle(), "Error", e.getMessage()); - dialog.open(); - } } /** @@ -46,6 +44,13 @@ public DownloadDialog(Shell parent, int style, String url, String fileName, Stri */ public Object open() { createContents(); + try { + this.url = new URL(urlString); + downloader = new Downloader(this, parent, shell, this.url, savePath); + } catch(MalformedURLException e) { + final MessageDialog dialog = new MessageDialog(shell, getStyle(), "Error", e.getMessage()); + dialog.open(); + } shell.open(); shell.layout(); Display display = getParent().getDisplay(); @@ -62,20 +67,30 @@ public Object open() { */ private void createContents() { shell = new Shell(getParent(), getStyle()); - shell.setSize(450, 148); + shell.setSize(450, 168); shell.setText(getText()); - ProgressBar progressBar = new ProgressBar(shell, SWT.NONE); - progressBar.setBounds(10, 52, 424, 25); + progressBar = new ProgressBar(shell, SWT.NONE); + progressBar.setBounds(10, 70, 424, 25); Button btnCancel = new Button(shell, SWT.NONE); - btnCancel.setBounds(10, 83, 424, 25); + btnCancel.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + downloader.setStatus(Downloader.CANCELLED); + System.out.println("Download cancelled: " + downloader.getStatus()); + } + }); + btnCancel.setBounds(10, 101, 424, 25); btnCancel.setText("Cancel"); Label lblFile = new Label(shell, SWT.WRAP | SWT.CENTER); lblFile.setAlignment(SWT.CENTER); lblFile.setText("Downloading file: \n" + fileName); lblFile.setBounds(10, 10, 424, 36); - + + lblProgress = new Label(shell, SWT.NONE); + lblProgress.setAlignment(SWT.CENTER); + lblProgress.setBounds(10, 52, 424, 15); } } diff --git a/src/me/puyodead1/filedownloader/Downloader.java b/src/me/puyodead1/filedownloader/Downloader.java index 7ffb0e7..50359a5 100644 --- a/src/me/puyodead1/filedownloader/Downloader.java +++ b/src/me/puyodead1/filedownloader/Downloader.java @@ -1,6 +1,5 @@ package me.puyodead1.filedownloader; -import java.io.FileNotFoundException; import java.io.InputStream; import java.io.PrintWriter; import java.io.RandomAccessFile; @@ -14,7 +13,8 @@ public class Downloader implements Runnable { private static final int MAX_BUFFER_SIZE = 1024; - public static final String STATUSES[] = { "Downloading", "Paused", "Complete", "Cancelled", "Error" }; + public static final String STATUSES[] = {"Downloading", "Paused", + "Complete", "Cancelled", "Error"}; public static final int DOWNLOADING = 0; public static final int PAUSED = 1; @@ -22,17 +22,22 @@ public class Downloader implements Runnable { public static final int CANCELLED = 3; public static final int ERROR = 4; - private Shell parentShell; + private Shell downloadDialogShell, parentShell; private URL url; private int size; private int downloaded; private int status; private String output; + private DownloadDialog downloadDialog; - public Downloader(Shell parent, URL url, String output) { - this.parentShell = parent; + public Downloader(DownloadDialog downloadDialog, Shell parentShell, + Shell downloadDialogShell, URL url, String output) { + this.downloadDialogShell = downloadDialogShell; + this.parentShell = parentShell; this.url = url; this.output = output; + this.downloadDialog = downloadDialog; + size = -1; downloaded = 0; status = DOWNLOADING; @@ -56,6 +61,10 @@ public int getStatus() { return status; } + public void setStatus(int status) { + this.status = status; + } + private void error() { status = ERROR; stateChanged(); @@ -72,7 +81,8 @@ public void run() { try { // Open connection to URL. - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + HttpURLConnection connection = (HttpURLConnection) url + .openConnection(); // Specify what portion of file to download. connection.setRequestProperty("Range", "bytes=" + downloaded + "-"); @@ -102,58 +112,46 @@ public void run() { } // Open file and seek to the end of it. - try { - file = new RandomAccessFile(output, "rw"); - file.seek(downloaded); - - stream = connection.getInputStream(); - while (status == DOWNLOADING) { - /* - * Size buffer according to how much of the file is left to download. - */ - byte buffer[]; - if (size - downloaded > MAX_BUFFER_SIZE) { - buffer = new byte[MAX_BUFFER_SIZE]; - } else { - buffer = new byte[size - downloaded]; - } - - // Read from server into buffer. - int read = stream.read(buffer); - if (read == -1) - break; - - // Write buffer to file. - file.write(buffer, 0, read); - downloaded += read; - stateChanged(); - } + file = new RandomAccessFile(output, "rw"); + file.seek(downloaded); + stream = connection.getInputStream(); + while (status == DOWNLOADING) { /* - * Change status to complete if this point was reached because downloading has - * finished. + * Size buffer according to how much of the file is left to + * download. */ - if (status == DOWNLOADING) { - status = COMPLETE; - stateChanged(); + byte buffer[]; + if (size - downloaded > MAX_BUFFER_SIZE) { + buffer = new byte[MAX_BUFFER_SIZE]; + } else { + buffer = new byte[size - downloaded]; } - } catch (Throwable t) { - Display.getDefault().asyncExec(new Runnable() { - - @Override - public void run() { - final MessageDialog dialog = new MessageDialog(parentShell, parentShell.getStyle(), "Error", - t.getMessage()); - dialog.open(); - } - }); - error(); + + // Read from server into buffer. + int read = stream.read(buffer); + if (read == -1) + break; + + // Write buffer to file. + file.write(buffer, 0, read); + downloaded += read; + stateChanged(); + } + + /* + * Change status to complete if this point was reached because + * downloading has finished. + */ + if (status == DOWNLOADING) { + status = COMPLETE; + stateChanged(); } } catch (Exception e) { - error(); StringWriter writer = new StringWriter(); e.printStackTrace(new PrintWriter(writer)); System.out.println(writer.toString()); + error(); } finally { // Close file. if (file != null) { @@ -182,34 +180,39 @@ public void run() { private void stateChanged() { if (status == ERROR) { Display.getDefault().asyncExec(new Runnable() { - @Override public void run() { - final MessageDialog dialog = new MessageDialog(parentShell, parentShell.getStyle(), "Error", + System.out.println("error downloading"); + final MessageDialog dialog = new MessageDialog(parentShell, + parentShell.getStyle(), "Error", "An error occured and the download could not complete!"); dialog.open(); - } }); } else if (status == DOWNLOADING) { - // update progess bar - int progress = Math.round(this.getProgress()); - - Display.getDefault().asyncExec(new Runnable() { + final int progress = Math.round(this.getProgress()); + + downloadDialogShell.getDisplay().asyncExec(new Runnable() { public void run() { - // DownloadDialog.progressBar.setText(progress + "%"); - System.out.println(progress + "%"); + downloadDialog.progressBar.setSelection(progress); + downloadDialog.lblProgress.setText(progress + "%"); } }); } else if (status == COMPLETE) { + downloadDialogShell.getDisplay().asyncExec(new Runnable() { + public void run() { + downloadDialog.progressBar.setSelection(100); + } + }); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { - final MessageDialog dialog = new MessageDialog(parentShell, parentShell.getStyle(), "Complete", + downloadDialogShell.close(); + final MessageDialog dialog = new MessageDialog(parentShell, + parentShell.getStyle(), "Complete", "File download complete!"); dialog.open(); - } }); } diff --git a/src/me/puyodead1/filedownloader/FileDownloader.java b/src/me/puyodead1/filedownloader/FileDownloader.java index 3124419..7f44cd4 100644 --- a/src/me/puyodead1/filedownloader/FileDownloader.java +++ b/src/me/puyodead1/filedownloader/FileDownloader.java @@ -4,6 +4,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import java.io.File; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -14,6 +15,7 @@ import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; +import org.eclipse.wb.swt.SWTResourceManager; public class FileDownloader { private static final List allowedExts = Arrays.asList("mp4", "webm", "mp3", "wav", "iso", "rar", "zip", "java"); @@ -28,19 +30,19 @@ public class FileDownloader { */ public static void main(String[] args) { Display display = Display.getDefault(); - Shell shell = new Shell(); - shell.setSize(755, 434); - shell.setText("SWT Application"); + Shell shlNoBsFile = new Shell(); + shlNoBsFile.setSize(755, 222); + shlNoBsFile.setText("No BS File Downloader"); - txtUrl = new Text(shell, SWT.BORDER); - txtUrl.setBounds(10, 106, 719, 21); + txtUrl = new Text(shlNoBsFile, SWT.BORDER); + txtUrl.setBounds(10, 31, 719, 21); - Label lblUrl = new Label(shell, SWT.NONE); + Label lblUrl = new Label(shlNoBsFile, SWT.NONE); lblUrl.setAlignment(SWT.CENTER); - lblUrl.setBounds(10, 85, 719, 15); + lblUrl.setBounds(10, 10, 719, 15); lblUrl.setText("URL"); - Button btnDownload = new Button(shell, SWT.NONE); + Button btnDownload = new Button(shlNoBsFile, SWT.NONE); btnDownload.addMouseListener(new MouseAdapter() { @Override public void mouseDown(MouseEvent e) { @@ -55,9 +57,10 @@ public void mouseDown(MouseEvent e) { final String fileExt = fileExtSplit[fileExtSplit.length - 1]; if (allowedExts.contains(fileExt)) { final String savePath = txtSavePath.getText(); - new DownloadDialog(shell, shell.getStyle(), url, fileName, savePath); + final DownloadDialog dialog = new DownloadDialog(shlNoBsFile, shlNoBsFile.getStyle(), url, fileName, savePath + File.separator + fileName); + dialog.open(); } else { - final MessageDialog dialog = new MessageDialog(shell, shell.getStyle(), "Error", + final MessageDialog dialog = new MessageDialog(shlNoBsFile, shlNoBsFile.getStyle(), "Error", "File extension not allowed!"); dialog.open(); } @@ -75,18 +78,18 @@ public void mouseDown(MouseEvent e) { } } }); - btnDownload.setBounds(10, 202, 719, 25); + btnDownload.setBounds(10, 127, 719, 25); btnDownload.setText("Download"); - txtSavePath = new Text(shell, SWT.BORDER | SWT.READ_ONLY | SWT.H_SCROLL | SWT.CANCEL); + txtSavePath = new Text(shlNoBsFile, SWT.BORDER | SWT.READ_ONLY | SWT.H_SCROLL | SWT.CANCEL); txtSavePath.setEditable(false); - txtSavePath.setBounds(128, 175, 601, 21); + txtSavePath.setBounds(128, 100, 601, 21); - Button btnBrowse = new Button(shell, SWT.NONE); + Button btnBrowse = new Button(shlNoBsFile, SWT.NONE); btnBrowse.addMouseListener(new MouseAdapter() { @Override public void mouseDown(MouseEvent e) { - DirectoryDialog dialog = new DirectoryDialog(shell); + DirectoryDialog dialog = new DirectoryDialog(shlNoBsFile); dialog.setMessage("Choose Save Location"); String dir = dialog.open(); if (dir != null) { @@ -94,17 +97,22 @@ public void mouseDown(MouseEvent e) { } } }); - btnBrowse.setBounds(10, 175, 112, 21); + btnBrowse.setBounds(10, 100, 112, 21); btnBrowse.setText("Browse"); - Label lblSaveTo = new Label(shell, SWT.NONE); + Label lblSaveTo = new Label(shlNoBsFile, SWT.NONE); lblSaveTo.setAlignment(SWT.CENTER); - lblSaveTo.setBounds(10, 154, 719, 15); + lblSaveTo.setBounds(10, 79, 719, 15); lblSaveTo.setText("Save To"); + + Label lblCopyright = new Label(shlNoBsFile, SWT.NONE); + lblCopyright.setFont(SWTResourceManager.getFont("Segoe UI", 6, SWT.ITALIC)); + lblCopyright.setBounds(10, 168, 152, 15); + lblCopyright.setText("Copyright 2019 Puyodead1"); - shell.open(); - shell.layout(); - while (!shell.isDisposed()) { + shlNoBsFile.open(); + shlNoBsFile.layout(); + while (!shlNoBsFile.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } diff --git a/src/org/eclipse/wb/swt/SWTResourceManager.java b/src/org/eclipse/wb/swt/SWTResourceManager.java new file mode 100644 index 0000000..d8a2858 --- /dev/null +++ b/src/org/eclipse/wb/swt/SWTResourceManager.java @@ -0,0 +1,447 @@ +/******************************************************************************* + * Copyright (c) 2011 Google, Inc. + * 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: + * Google, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.wb.swt; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; + +/** + * Utility class for managing OS resources associated with SWT controls such as colors, fonts, images, etc. + *

+ * !!! IMPORTANT !!! Application code must explicitly invoke the dispose() method to release the + * operating system resources managed by cached objects when those objects and OS resources are no longer + * needed (e.g. on application shutdown) + *

+ * This class may be freely distributed as part of any application or plugin. + *

+ * @author scheglov_ke + * @author Dan Rubel + */ +public class SWTResourceManager { + //////////////////////////////////////////////////////////////////////////// + // + // Color + // + //////////////////////////////////////////////////////////////////////////// + private static Map m_colorMap = new HashMap(); + /** + * Returns the system {@link Color} matching the specific ID. + * + * @param systemColorID + * the ID value for the color + * @return the system {@link Color} matching the specific ID + */ + public static Color getColor(int systemColorID) { + Display display = Display.getCurrent(); + return display.getSystemColor(systemColorID); + } + /** + * Returns a {@link Color} given its red, green and blue component values. + * + * @param r + * the red component of the color + * @param g + * the green component of the color + * @param b + * the blue component of the color + * @return the {@link Color} matching the given red, green and blue component values + */ + public static Color getColor(int r, int g, int b) { + return getColor(new RGB(r, g, b)); + } + /** + * Returns a {@link Color} given its RGB value. + * + * @param rgb + * the {@link RGB} value of the color + * @return the {@link Color} matching the RGB value + */ + public static Color getColor(RGB rgb) { + Color color = m_colorMap.get(rgb); + if (color == null) { + Display display = Display.getCurrent(); + color = new Color(display, rgb); + m_colorMap.put(rgb, color); + } + return color; + } + /** + * Dispose of all the cached {@link Color}'s. + */ + public static void disposeColors() { + for (Color color : m_colorMap.values()) { + color.dispose(); + } + m_colorMap.clear(); + } + //////////////////////////////////////////////////////////////////////////// + // + // Image + // + //////////////////////////////////////////////////////////////////////////// + /** + * Maps image paths to images. + */ + private static Map m_imageMap = new HashMap(); + /** + * Returns an {@link Image} encoded by the specified {@link InputStream}. + * + * @param stream + * the {@link InputStream} encoding the image data + * @return the {@link Image} encoded by the specified input stream + */ + protected static Image getImage(InputStream stream) throws IOException { + try { + Display display = Display.getCurrent(); + ImageData data = new ImageData(stream); + if (data.transparentPixel > 0) { + return new Image(display, data, data.getTransparencyMask()); + } + return new Image(display, data); + } finally { + stream.close(); + } + } + /** + * Returns an {@link Image} stored in the file at the specified path. + * + * @param path + * the path to the image file + * @return the {@link Image} stored in the file at the specified path + */ + public static Image getImage(String path) { + Image image = m_imageMap.get(path); + if (image == null) { + try { + image = getImage(new FileInputStream(path)); + m_imageMap.put(path, image); + } catch (Exception e) { + image = getMissingImage(); + m_imageMap.put(path, image); + } + } + return image; + } + /** + * Returns an {@link Image} stored in the file at the specified path relative to the specified class. + * + * @param clazz + * the {@link Class} relative to which to find the image + * @param path + * the path to the image file, if starts with '/' + * @return the {@link Image} stored in the file at the specified path + */ + public static Image getImage(Class clazz, String path) { + String key = clazz.getName() + '|' + path; + Image image = m_imageMap.get(key); + if (image == null) { + try { + image = getImage(clazz.getResourceAsStream(path)); + m_imageMap.put(key, image); + } catch (Exception e) { + image = getMissingImage(); + m_imageMap.put(key, image); + } + } + return image; + } + private static final int MISSING_IMAGE_SIZE = 10; + /** + * @return the small {@link Image} that can be used as placeholder for missing image. + */ + private static Image getMissingImage() { + Image image = new Image(Display.getCurrent(), MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE); + // + GC gc = new GC(image); + gc.setBackground(getColor(SWT.COLOR_RED)); + gc.fillRectangle(0, 0, MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE); + gc.dispose(); + // + return image; + } + /** + * Style constant for placing decorator image in top left corner of base image. + */ + public static final int TOP_LEFT = 1; + /** + * Style constant for placing decorator image in top right corner of base image. + */ + public static final int TOP_RIGHT = 2; + /** + * Style constant for placing decorator image in bottom left corner of base image. + */ + public static final int BOTTOM_LEFT = 3; + /** + * Style constant for placing decorator image in bottom right corner of base image. + */ + public static final int BOTTOM_RIGHT = 4; + /** + * Internal value. + */ + protected static final int LAST_CORNER_KEY = 5; + /** + * Maps images to decorated images. + */ + @SuppressWarnings("unchecked") + private static Map>[] m_decoratedImageMap = new Map[LAST_CORNER_KEY]; + /** + * Returns an {@link Image} composed of a base image decorated by another image. + * + * @param baseImage + * the base {@link Image} that should be decorated + * @param decorator + * the {@link Image} to decorate the base image + * @return {@link Image} The resulting decorated image + */ + public static Image decorateImage(Image baseImage, Image decorator) { + return decorateImage(baseImage, decorator, BOTTOM_RIGHT); + } + /** + * Returns an {@link Image} composed of a base image decorated by another image. + * + * @param baseImage + * the base {@link Image} that should be decorated + * @param decorator + * the {@link Image} to decorate the base image + * @param corner + * the corner to place decorator image + * @return the resulting decorated {@link Image} + */ + public static Image decorateImage(final Image baseImage, final Image decorator, final int corner) { + if (corner <= 0 || corner >= LAST_CORNER_KEY) { + throw new IllegalArgumentException("Wrong decorate corner"); + } + Map> cornerDecoratedImageMap = m_decoratedImageMap[corner]; + if (cornerDecoratedImageMap == null) { + cornerDecoratedImageMap = new HashMap>(); + m_decoratedImageMap[corner] = cornerDecoratedImageMap; + } + Map decoratedMap = cornerDecoratedImageMap.get(baseImage); + if (decoratedMap == null) { + decoratedMap = new HashMap(); + cornerDecoratedImageMap.put(baseImage, decoratedMap); + } + // + Image result = decoratedMap.get(decorator); + if (result == null) { + Rectangle bib = baseImage.getBounds(); + Rectangle dib = decorator.getBounds(); + // + result = new Image(Display.getCurrent(), bib.width, bib.height); + // + GC gc = new GC(result); + gc.drawImage(baseImage, 0, 0); + if (corner == TOP_LEFT) { + gc.drawImage(decorator, 0, 0); + } else if (corner == TOP_RIGHT) { + gc.drawImage(decorator, bib.width - dib.width, 0); + } else if (corner == BOTTOM_LEFT) { + gc.drawImage(decorator, 0, bib.height - dib.height); + } else if (corner == BOTTOM_RIGHT) { + gc.drawImage(decorator, bib.width - dib.width, bib.height - dib.height); + } + gc.dispose(); + // + decoratedMap.put(decorator, result); + } + return result; + } + /** + * Dispose all of the cached {@link Image}'s. + */ + public static void disposeImages() { + // dispose loaded images + { + for (Image image : m_imageMap.values()) { + image.dispose(); + } + m_imageMap.clear(); + } + // dispose decorated images + for (int i = 0; i < m_decoratedImageMap.length; i++) { + Map> cornerDecoratedImageMap = m_decoratedImageMap[i]; + if (cornerDecoratedImageMap != null) { + for (Map decoratedMap : cornerDecoratedImageMap.values()) { + for (Image image : decoratedMap.values()) { + image.dispose(); + } + decoratedMap.clear(); + } + cornerDecoratedImageMap.clear(); + } + } + } + //////////////////////////////////////////////////////////////////////////// + // + // Font + // + //////////////////////////////////////////////////////////////////////////// + /** + * Maps font names to fonts. + */ + private static Map m_fontMap = new HashMap(); + /** + * Maps fonts to their bold versions. + */ + private static Map m_fontToBoldFontMap = new HashMap(); + /** + * Returns a {@link Font} based on its name, height and style. + * + * @param name + * the name of the font + * @param height + * the height of the font + * @param style + * the style of the font + * @return {@link Font} The font matching the name, height and style + */ + public static Font getFont(String name, int height, int style) { + return getFont(name, height, style, false, false); + } + /** + * Returns a {@link Font} based on its name, height and style. Windows-specific strikeout and underline + * flags are also supported. + * + * @param name + * the name of the font + * @param size + * the size of the font + * @param style + * the style of the font + * @param strikeout + * the strikeout flag (warning: Windows only) + * @param underline + * the underline flag (warning: Windows only) + * @return {@link Font} The font matching the name, height, style, strikeout and underline + */ + public static Font getFont(String name, int size, int style, boolean strikeout, boolean underline) { + String fontName = name + '|' + size + '|' + style + '|' + strikeout + '|' + underline; + Font font = m_fontMap.get(fontName); + if (font == null) { + FontData fontData = new FontData(name, size, style); + if (strikeout || underline) { + try { + Class logFontClass = Class.forName("org.eclipse.swt.internal.win32.LOGFONT"); //$NON-NLS-1$ + Object logFont = FontData.class.getField("data").get(fontData); //$NON-NLS-1$ + if (logFont != null && logFontClass != null) { + if (strikeout) { + logFontClass.getField("lfStrikeOut").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$ + } + if (underline) { + logFontClass.getField("lfUnderline").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$ + } + } + } catch (Throwable e) { + System.err.println("Unable to set underline or strikeout" + " (probably on a non-Windows platform). " + e); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + font = new Font(Display.getCurrent(), fontData); + m_fontMap.put(fontName, font); + } + return font; + } + /** + * Returns a bold version of the given {@link Font}. + * + * @param baseFont + * the {@link Font} for which a bold version is desired + * @return the bold version of the given {@link Font} + */ + public static Font getBoldFont(Font baseFont) { + Font font = m_fontToBoldFontMap.get(baseFont); + if (font == null) { + FontData fontDatas[] = baseFont.getFontData(); + FontData data = fontDatas[0]; + font = new Font(Display.getCurrent(), data.getName(), data.getHeight(), SWT.BOLD); + m_fontToBoldFontMap.put(baseFont, font); + } + return font; + } + /** + * Dispose all of the cached {@link Font}'s. + */ + public static void disposeFonts() { + // clear fonts + for (Font font : m_fontMap.values()) { + font.dispose(); + } + m_fontMap.clear(); + // clear bold fonts + for (Font font : m_fontToBoldFontMap.values()) { + font.dispose(); + } + m_fontToBoldFontMap.clear(); + } + //////////////////////////////////////////////////////////////////////////// + // + // Cursor + // + //////////////////////////////////////////////////////////////////////////// + /** + * Maps IDs to cursors. + */ + private static Map m_idToCursorMap = new HashMap(); + /** + * Returns the system cursor matching the specific ID. + * + * @param id + * int The ID value for the cursor + * @return Cursor The system cursor matching the specific ID + */ + public static Cursor getCursor(int id) { + Integer key = Integer.valueOf(id); + Cursor cursor = m_idToCursorMap.get(key); + if (cursor == null) { + cursor = new Cursor(Display.getDefault(), id); + m_idToCursorMap.put(key, cursor); + } + return cursor; + } + /** + * Dispose all of the cached cursors. + */ + public static void disposeCursors() { + for (Cursor cursor : m_idToCursorMap.values()) { + cursor.dispose(); + } + m_idToCursorMap.clear(); + } + //////////////////////////////////////////////////////////////////////////// + // + // General + // + //////////////////////////////////////////////////////////////////////////// + /** + * Dispose of cached objects and their underlying OS resources. This should only be called when the cached + * objects are no longer needed (e.g. on application shutdown). + */ + public static void dispose() { + disposeColors(); + disposeImages(); + disposeFonts(); + disposeCursors(); + } +} \ No newline at end of file