mirror of
https://github.com/mitb-archive/filebot
synced 2024-12-24 16:58:51 -05:00
* organize imports
This commit is contained in:
parent
664f83ced0
commit
37d55d4867
@ -1,3 +1,4 @@
|
||||
//TODO MOVE package net.sourceforge.filebot to net.filebot
|
||||
package net.sourceforge.filebot;
|
||||
|
||||
import static java.awt.GraphicsEnvironment.*;
|
||||
@ -58,10 +59,10 @@ import net.sourceforge.filebot.media.MediaDetection;
|
||||
import net.sourceforge.filebot.ui.MainFrame;
|
||||
import net.sourceforge.filebot.ui.PanelBuilder;
|
||||
import net.sourceforge.filebot.ui.SinglePanelFrame;
|
||||
import net.sourceforge.filebot.web.CachedResource;
|
||||
import net.sourceforge.filebot.util.ByteBufferInputStream;
|
||||
import net.sourceforge.filebot.util.PreferencesMap.PreferencesEntry;
|
||||
import net.sourceforge.filebot.util.TeePrintStream;
|
||||
import net.sourceforge.filebot.web.CachedResource;
|
||||
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
|
@ -21,9 +21,9 @@ import net.sf.sevenzipjbinding.ISevenZipInArchive;
|
||||
import net.sf.sevenzipjbinding.PropID;
|
||||
import net.sf.sevenzipjbinding.SevenZipException;
|
||||
import net.sourceforge.filebot.MediaTypes;
|
||||
import net.sourceforge.filebot.util.FileUtilities.ExtensionFileFilter;
|
||||
import net.sourceforge.filebot.vfs.FileInfo;
|
||||
import net.sourceforge.filebot.vfs.SimpleFileInfo;
|
||||
import net.sourceforge.filebot.util.FileUtilities.ExtensionFileFilter;
|
||||
|
||||
public class Archive implements Closeable {
|
||||
|
||||
|
@ -58,6 +58,7 @@ import net.sourceforge.filebot.similarity.SimilarityComparator;
|
||||
import net.sourceforge.filebot.similarity.SimilarityMetric;
|
||||
import net.sourceforge.filebot.subtitle.SubtitleFormat;
|
||||
import net.sourceforge.filebot.subtitle.SubtitleNaming;
|
||||
import net.sourceforge.filebot.util.FileUtilities.ParentFilter;
|
||||
import net.sourceforge.filebot.vfs.FileInfo;
|
||||
import net.sourceforge.filebot.vfs.MemoryFile;
|
||||
import net.sourceforge.filebot.vfs.SimpleFileInfo;
|
||||
@ -75,7 +76,6 @@ import net.sourceforge.filebot.web.SortOrder;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
import net.sourceforge.filebot.web.SubtitleProvider;
|
||||
import net.sourceforge.filebot.web.VideoHashSubtitleService;
|
||||
import net.sourceforge.filebot.util.FileUtilities.ParentFilter;
|
||||
|
||||
public class CmdlineOperations implements CmdlineInterface {
|
||||
|
||||
|
@ -7,9 +7,9 @@ import static net.sourceforge.filebot.format.Define.*;
|
||||
import static net.sourceforge.filebot.hash.VerificationUtilities.*;
|
||||
import static net.sourceforge.filebot.media.MediaDetection.*;
|
||||
import static net.sourceforge.filebot.similarity.Normalization.*;
|
||||
import static net.sourceforge.filebot.web.EpisodeFormat.*;
|
||||
import static net.sourceforge.filebot.util.FileUtilities.*;
|
||||
import static net.sourceforge.filebot.util.StringUtilities.*;
|
||||
import static net.sourceforge.filebot.web.EpisodeFormat.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -36,6 +36,8 @@ import net.sourceforge.filebot.media.MetaAttributes;
|
||||
import net.sourceforge.filebot.mediainfo.MediaInfo;
|
||||
import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind;
|
||||
import net.sourceforge.filebot.similarity.SimilarityComparator;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.util.FileUtilities.ExtensionFileFilter;
|
||||
import net.sourceforge.filebot.web.AnidbSearchResult;
|
||||
import net.sourceforge.filebot.web.AudioTrack;
|
||||
import net.sourceforge.filebot.web.Date;
|
||||
@ -47,8 +49,6 @@ import net.sourceforge.filebot.web.MultiEpisode;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.filebot.web.SortOrder;
|
||||
import net.sourceforge.filebot.web.TheTVDBSearchResult;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.util.FileUtilities.ExtensionFileFilter;
|
||||
|
||||
import com.cedarsoftware.util.io.JsonWriter;
|
||||
|
||||
|
@ -31,12 +31,12 @@ import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.sourceforge.filebot.util.ByteBufferInputStream;
|
||||
import net.sourceforge.filebot.util.FileUtilities.RegexFileFilter;
|
||||
import net.sourceforge.filebot.web.AnidbSearchResult;
|
||||
import net.sourceforge.filebot.web.CachedResource;
|
||||
import net.sourceforge.filebot.web.Movie;
|
||||
import net.sourceforge.filebot.web.TheTVDBSearchResult;
|
||||
import net.sourceforge.filebot.util.ByteBufferInputStream;
|
||||
import net.sourceforge.filebot.util.FileUtilities.RegexFileFilter;
|
||||
|
||||
import org.tukaani.xz.XZInputStream;
|
||||
|
||||
|
@ -34,10 +34,10 @@ import javax.swing.event.ChangeListener;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sourceforge.filebot.ResourceManager;
|
||||
import net.sourceforge.filebot.Settings;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.filebot.util.ExceptionUtilities;
|
||||
import net.sourceforge.filebot.util.ui.LabelProvider;
|
||||
import net.sourceforge.filebot.util.ui.SelectButton;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import ca.odell.glazedlists.BasicEventList;
|
||||
import ca.odell.glazedlists.matchers.TextMatcherEditor;
|
||||
import ca.odell.glazedlists.swing.AutoCompleteSupport;
|
||||
|
@ -19,10 +19,10 @@ import javax.swing.table.TableModel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sourceforge.filebot.media.MetaAttributes;
|
||||
import net.sourceforge.filebot.ui.analyze.FileTree.FolderNode;
|
||||
import net.sourceforge.filebot.util.ui.LoadingOverlayPane;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
import net.sourceforge.filebot.web.Movie;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.filebot.util.ui.LoadingOverlayPane;
|
||||
|
||||
class AttributeTool extends Tool<TableModel> {
|
||||
|
||||
|
@ -36,7 +36,6 @@ import net.sourceforge.filebot.ResourceManager;
|
||||
import net.sourceforge.filebot.archive.Archive;
|
||||
import net.sourceforge.filebot.archive.FileMapper;
|
||||
import net.sourceforge.filebot.ui.analyze.FileTree.FolderNode;
|
||||
import net.sourceforge.filebot.vfs.FileInfo;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.util.ui.GradientStyle;
|
||||
import net.sourceforge.filebot.util.ui.LoadingOverlayPane;
|
||||
@ -44,6 +43,7 @@ import net.sourceforge.filebot.util.ui.ProgressDialog;
|
||||
import net.sourceforge.filebot.util.ui.ProgressDialog.Cancellable;
|
||||
import net.sourceforge.filebot.util.ui.SwingWorkerPropertyChangeAdapter;
|
||||
import net.sourceforge.filebot.util.ui.notification.SeparatorBorder;
|
||||
import net.sourceforge.filebot.vfs.FileInfo;
|
||||
|
||||
class ExtractTool extends Tool<TableModel> {
|
||||
|
||||
|
@ -42,16 +42,16 @@ import net.sourceforge.filebot.ui.transfer.ArrayTransferable;
|
||||
import net.sourceforge.filebot.ui.transfer.ClipboardHandler;
|
||||
import net.sourceforge.filebot.ui.transfer.CompositeTranserable;
|
||||
import net.sourceforge.filebot.ui.transfer.FileExportHandler;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
import net.sourceforge.filebot.web.EpisodeListProvider;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.filebot.web.SeasonOutOfBoundsException;
|
||||
import net.sourceforge.filebot.web.SortOrder;
|
||||
import net.sourceforge.filebot.util.StringUtilities;
|
||||
import net.sourceforge.filebot.util.ui.LabelProvider;
|
||||
import net.sourceforge.filebot.util.ui.SelectButton;
|
||||
import net.sourceforge.filebot.util.ui.SimpleLabelProvider;
|
||||
import net.sourceforge.filebot.util.ui.TunedUtilities;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
import net.sourceforge.filebot.web.EpisodeListProvider;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.filebot.web.SeasonOutOfBoundsException;
|
||||
import net.sourceforge.filebot.web.SortOrder;
|
||||
|
||||
public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, Episode> {
|
||||
|
||||
|
@ -6,8 +6,8 @@ import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sourceforge.filebot.similarity.Match;
|
||||
import net.sourceforge.filebot.vfs.FileInfo;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.vfs.FileInfo;
|
||||
|
||||
|
||||
class FileNameFormatter implements MatchFormatter {
|
||||
|
@ -64,9 +64,6 @@ import net.sourceforge.filebot.Settings;
|
||||
import net.sourceforge.filebot.format.BindingException;
|
||||
import net.sourceforge.filebot.format.ExpressionFormat;
|
||||
import net.sourceforge.filebot.format.MediaBindingBean;
|
||||
import net.sourceforge.filebot.web.AudioTrackFormat;
|
||||
import net.sourceforge.filebot.web.EpisodeFormat;
|
||||
import net.sourceforge.filebot.web.MovieFormat;
|
||||
import net.sourceforge.filebot.util.DefaultThreadFactory;
|
||||
import net.sourceforge.filebot.util.ExceptionUtilities;
|
||||
import net.sourceforge.filebot.util.PreferencesList;
|
||||
@ -78,6 +75,9 @@ import net.sourceforge.filebot.util.ui.ProgressIndicator;
|
||||
import net.sourceforge.filebot.util.ui.TunedUtilities;
|
||||
import net.sourceforge.filebot.util.ui.notification.SeparatorBorder;
|
||||
import net.sourceforge.filebot.util.ui.notification.SeparatorBorder.Position;
|
||||
import net.sourceforge.filebot.web.AudioTrackFormat;
|
||||
import net.sourceforge.filebot.web.EpisodeFormat;
|
||||
import net.sourceforge.filebot.web.MovieFormat;
|
||||
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
|
@ -50,11 +50,11 @@ import net.sourceforge.filebot.similarity.Match;
|
||||
import net.sourceforge.filebot.similarity.NameSimilarityMetric;
|
||||
import net.sourceforge.filebot.similarity.SimilarityMetric;
|
||||
import net.sourceforge.filebot.ui.SelectDialog;
|
||||
import net.sourceforge.filebot.util.FileUtilities.ParentFilter;
|
||||
import net.sourceforge.filebot.web.Movie;
|
||||
import net.sourceforge.filebot.web.MovieIdentificationService;
|
||||
import net.sourceforge.filebot.web.MoviePart;
|
||||
import net.sourceforge.filebot.web.SortOrder;
|
||||
import net.sourceforge.filebot.util.FileUtilities.ParentFilter;
|
||||
|
||||
class MovieHashMatcher implements AutoCompleteMatcher {
|
||||
|
||||
|
@ -20,9 +20,9 @@ import net.sourceforge.filebot.hash.VerificationFileReader;
|
||||
import net.sourceforge.filebot.torrent.Torrent;
|
||||
import net.sourceforge.filebot.ui.transfer.ArrayTransferable;
|
||||
import net.sourceforge.filebot.ui.transfer.FileTransferablePolicy;
|
||||
import net.sourceforge.filebot.util.FastFile;
|
||||
import net.sourceforge.filebot.vfs.SimpleFileInfo;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
import net.sourceforge.filebot.util.FastFile;
|
||||
|
||||
class NamesListTransferablePolicy extends FileTransferablePolicy {
|
||||
|
||||
|
@ -27,10 +27,10 @@ import net.sourceforge.filebot.similarity.MetricCascade;
|
||||
import net.sourceforge.filebot.similarity.MetricMin;
|
||||
import net.sourceforge.filebot.similarity.SimilarityMetric;
|
||||
import net.sourceforge.filebot.ui.rename.RenameModel.FormattedFuture;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.util.ui.DefaultFancyListCellRenderer;
|
||||
import net.sourceforge.filebot.util.ui.GradientStyle;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
|
||||
class RenameListCellRenderer extends DefaultFancyListCellRenderer {
|
||||
|
||||
|
@ -58,6 +58,9 @@ import net.sourceforge.filebot.format.MediaBindingBean;
|
||||
import net.sourceforge.filebot.similarity.Match;
|
||||
import net.sourceforge.filebot.ui.rename.FormatDialog.Mode;
|
||||
import net.sourceforge.filebot.ui.rename.RenameModel.FormattedFuture;
|
||||
import net.sourceforge.filebot.util.PreferencesMap.PreferencesEntry;
|
||||
import net.sourceforge.filebot.util.ui.ActionPopup;
|
||||
import net.sourceforge.filebot.util.ui.LoadingOverlayPane;
|
||||
import net.sourceforge.filebot.web.AudioTrack;
|
||||
import net.sourceforge.filebot.web.AudioTrackFormat;
|
||||
import net.sourceforge.filebot.web.Episode;
|
||||
@ -68,9 +71,6 @@ import net.sourceforge.filebot.web.MovieFormat;
|
||||
import net.sourceforge.filebot.web.MovieIdentificationService;
|
||||
import net.sourceforge.filebot.web.MusicIdentificationService;
|
||||
import net.sourceforge.filebot.web.SortOrder;
|
||||
import net.sourceforge.filebot.util.PreferencesMap.PreferencesEntry;
|
||||
import net.sourceforge.filebot.util.ui.ActionPopup;
|
||||
import net.sourceforge.filebot.util.ui.LoadingOverlayPane;
|
||||
import ca.odell.glazedlists.EventList;
|
||||
import ca.odell.glazedlists.ListSelection;
|
||||
import ca.odell.glazedlists.swing.EventSelectionModel;
|
||||
|
@ -62,14 +62,14 @@ import net.sourceforge.filebot.similarity.EpisodeMetrics;
|
||||
import net.sourceforge.filebot.similarity.MetricCascade;
|
||||
import net.sourceforge.filebot.similarity.SimilarityMetric;
|
||||
import net.sourceforge.filebot.subtitle.SubtitleNaming;
|
||||
import net.sourceforge.filebot.vfs.MemoryFile;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
import net.sourceforge.filebot.web.SubtitleProvider;
|
||||
import net.sourceforge.filebot.web.VideoHashSubtitleService;
|
||||
import net.sourceforge.filebot.util.ui.AbstractBean;
|
||||
import net.sourceforge.filebot.util.ui.EmptySelectionModel;
|
||||
import net.sourceforge.filebot.util.ui.LinkButton;
|
||||
import net.sourceforge.filebot.util.ui.RoundBorder;
|
||||
import net.sourceforge.filebot.vfs.MemoryFile;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
import net.sourceforge.filebot.web.SubtitleProvider;
|
||||
import net.sourceforge.filebot.web.VideoHashSubtitleService;
|
||||
|
||||
class SubtitleAutoMatchDialog extends JDialog {
|
||||
|
||||
|
@ -45,10 +45,10 @@ import net.sourceforge.filebot.ResourceManager;
|
||||
import net.sourceforge.filebot.subtitle.SubtitleFormat;
|
||||
import net.sourceforge.filebot.ui.subtitle.SubtitlePackage.Download.Phase;
|
||||
import net.sourceforge.filebot.ui.transfer.DefaultTransferHandler;
|
||||
import net.sourceforge.filebot.vfs.MemoryFile;
|
||||
import net.sourceforge.filebot.util.ExceptionUtilities;
|
||||
import net.sourceforge.filebot.util.ui.ListView;
|
||||
import net.sourceforge.filebot.util.ui.TunedUtilities;
|
||||
import net.sourceforge.filebot.vfs.MemoryFile;
|
||||
import ca.odell.glazedlists.BasicEventList;
|
||||
import ca.odell.glazedlists.EventList;
|
||||
import ca.odell.glazedlists.FilterList;
|
||||
|
@ -35,11 +35,11 @@ import javax.swing.JFileChooser;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
|
||||
import net.sourceforge.filebot.ResourceManager;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.util.FileUtilities.ParentFilter;
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesClient;
|
||||
import net.sourceforge.filebot.web.SubtitleProvider;
|
||||
import net.sourceforge.filebot.web.VideoHashSubtitleService;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.util.FileUtilities.ParentFilter;
|
||||
|
||||
abstract class SubtitleDropTarget extends JButton {
|
||||
|
||||
|
@ -19,11 +19,11 @@ import javax.swing.SwingWorker;
|
||||
import javax.swing.event.SwingPropertyChangeSupport;
|
||||
|
||||
import net.sourceforge.filebot.Language;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.vfs.ArchiveType;
|
||||
import net.sourceforge.filebot.vfs.MemoryFile;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
import net.sourceforge.filebot.web.SubtitleProvider;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
|
||||
public class SubtitlePackage {
|
||||
|
||||
|
@ -40,13 +40,13 @@ import net.sourceforge.filebot.WebServices;
|
||||
import net.sourceforge.filebot.ui.AbstractSearchPanel;
|
||||
import net.sourceforge.filebot.ui.LanguageComboBox;
|
||||
import net.sourceforge.filebot.ui.SelectDialog;
|
||||
import net.sourceforge.filebot.util.ui.LabelProvider;
|
||||
import net.sourceforge.filebot.util.ui.SimpleLabelProvider;
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesClient;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
import net.sourceforge.filebot.web.SubtitleProvider;
|
||||
import net.sourceforge.filebot.web.VideoHashSubtitleService;
|
||||
import net.sourceforge.filebot.util.ui.LabelProvider;
|
||||
import net.sourceforge.filebot.util.ui.SimpleLabelProvider;
|
||||
|
||||
public class SubtitlePanel extends AbstractSearchPanel<SubtitleProvider, SubtitlePackage> {
|
||||
|
||||
|
@ -57,15 +57,15 @@ import net.sourceforge.filebot.WebServices;
|
||||
import net.sourceforge.filebot.media.MediaDetection;
|
||||
import net.sourceforge.filebot.ui.LanguageComboBox;
|
||||
import net.sourceforge.filebot.ui.SelectDialog;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.util.ui.AbstractBean;
|
||||
import net.sourceforge.filebot.util.ui.EmptySelectionModel;
|
||||
import net.sourceforge.filebot.web.Movie;
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesClient;
|
||||
import net.sourceforge.filebot.web.SearchResult;
|
||||
import net.sourceforge.filebot.web.TheTVDBClient.SeriesInfo;
|
||||
import net.sourceforge.filebot.web.TheTVDBSearchResult;
|
||||
import net.sourceforge.filebot.web.VideoHashSubtitleService.CheckResult;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.util.ui.AbstractBean;
|
||||
import net.sourceforge.filebot.util.ui.EmptySelectionModel;
|
||||
|
||||
public class SubtitleUploadDialog extends JDialog {
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
import static net.sourceforge.filebot.util.FileUtilities.*;
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
import static net.sourceforge.filebot.util.XPathUtilities.*;
|
||||
import static net.sourceforge.filebot.web.EpisodeUtilities.*;
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
import static net.sourceforge.filebot.util.XPathUtilities.*;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
import static net.sourceforge.filebot.util.FileUtilities.*;
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
import static net.sourceforge.filebot.util.XPathUtilities.*;
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
import static net.sourceforge.filebot.util.XPathUtilities.*;
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
|
@ -3,8 +3,8 @@ package net.sourceforge.filebot.web;
|
||||
import static java.lang.Math.*;
|
||||
import static java.util.Arrays.*;
|
||||
import static java.util.Collections.*;
|
||||
import static net.sourceforge.filebot.web.OpenSubtitlesHasher.*;
|
||||
import static net.sourceforge.filebot.util.FileUtilities.*;
|
||||
import static net.sourceforge.filebot.web.OpenSubtitlesHasher.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -35,12 +35,12 @@ import net.sourceforge.filebot.Cache.Key;
|
||||
import net.sourceforge.filebot.ResourceManager;
|
||||
import net.sourceforge.filebot.mediainfo.MediaInfo;
|
||||
import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind;
|
||||
import net.sourceforge.filebot.util.ExceptionUtilities;
|
||||
import net.sourceforge.filebot.util.Timer;
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesXmlRpc.BaseInfo;
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesXmlRpc.Query;
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesXmlRpc.SubFile;
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesXmlRpc.TryUploadResponse;
|
||||
import net.sourceforge.filebot.util.ExceptionUtilities;
|
||||
import net.sourceforge.filebot.util.Timer;
|
||||
import redstone.xmlrpc.XmlRpcException;
|
||||
import redstone.xmlrpc.XmlRpcFault;
|
||||
|
||||
|
@ -25,8 +25,8 @@ import java.util.regex.Pattern;
|
||||
import java.util.zip.DeflaterInputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesSubtitleDescriptor.Property;
|
||||
import net.sourceforge.filebot.util.ByteBufferOutputStream;
|
||||
import net.sourceforge.filebot.web.OpenSubtitlesSubtitleDescriptor.Property;
|
||||
import redstone.xmlrpc.XmlRpcClient;
|
||||
import redstone.xmlrpc.XmlRpcException;
|
||||
import redstone.xmlrpc.XmlRpcFault;
|
||||
|
@ -2,9 +2,9 @@
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
|
||||
import static net.sourceforge.filebot.util.XPathUtilities.*;
|
||||
import static net.sourceforge.filebot.web.EpisodeUtilities.*;
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
import static net.sourceforge.filebot.util.XPathUtilities.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
@ -1,9 +1,9 @@
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
import static java.util.Arrays.*;
|
||||
import static net.sourceforge.filebot.util.XPathUtilities.*;
|
||||
import static net.sourceforge.filebot.web.EpisodeUtilities.*;
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
import static net.sourceforge.filebot.util.XPathUtilities.*;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
@ -27,9 +27,9 @@ import javax.swing.Icon;
|
||||
|
||||
import net.sourceforge.filebot.Cache;
|
||||
import net.sourceforge.filebot.ResourceManager;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
import net.sourceforge.filebot.web.TheTVDBClient.BannerDescriptor.BannerProperty;
|
||||
import net.sourceforge.filebot.web.TheTVDBClient.SeriesInfo.SeriesProperty;
|
||||
import net.sourceforge.filebot.util.FileUtilities;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
@ -1,74 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
public class ByteBufferInputStream extends InputStream {
|
||||
|
||||
private final ByteBuffer buffer;
|
||||
|
||||
|
||||
public ByteBufferInputStream(ByteBuffer buffer) {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return (buffer.position() < buffer.limit()) ? (buffer.get() & 0xff) : -1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (b == null) {
|
||||
throw new NullPointerException();
|
||||
} else if (off < 0 || len < 0 || len > b.length - off) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
if (buffer.position() >= buffer.limit()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > buffer.remaining()) {
|
||||
len = buffer.remaining();
|
||||
}
|
||||
|
||||
if (len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer.get(b, off, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return buffer.remaining();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void mark(int readlimit) {
|
||||
buffer.mark();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
buffer.reset();
|
||||
}
|
||||
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
public class ByteBufferOutputStream extends OutputStream {
|
||||
|
||||
private ByteBuffer buffer;
|
||||
|
||||
private final float loadFactor;
|
||||
|
||||
public ByteBufferOutputStream(long initialCapacity) {
|
||||
this((int) initialCapacity);
|
||||
}
|
||||
|
||||
public ByteBufferOutputStream(int initialCapacity) {
|
||||
this(initialCapacity, 1.0f);
|
||||
}
|
||||
|
||||
public ByteBufferOutputStream(int initialCapacity, float loadFactor) {
|
||||
if (initialCapacity < 0)
|
||||
throw new IllegalArgumentException("initialCapacity must not be negative");
|
||||
|
||||
if (loadFactor <= 0 || Float.isNaN(loadFactor))
|
||||
throw new IllegalArgumentException("loadFactor must be greater than 0");
|
||||
|
||||
this.buffer = ByteBuffer.allocate(initialCapacity + 1);
|
||||
this.loadFactor = loadFactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
ensureCapacity(buffer.position() + 1);
|
||||
buffer.put((byte) b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] src) throws IOException {
|
||||
ensureCapacity(buffer.position() + src.length);
|
||||
buffer.put(src);
|
||||
}
|
||||
|
||||
public void write(ByteBuffer src) throws IOException {
|
||||
ensureCapacity(buffer.position() + src.remaining());
|
||||
buffer.put(src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] src, int offset, int length) throws IOException {
|
||||
ensureCapacity(buffer.position() + length);
|
||||
buffer.put(src, offset, length);
|
||||
}
|
||||
|
||||
public void ensureCapacity(int minCapacity) {
|
||||
if (minCapacity <= buffer.capacity())
|
||||
return;
|
||||
|
||||
// calculate new buffer size with load factor
|
||||
int newCapacity = (int) (buffer.capacity() * (1 + loadFactor));
|
||||
|
||||
// ensure minCapacity
|
||||
if (newCapacity < minCapacity)
|
||||
newCapacity = minCapacity;
|
||||
|
||||
// create new buffer with increased capacity
|
||||
ByteBuffer newBuffer = ByteBuffer.allocate(newCapacity);
|
||||
|
||||
// copy current data to new buffer
|
||||
buffer.flip();
|
||||
newBuffer.put(buffer);
|
||||
|
||||
buffer = newBuffer;
|
||||
}
|
||||
|
||||
public ByteBuffer getByteBuffer() {
|
||||
ByteBuffer result = buffer.duplicate();
|
||||
|
||||
// flip buffer so it can be read
|
||||
result.flip();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public byte[] getByteArray() {
|
||||
ByteBuffer data = getByteBuffer();
|
||||
|
||||
// copy data to byte array
|
||||
byte[] bytes = new byte[data.remaining()];
|
||||
data.get(bytes);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public int transferFrom(ReadableByteChannel channel) throws IOException {
|
||||
// make sure buffer is not at its limit
|
||||
ensureCapacity(buffer.position() + 1);
|
||||
|
||||
return channel.read(buffer);
|
||||
}
|
||||
|
||||
public int transferFully(InputStream inputStream) throws IOException {
|
||||
return transferFully(Channels.newChannel(inputStream));
|
||||
}
|
||||
|
||||
public int transferFully(ReadableByteChannel channel) throws IOException {
|
||||
int total = 0, read = 0;
|
||||
|
||||
while ((read = transferFrom(channel)) >= 0) {
|
||||
total += read;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public int position() {
|
||||
return buffer.position();
|
||||
}
|
||||
|
||||
public int capacity() {
|
||||
return buffer.capacity();
|
||||
}
|
||||
|
||||
public void rewind() {
|
||||
buffer.rewind();
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
||||
public class DefaultThreadFactory implements ThreadFactory {
|
||||
|
||||
private final AtomicInteger threadNumber = new AtomicInteger(0);
|
||||
private final ThreadGroup group;
|
||||
|
||||
private final int priority;
|
||||
private final boolean daemon;
|
||||
|
||||
|
||||
public DefaultThreadFactory(String name) {
|
||||
this(name, Thread.NORM_PRIORITY);
|
||||
}
|
||||
|
||||
|
||||
public DefaultThreadFactory(String name, int priority) {
|
||||
this(name, priority, false);
|
||||
}
|
||||
|
||||
|
||||
public DefaultThreadFactory(String groupName, int priority, boolean daemon) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
ThreadGroup parentGroup = (sm != null) ? sm.getThreadGroup() : Thread.currentThread().getThreadGroup();
|
||||
|
||||
this.group = new ThreadGroup(parentGroup, groupName);
|
||||
|
||||
this.daemon = daemon;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(group, r, String.format("%s-thread-%d", group.getName(), threadNumber.incrementAndGet()));
|
||||
|
||||
if (daemon != thread.isDaemon())
|
||||
thread.setDaemon(daemon);
|
||||
|
||||
if (priority != thread.getPriority())
|
||||
thread.setPriority(priority);
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
|
||||
public ThreadGroup getThreadGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import static net.sourceforge.filebot.web.WebRequest.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
|
||||
public class DownloadTask extends SwingWorker<ByteBuffer, Void> {
|
||||
|
||||
public static final String DOWNLOAD_STATE = "download state";
|
||||
public static final String DOWNLOAD_PROGRESS = "download progress";
|
||||
|
||||
|
||||
public static enum DownloadState {
|
||||
PENDING, CONNECTING, DOWNLOADING, DONE
|
||||
}
|
||||
|
||||
private URL url;
|
||||
|
||||
private long contentLength = -1;
|
||||
private DownloadState state = DownloadState.PENDING;
|
||||
|
||||
private Map<String, String> postParameters;
|
||||
private Map<String, String> requestHeaders;
|
||||
private Map<String, List<String>> responseHeaders;
|
||||
|
||||
|
||||
public DownloadTask(URL url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
|
||||
protected HttpURLConnection createConnection() throws Exception {
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
|
||||
if (requestHeaders != null) {
|
||||
for (Entry<String, String> entry : requestHeaders.entrySet()) {
|
||||
connection.addRequestProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ByteBuffer doInBackground() throws Exception {
|
||||
setDownloadState(DownloadState.CONNECTING);
|
||||
|
||||
HttpURLConnection connection = createConnection();
|
||||
|
||||
if (postParameters != null) {
|
||||
ByteBuffer postData = Charset.forName("UTF-8").encode(encodeParameters(postParameters, true));
|
||||
|
||||
// add content type and content length headers
|
||||
connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(postData.remaining()));
|
||||
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setDoOutput(true);
|
||||
|
||||
// write post data
|
||||
WritableByteChannel out = Channels.newChannel(connection.getOutputStream());
|
||||
out.write(postData);
|
||||
out.close();
|
||||
}
|
||||
|
||||
contentLength = connection.getContentLength();
|
||||
|
||||
responseHeaders = connection.getHeaderFields();
|
||||
|
||||
setDownloadState(DownloadState.DOWNLOADING);
|
||||
|
||||
ReadableByteChannel in = Channels.newChannel(connection.getInputStream());
|
||||
ByteBufferOutputStream buffer = new ByteBufferOutputStream((int) (contentLength > 0 ? contentLength : 32 * 1024));
|
||||
|
||||
try {
|
||||
while (!isCancelled() && ((buffer.transferFrom(in)) >= 0)) {
|
||||
|
||||
firePropertyChange(DOWNLOAD_PROGRESS, null, buffer.position());
|
||||
|
||||
if (isContentLengthKnown()) {
|
||||
setProgress((int) ((buffer.position() * 100) / contentLength));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// if the content length is not known in advance an IOException (Premature EOF)
|
||||
// is always thrown after all the data has been read
|
||||
if (isContentLengthKnown())
|
||||
throw e;
|
||||
|
||||
} finally {
|
||||
in.close();
|
||||
|
||||
// download either finished or an exception is thrown
|
||||
setDownloadState(DownloadState.DONE);
|
||||
}
|
||||
|
||||
return buffer.getByteBuffer();
|
||||
}
|
||||
|
||||
|
||||
protected void setDownloadState(DownloadState state) {
|
||||
this.state = state;
|
||||
firePropertyChange(DOWNLOAD_STATE, null, state);
|
||||
}
|
||||
|
||||
|
||||
public DownloadState getDownloadState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
public URL getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
public boolean isContentLengthKnown() {
|
||||
return contentLength >= 0;
|
||||
}
|
||||
|
||||
|
||||
public long getContentLength() {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
|
||||
public void setRequestHeaders(Map<String, String> requestHeaders) {
|
||||
this.requestHeaders = new HashMap<String, String>(requestHeaders);
|
||||
}
|
||||
|
||||
|
||||
public void setPostParameters(Map<String, String> postParameters) {
|
||||
this.postParameters = new HashMap<String, String>(postParameters);
|
||||
}
|
||||
|
||||
|
||||
public Map<String, List<String>> getResponseHeaders() {
|
||||
return responseHeaders;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, String> getPostParameters() {
|
||||
return postParameters;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, String> getRequestHeaders() {
|
||||
return requestHeaders;
|
||||
}
|
||||
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
public final class ExceptionUtilities {
|
||||
|
||||
public static Throwable getRootCause(Throwable t) {
|
||||
while (t.getCause() != null) {
|
||||
t = t.getCause();
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
public static <T extends Throwable> T findCause(Throwable t, Class<T> type) {
|
||||
while (t != null) {
|
||||
if (type.isInstance(t))
|
||||
return type.cast(t);
|
||||
|
||||
t = t.getCause();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String getRootCauseMessage(Throwable t) {
|
||||
return getMessage(getRootCause(t));
|
||||
}
|
||||
|
||||
|
||||
public static String getMessage(Throwable t) {
|
||||
String message = t.getMessage();
|
||||
|
||||
if (message == null || message.isEmpty()) {
|
||||
message = t.toString();
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
public static <T extends Throwable> T wrap(Throwable t, Class<T> type) {
|
||||
if (type.isInstance(t)) {
|
||||
return type.cast(t);
|
||||
}
|
||||
|
||||
try {
|
||||
return type.getConstructor(Throwable.class).newInstance(t);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static RuntimeException asRuntimeException(Throwable t) {
|
||||
return wrap(t, RuntimeException.class);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dummy constructor to prevent instantiation.
|
||||
*/
|
||||
private ExceptionUtilities() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class FastFile extends File {
|
||||
|
||||
private Long length;
|
||||
private Boolean isDirectory;
|
||||
private Boolean isFile;
|
||||
|
||||
public FastFile(String path) {
|
||||
super(path);
|
||||
}
|
||||
|
||||
public FastFile(File parent, String child) {
|
||||
super(parent, child);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long length() {
|
||||
return length != null ? length : (length = super.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory() {
|
||||
return isDirectory != null ? isDirectory : (isDirectory = super.isDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFile() {
|
||||
return isFile != null ? isFile : (isFile = super.isFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public File[] listFiles() {
|
||||
String[] names = list();
|
||||
if (names == null)
|
||||
return null;
|
||||
|
||||
File[] files = new File[names.length];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
files[i] = new FastFile(this, names[i]);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public static FastFile get(File file) {
|
||||
return new FastFile(file.getPath());
|
||||
}
|
||||
|
||||
public static List<FastFile> get(Collection<File> files) {
|
||||
List<FastFile> result = new ArrayList<FastFile>(files.size());
|
||||
|
||||
for (File file : files) {
|
||||
result.add(new FastFile(file.getPath()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -1,693 +0,0 @@
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.AtomicMoveNotSupportedException;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import com.ibm.icu.text.CharsetDetector;
|
||||
import com.ibm.icu.text.CharsetMatch;
|
||||
|
||||
public final class FileUtilities {
|
||||
|
||||
public static File moveRename(File source, File destination) throws IOException {
|
||||
// resolve destination
|
||||
destination = resolveDestination(source, destination, true);
|
||||
|
||||
if (source.isDirectory()) {
|
||||
// move folder
|
||||
org.apache.commons.io.FileUtils.moveDirectory(source, destination);
|
||||
} else {
|
||||
// on Windows ATOMIC_MOVE allows us to rename files even if only lower/upper-case changes (without ATOMIC_MOVE the operation would be ignored)
|
||||
try {
|
||||
java.nio.file.Files.move(source.toPath(), destination.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
|
||||
} catch (AtomicMoveNotSupportedException e) {
|
||||
java.nio.file.Files.move(source.toPath(), destination.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
public static File copyAs(File source, File destination) throws IOException {
|
||||
// resolve destination
|
||||
destination = resolveDestination(source, destination, true);
|
||||
|
||||
if (source.isDirectory()) {
|
||||
// copy folder
|
||||
org.apache.commons.io.FileUtils.copyDirectory(source, destination);
|
||||
} else {
|
||||
// copy file
|
||||
java.nio.file.Files.copy(source.toPath(), destination.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
public static File resolveDestination(File source, File destination, boolean mkdirs) throws IOException {
|
||||
// resolve destination
|
||||
if (!destination.isAbsolute()) {
|
||||
// same folder, different name
|
||||
destination = new File(source.getParentFile(), destination.getPath());
|
||||
}
|
||||
|
||||
// make sure we that we can create the destination folder structure
|
||||
File destinationFolder = destination.getParentFile();
|
||||
|
||||
// create parent folder if necessary
|
||||
if (mkdirs && !destinationFolder.isDirectory() && !destinationFolder.mkdirs()) {
|
||||
throw new IOException("Failed to create folder: " + destinationFolder);
|
||||
}
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
public static File createRelativeSymlink(File link, File target, boolean relativize) throws IOException {
|
||||
if (relativize) {
|
||||
// make sure we're working with the full path
|
||||
link = link.getCanonicalFile();
|
||||
target = target.getCanonicalFile();
|
||||
|
||||
try {
|
||||
target = link.getParentFile().toPath().relativize(target.toPath()).toFile();
|
||||
} catch (Throwable e) {
|
||||
// unable to relativize link target
|
||||
}
|
||||
}
|
||||
|
||||
// create symlink via NIO.2
|
||||
return java.nio.file.Files.createSymbolicLink(link.toPath(), target.toPath()).toFile();
|
||||
}
|
||||
|
||||
public static boolean delete(File file) {
|
||||
// delete files or files
|
||||
return org.apache.commons.io.FileUtils.deleteQuietly(file);
|
||||
}
|
||||
|
||||
public static byte[] readFile(File source) throws IOException {
|
||||
InputStream in = new FileInputStream(source);
|
||||
|
||||
try {
|
||||
long size = source.length();
|
||||
if (size < 0 || size > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("Unable to read file: " + source);
|
||||
}
|
||||
|
||||
byte[] data = new byte[(int) size];
|
||||
|
||||
int position = 0;
|
||||
int read = 0;
|
||||
|
||||
while (position < data.length && (read = in.read(data, position, data.length - position)) >= 0) {
|
||||
position += read;
|
||||
}
|
||||
|
||||
return data;
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static String readAll(Reader source) throws IOException {
|
||||
StringBuilder text = new StringBuilder();
|
||||
char[] buffer = new char[2048];
|
||||
|
||||
int read = 0;
|
||||
while ((read = source.read(buffer)) >= 0) {
|
||||
text.append(buffer, 0, read);
|
||||
}
|
||||
|
||||
return text.toString();
|
||||
}
|
||||
|
||||
public static void writeFile(ByteBuffer data, File destination) throws IOException {
|
||||
FileChannel fileChannel = new FileOutputStream(destination).getChannel();
|
||||
|
||||
try {
|
||||
fileChannel.write(data);
|
||||
} finally {
|
||||
fileChannel.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String[]> readCSV(InputStream source, String charsetName, String separatorPattern) {
|
||||
Scanner scanner = new Scanner(source, charsetName);
|
||||
Pattern separator = Pattern.compile(separatorPattern);
|
||||
List<String[]> rows = new ArrayList<String[]>(65536);
|
||||
|
||||
while (scanner.hasNextLine()) {
|
||||
rows.add(separator.split(scanner.nextLine()));
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
public static Reader createTextReader(File file) throws IOException {
|
||||
CharsetDetector detector = new CharsetDetector();
|
||||
detector.setDeclaredEncoding("UTF-8"); // small boost for UTF-8 as default encoding
|
||||
detector.setText(new BufferedInputStream(new FileInputStream(file)));
|
||||
|
||||
CharsetMatch charset = detector.detect();
|
||||
if (charset != null)
|
||||
return charset.getReader();
|
||||
|
||||
// assume UTF-8 by default
|
||||
return new InputStreamReader(new FileInputStream(file), "UTF-8");
|
||||
}
|
||||
|
||||
public static String getText(ByteBuffer data) throws IOException {
|
||||
CharsetDetector detector = new CharsetDetector();
|
||||
detector.setDeclaredEncoding("UTF-8"); // small boost for UTF-8 as default encoding
|
||||
detector.setText(new ByteBufferInputStream(data));
|
||||
|
||||
CharsetMatch charset = detector.detect();
|
||||
if (charset != null) {
|
||||
try {
|
||||
return charset.getString();
|
||||
} catch (RuntimeException e) {
|
||||
throw new IOException("Failed to read text", e);
|
||||
}
|
||||
}
|
||||
|
||||
// assume UTF-8 by default
|
||||
return Charset.forName("UTF-8").decode(data).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pattern used for matching file extensions.
|
||||
*
|
||||
* e.g. "file.txt" -> match "txt", ".hidden" -> no match
|
||||
*/
|
||||
public static final Pattern EXTENSION = Pattern.compile("(?<=.[.])\\p{Alnum}+$");
|
||||
public static final String UNC_PREFIX = "\\\\";
|
||||
|
||||
public static String getExtension(File file) {
|
||||
if (file.isDirectory())
|
||||
return null;
|
||||
|
||||
return getExtension(file.getName());
|
||||
}
|
||||
|
||||
public static String getExtension(String name) {
|
||||
Matcher matcher = EXTENSION.matcher(name);
|
||||
|
||||
if (matcher.find()) {
|
||||
// extension without leading '.'
|
||||
return matcher.group();
|
||||
}
|
||||
|
||||
// no extension
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean hasExtension(File file, String... extensions) {
|
||||
// avoid native call for speed, if possible
|
||||
return hasExtension(file.getName(), extensions) && !file.isDirectory();
|
||||
}
|
||||
|
||||
public static boolean hasExtension(String filename, String... extensions) {
|
||||
for (String it : extensions) {
|
||||
if (filename.length() - it.length() >= 2 && filename.charAt(filename.length() - it.length() - 1) == '.') {
|
||||
String tail = filename.substring(filename.length() - it.length(), filename.length());
|
||||
if (tail.equalsIgnoreCase(it)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String getNameWithoutExtension(String name) {
|
||||
Matcher matcher = EXTENSION.matcher(name);
|
||||
|
||||
if (matcher.find()) {
|
||||
return name.substring(0, matcher.start() - 1);
|
||||
}
|
||||
|
||||
// no extension, return given name
|
||||
return name;
|
||||
}
|
||||
|
||||
public static String getName(File file) {
|
||||
if (file.getName().isEmpty() || UNC_PREFIX.equals(file.getParent()))
|
||||
return getFolderName(file);
|
||||
|
||||
return getNameWithoutExtension(file.getName());
|
||||
}
|
||||
|
||||
public static String getFolderName(File file) {
|
||||
if (UNC_PREFIX.equals(file.getParent()))
|
||||
return file.toString();
|
||||
|
||||
if (file.getName().length() > 0)
|
||||
return file.getName();
|
||||
|
||||
// file might be a drive (only has a path, but no name)
|
||||
return replacePathSeparators(file.toString(), "");
|
||||
}
|
||||
|
||||
public static boolean isDerived(File derivate, File prime) {
|
||||
return isDerived(getName(derivate), prime);
|
||||
}
|
||||
|
||||
public static boolean isDerived(String derivate, File prime) {
|
||||
String base = getName(prime).trim().toLowerCase();
|
||||
derivate = derivate.trim().toLowerCase();
|
||||
return derivate.startsWith(base);
|
||||
}
|
||||
|
||||
public static boolean isDerivedByExtension(File derivate, File prime) {
|
||||
return isDerivedByExtension(getName(derivate), prime);
|
||||
}
|
||||
|
||||
public static boolean isDerivedByExtension(String derivate, File prime) {
|
||||
String base = getName(prime).trim().toLowerCase();
|
||||
derivate = derivate.trim().toLowerCase();
|
||||
|
||||
if (derivate.equals(base))
|
||||
return true;
|
||||
|
||||
while (derivate.length() > base.length() && getExtension(derivate) != null) {
|
||||
derivate = getNameWithoutExtension(derivate);
|
||||
|
||||
if (derivate.equals(base))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean containsOnly(Collection<File> files, FileFilter filter) {
|
||||
if (files.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (File file : files) {
|
||||
if (!filter.accept(file))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static List<File> sortByUniquePath(Collection<File> files) {
|
||||
// sort by unique lower-case paths
|
||||
TreeSet<File> sortedSet = new TreeSet<File>(CASE_INSENSITIVE_PATH);
|
||||
sortedSet.addAll(files);
|
||||
|
||||
return new ArrayList<File>(sortedSet);
|
||||
}
|
||||
|
||||
public static List<File> filter(Iterable<File> files, FileFilter... filters) {
|
||||
List<File> accepted = new ArrayList<File>();
|
||||
|
||||
for (File file : files) {
|
||||
for (FileFilter filter : filters) {
|
||||
if (filter.accept(file)) {
|
||||
accepted.add(file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return accepted;
|
||||
}
|
||||
|
||||
public static FileFilter not(FileFilter filter) {
|
||||
return new NotFileFilter(filter);
|
||||
}
|
||||
|
||||
public static List<File> flatten(Iterable<File> roots, int maxDepth, boolean listHiddenFiles) {
|
||||
List<File> files = new ArrayList<File>();
|
||||
|
||||
// unfold/flatten file tree
|
||||
for (File root : roots) {
|
||||
if (root.isDirectory()) {
|
||||
listFiles(root, 0, files, maxDepth, listHiddenFiles);
|
||||
} else {
|
||||
files.add(root);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
public static List<File> listPath(File file) {
|
||||
return listPathTail(file, Integer.MAX_VALUE, false);
|
||||
}
|
||||
|
||||
public static List<File> listPathTail(File file, int tailSize, boolean reverse) {
|
||||
LinkedList<File> nodes = new LinkedList<File>();
|
||||
|
||||
File node = file;
|
||||
for (int i = 0; node != null && i < tailSize && !UNC_PREFIX.equals(node.toString()); i++, node = node.getParentFile()) {
|
||||
if (reverse) {
|
||||
nodes.addLast(node);
|
||||
} else {
|
||||
nodes.addFirst(node);
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public static File getRelativePathTail(File file, int tailSize) {
|
||||
File f = null;
|
||||
for (File it : listPathTail(file, tailSize, false)) {
|
||||
if (it.getParentFile() != null) {
|
||||
f = new File(f, it.getName());
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
public static List<File> listFiles(Iterable<File> folders, int maxDepth, boolean listHiddenFiles) {
|
||||
List<File> files = new ArrayList<File>();
|
||||
|
||||
// collect files from directory tree
|
||||
for (File folder : folders) {
|
||||
listFiles(folder, 0, files, maxDepth, listHiddenFiles);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
private static void listFiles(File folder, int depth, List<File> files, int maxDepth, boolean listHiddenFiles) {
|
||||
if (depth > maxDepth)
|
||||
return;
|
||||
|
||||
File[] children = folder.listFiles();
|
||||
if (children == null)
|
||||
return;
|
||||
|
||||
for (File file : children) {
|
||||
if (!listHiddenFiles && file.isHidden()) // ignore hidden files
|
||||
continue;
|
||||
|
||||
if (file.isDirectory()) {
|
||||
listFiles(file, depth + 1, files, maxDepth, listHiddenFiles);
|
||||
} else {
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static SortedMap<File, List<File>> mapByFolder(Iterable<File> files) {
|
||||
SortedMap<File, List<File>> map = new TreeMap<File, List<File>>();
|
||||
|
||||
for (File file : files) {
|
||||
File key = file.getParentFile();
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("Parent is null: " + file);
|
||||
}
|
||||
|
||||
List<File> valueList = map.get(key);
|
||||
if (valueList == null) {
|
||||
valueList = new ArrayList<File>();
|
||||
map.put(key, valueList);
|
||||
}
|
||||
|
||||
valueList.add(file);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Map<String, List<File>> mapByExtension(Iterable<File> files) {
|
||||
Map<String, List<File>> map = new HashMap<String, List<File>>();
|
||||
|
||||
for (File file : files) {
|
||||
String key = getExtension(file);
|
||||
if (key != null) {
|
||||
key = key.toLowerCase();
|
||||
}
|
||||
|
||||
List<File> valueList = map.get(key);
|
||||
if (valueList == null) {
|
||||
valueList = new ArrayList<File>();
|
||||
map.put(key, valueList);
|
||||
}
|
||||
|
||||
valueList.add(file);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid file name characters: \, /, :, *, ?, ", <, >, |, \r and \n
|
||||
*/
|
||||
public static final Pattern ILLEGAL_CHARACTERS = Pattern.compile("[\\\\/:*?\"<>|\\r\\n]|[ ]+$|(?<=[^.])[.]+$");
|
||||
|
||||
/**
|
||||
* Strip file name of invalid characters
|
||||
*
|
||||
* @param filename
|
||||
* original filename
|
||||
* @return valid file name stripped of invalid characters
|
||||
*/
|
||||
public static String validateFileName(CharSequence filename) {
|
||||
// strip invalid characters from file name
|
||||
return ILLEGAL_CHARACTERS.matcher(filename).replaceAll("").replaceAll("\\s+", " ").trim();
|
||||
}
|
||||
|
||||
public static boolean isInvalidFileName(CharSequence filename) {
|
||||
// check if file name contains any illegal characters
|
||||
return ILLEGAL_CHARACTERS.matcher(filename).find();
|
||||
}
|
||||
|
||||
public static File validateFileName(File file) {
|
||||
// windows drives (e.g. c:, d:, etc.) are never invalid because name will be an empty string
|
||||
if (!isInvalidFileName(file.getName()))
|
||||
return file;
|
||||
|
||||
// validate file name only
|
||||
return new File(file.getParentFile(), validateFileName(file.getName()));
|
||||
}
|
||||
|
||||
public static File validateFilePath(File path) {
|
||||
Iterator<File> nodes = listPath(path).iterator();
|
||||
|
||||
// initialize with root node, keep original root object if possible (so we don't loose the drive on windows)
|
||||
File validatedPath = validateFileName(nodes.next());
|
||||
|
||||
// validate the rest of the path
|
||||
while (nodes.hasNext()) {
|
||||
validatedPath = new File(validatedPath, validateFileName(nodes.next().getName()));
|
||||
}
|
||||
|
||||
return validatedPath;
|
||||
}
|
||||
|
||||
public static boolean isInvalidFilePath(File path) {
|
||||
// check if file name contains any illegal characters
|
||||
for (File node = path; node != null; node = node.getParentFile()) {
|
||||
if (isInvalidFileName(node.getName()))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String normalizePathSeparators(String path) {
|
||||
// special handling for UNC paths
|
||||
if (path.startsWith(UNC_PREFIX) && path.length() > 2) {
|
||||
return UNC_PREFIX + path.substring(2).replace('\\', '/');
|
||||
}
|
||||
return path.replace('\\', '/');
|
||||
}
|
||||
|
||||
public static String replacePathSeparators(CharSequence path) {
|
||||
return replacePathSeparators(path, " ");
|
||||
}
|
||||
|
||||
public static String replacePathSeparators(CharSequence path, String replacement) {
|
||||
return Pattern.compile("\\s*[\\\\/]+\\s*").matcher(path).replaceAll(replacement);
|
||||
}
|
||||
|
||||
public static String getXmlString(Document dom) throws TransformerException {
|
||||
Transformer tr = TransformerFactory.newInstance().newTransformer();
|
||||
tr.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
tr.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
|
||||
// create string from dom
|
||||
StringWriter buffer = new StringWriter();
|
||||
tr.transform(new DOMSource(dom), new StreamResult(buffer));
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static final long KILO = 1024;
|
||||
public static final long MEGA = 1024 * KILO;
|
||||
public static final long GIGA = 1024 * MEGA;
|
||||
|
||||
public static String formatSize(long size) {
|
||||
if (size >= MEGA)
|
||||
return String.format("%,d MB", size / MEGA);
|
||||
else if (size >= KILO)
|
||||
return String.format("%,d KB", size / KILO);
|
||||
else
|
||||
return String.format("%,d Byte", size);
|
||||
}
|
||||
|
||||
public static final FileFilter FOLDERS = new FileFilter() {
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return file.isDirectory();
|
||||
}
|
||||
};
|
||||
|
||||
public static final FileFilter FILES = new FileFilter() {
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return file.isFile();
|
||||
}
|
||||
};
|
||||
|
||||
public static final FileFilter TEMPORARY = new FileFilter() {
|
||||
|
||||
private final String tmpdir = System.getProperty("java.io.tmpdir");
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return file.getAbsolutePath().startsWith(tmpdir);
|
||||
}
|
||||
};
|
||||
|
||||
public static class ParentFilter implements FileFilter {
|
||||
|
||||
private final File folder;
|
||||
|
||||
public ParentFilter(File folder) {
|
||||
this.folder = folder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return listPath(file).contains(folder);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExtensionFileFilter implements FileFilter {
|
||||
|
||||
private final String[] extensions;
|
||||
|
||||
public ExtensionFileFilter(String... extensions) {
|
||||
this.extensions = extensions;
|
||||
}
|
||||
|
||||
public ExtensionFileFilter(Collection<String> extensions) {
|
||||
this.extensions = extensions.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return hasExtension(file, extensions);
|
||||
}
|
||||
|
||||
public boolean accept(String name) {
|
||||
return hasExtension(name, extensions);
|
||||
}
|
||||
|
||||
public boolean acceptExtension(String extension) {
|
||||
for (String other : extensions) {
|
||||
if (other.equalsIgnoreCase(extension))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String extension() {
|
||||
return extensions[0];
|
||||
}
|
||||
|
||||
public String[] extensions() {
|
||||
return extensions.clone();
|
||||
}
|
||||
}
|
||||
|
||||
public static class RegexFileFilter implements FileFilter, FilenameFilter {
|
||||
|
||||
private final Pattern pattern;
|
||||
|
||||
public RegexFileFilter(Pattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return pattern.matcher(name).find();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return accept(file.getParentFile(), file.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public static class NotFileFilter implements FileFilter {
|
||||
|
||||
public FileFilter filter;
|
||||
|
||||
public NotFileFilter(FileFilter filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return !filter.accept(file);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Comparator<File> CASE_INSENSITIVE_PATH = new Comparator<File>() {
|
||||
|
||||
@Override
|
||||
public int compare(File o1, File o2) {
|
||||
return o1.getPath().compareToIgnoreCase(o2.getPath());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dummy constructor to prevent instantiation.
|
||||
*/
|
||||
private FileUtilities() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public abstract class FilterIterator<S, T> implements Iterator<T> {
|
||||
|
||||
private final Iterator<S> sourceIterator;
|
||||
|
||||
|
||||
public FilterIterator(Iterable<S> source) {
|
||||
this(source.iterator());
|
||||
}
|
||||
|
||||
|
||||
public FilterIterator(Iterator<S> sourceIterator) {
|
||||
this.sourceIterator = sourceIterator;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return peekNext(false) != null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
try {
|
||||
return peekNext(true);
|
||||
} finally {
|
||||
current = null;
|
||||
}
|
||||
}
|
||||
|
||||
private T current = null;
|
||||
|
||||
|
||||
private T peekNext(boolean forceNext) {
|
||||
while (current == null && (forceNext || (sourceIterator.hasNext()))) {
|
||||
current = filter(sourceIterator.next());
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
protected abstract T filter(S sourceValue);
|
||||
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
sourceIterator.remove();
|
||||
}
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ca.odell.glazedlists.EventList;
|
||||
import ca.odell.glazedlists.event.ListEvent;
|
||||
import ca.odell.glazedlists.event.ListEventListener;
|
||||
|
||||
|
||||
public class ListChangeSynchronizer<E> implements ListEventListener<E> {
|
||||
|
||||
private final List<E> target;
|
||||
|
||||
|
||||
public ListChangeSynchronizer(EventList<E> source, List<E> target) {
|
||||
this.target = target;
|
||||
source.addListEventListener(this);
|
||||
}
|
||||
|
||||
|
||||
public void listChanged(ListEvent<E> listChanges) {
|
||||
EventList<E> source = listChanges.getSourceList();
|
||||
|
||||
// update target list
|
||||
while (listChanges.next()) {
|
||||
int index = listChanges.getIndex();
|
||||
int type = listChanges.getType();
|
||||
|
||||
switch (type) {
|
||||
case ListEvent.INSERT:
|
||||
target.add(index, source.get(index));
|
||||
break;
|
||||
case ListEvent.UPDATE:
|
||||
target.set(index, source.get(index));
|
||||
break;
|
||||
case ListEvent.DELETE:
|
||||
target.remove(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static <E> ListChangeSynchronizer<E> syncEventListToList(EventList<E> source, List<E> target) {
|
||||
return new ListChangeSynchronizer<E>(source, target);
|
||||
}
|
||||
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.RandomAccess;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import net.sourceforge.tuned.PreferencesMap.Adapter;
|
||||
|
||||
|
||||
public class PreferencesList<T> extends AbstractList<T> implements RandomAccess {
|
||||
|
||||
private final PreferencesMap<T> prefs;
|
||||
|
||||
|
||||
public PreferencesList(PreferencesMap<T> preferencesMap) {
|
||||
this.prefs = preferencesMap;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T get(int index) {
|
||||
return prefs.get(key(index));
|
||||
}
|
||||
|
||||
|
||||
private String key(int index) {
|
||||
return Integer.toString(index);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return prefs.size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean add(T e) {
|
||||
setImpl(size(), e);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void add(int index, T element) {
|
||||
int size = size();
|
||||
|
||||
if (index > size)
|
||||
throw new IndexOutOfBoundsException(String.format("Index: %d, Size: %d", index, size));
|
||||
|
||||
copy(index, index + 1, size - index);
|
||||
|
||||
setImpl(index, element);
|
||||
}
|
||||
|
||||
|
||||
private T setImpl(int index, T element) {
|
||||
return prefs.put(key(index), element);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return always null
|
||||
*/
|
||||
@Override
|
||||
public T remove(int index) {
|
||||
int lastIndex = size() - 1;
|
||||
|
||||
copy(index + 1, index, lastIndex - index);
|
||||
prefs.remove(key(lastIndex));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T set(int index, T element) {
|
||||
if (index < 0 || index >= size())
|
||||
throw new IndexOutOfBoundsException();
|
||||
|
||||
return setImpl(index, element);
|
||||
}
|
||||
|
||||
|
||||
private void copy(int startIndex, int newStartIndex, int count) {
|
||||
if (count == 0 || startIndex == newStartIndex)
|
||||
return;
|
||||
|
||||
List<T> copy = new ArrayList<T>(subList(startIndex, startIndex + count));
|
||||
|
||||
for (int i = newStartIndex, n = 0; n < count; i++, n++) {
|
||||
setImpl(i, copy.get(n));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void trimToSize(int limit) {
|
||||
for (int i = size() - 1; i >= limit; i--) {
|
||||
remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void set(Collection<T> data) {
|
||||
// remove all elements beyond data.size
|
||||
trimToSize(data.size());
|
||||
|
||||
// override elements
|
||||
int i = 0;
|
||||
for (T element : data) {
|
||||
setImpl(i++, element);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
prefs.clear();
|
||||
}
|
||||
|
||||
|
||||
public static PreferencesList<String> map(Preferences prefs) {
|
||||
return new PreferencesList<String>(PreferencesMap.map(prefs));
|
||||
}
|
||||
|
||||
|
||||
public static <T> PreferencesList<T> map(Preferences prefs, Adapter<T> adapter) {
|
||||
return new PreferencesList<T>(PreferencesMap.map(prefs, adapter));
|
||||
}
|
||||
|
||||
}
|
@ -1,347 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
|
||||
public class PreferencesMap<T> implements Map<String, T> {
|
||||
|
||||
private final Preferences prefs;
|
||||
private final Adapter<T> adapter;
|
||||
|
||||
|
||||
public PreferencesMap(Preferences prefs, Adapter<T> adapter) {
|
||||
this.prefs = prefs;
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T get(Object key) {
|
||||
return adapter.get(prefs, key.toString());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T put(String key, T value) {
|
||||
adapter.put(prefs, key, value);
|
||||
|
||||
// don't know previous entry
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T remove(Object key) {
|
||||
adapter.remove(prefs, key.toString());
|
||||
|
||||
// don't know removed entry
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public String[] keys() {
|
||||
try {
|
||||
return adapter.keys(prefs);
|
||||
} catch (BackingStoreException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
for (String key : keys()) {
|
||||
adapter.remove(prefs, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
if (key instanceof String) {
|
||||
return Arrays.asList(keys()).contains(key);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
for (String key : keys()) {
|
||||
if (value.equals(get(key)))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<Entry<String, T>> entrySet() {
|
||||
Set<Map.Entry<String, T>> entries = new LinkedHashSet<Map.Entry<String, T>>();
|
||||
|
||||
for (String key : keys()) {
|
||||
entries.add(new PreferencesEntry<T>(prefs, key, adapter));
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> keySet() {
|
||||
return new LinkedHashSet<String>(Arrays.asList(keys()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends String, ? extends T> map) {
|
||||
for (Map.Entry<? extends String, ? extends T> entry : map.entrySet()) {
|
||||
put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return keys().length;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Collection<T> values() {
|
||||
List<T> values = new ArrayList<T>();
|
||||
|
||||
for (String key : keys()) {
|
||||
values.add(get(key));
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
public static PreferencesMap<String> map(Preferences prefs) {
|
||||
return map(prefs, new StringAdapter());
|
||||
}
|
||||
|
||||
|
||||
public static <T> PreferencesMap<T> map(Preferences prefs, Adapter<T> adapter) {
|
||||
return new PreferencesMap<T>(prefs, adapter);
|
||||
}
|
||||
|
||||
|
||||
public static interface Adapter<T> {
|
||||
|
||||
public String[] keys(Preferences prefs) throws BackingStoreException;
|
||||
|
||||
|
||||
public T get(Preferences prefs, String key);
|
||||
|
||||
|
||||
public void put(Preferences prefs, String key, T value);
|
||||
|
||||
|
||||
public void remove(Preferences prefs, String key);
|
||||
}
|
||||
|
||||
|
||||
public static abstract class AbstractAdapter<T> implements Adapter<T> {
|
||||
|
||||
@Override
|
||||
public abstract T get(Preferences prefs, String key);
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void put(Preferences prefs, String key, T value);
|
||||
|
||||
|
||||
@Override
|
||||
public String[] keys(Preferences prefs) throws BackingStoreException {
|
||||
return prefs.keys();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void remove(Preferences prefs, String key) {
|
||||
prefs.remove(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class StringAdapter extends AbstractAdapter<String> {
|
||||
|
||||
@Override
|
||||
public String get(Preferences prefs, String key) {
|
||||
return prefs.get(key, null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void put(Preferences prefs, String key, String value) {
|
||||
prefs.put(key, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class SimpleAdapter<T> extends AbstractAdapter<T> {
|
||||
|
||||
private final Constructor<T> constructor;
|
||||
|
||||
|
||||
public SimpleAdapter(Class<T> type) {
|
||||
try {
|
||||
constructor = type.getConstructor(String.class);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T get(Preferences prefs, String key) {
|
||||
String value = prefs.get(key, null);
|
||||
|
||||
if (value != null) {
|
||||
try {
|
||||
return constructor.newInstance(value);
|
||||
} catch (InvocationTargetException e) {
|
||||
// try to throw the cause directly, e.g. NumberFormatException
|
||||
throw ExceptionUtilities.asRuntimeException(e.getCause());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void put(Preferences prefs, String key, T value) {
|
||||
prefs.put(key, value.toString());
|
||||
}
|
||||
|
||||
|
||||
public static <T> SimpleAdapter<T> forClass(Class<T> type) {
|
||||
return new SimpleAdapter<T>(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class SerializableAdapter<T extends Serializable> extends AbstractAdapter<T> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T get(Preferences prefs, String key) {
|
||||
byte[] bytes = prefs.getByteArray(key, null);
|
||||
|
||||
if (bytes == null)
|
||||
return null;
|
||||
|
||||
try {
|
||||
ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
|
||||
Object object = in.readObject();
|
||||
in.close();
|
||||
|
||||
return (T) object;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void put(Preferences prefs, String key, T value) {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
try {
|
||||
ObjectOutputStream out = new ObjectOutputStream(buffer);
|
||||
out.writeObject(value);
|
||||
out.close();
|
||||
|
||||
prefs.putByteArray(key, buffer.toByteArray());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class PreferencesEntry<T> implements Entry<String, T> {
|
||||
|
||||
private final String key;
|
||||
|
||||
private final Preferences prefs;
|
||||
|
||||
private final Adapter<T> adapter;
|
||||
|
||||
private T defaultValue = null;
|
||||
|
||||
|
||||
public PreferencesEntry(Preferences prefs, String key, Adapter<T> adapter) {
|
||||
this.key = key;
|
||||
this.prefs = prefs;
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T getValue() {
|
||||
T value = adapter.get(prefs, key);
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T setValue(T value) {
|
||||
adapter.put(prefs, key, value);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public PreferencesEntry<T> defaultValue(T defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public void remove() {
|
||||
adapter.remove(prefs, key);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import static java.util.Arrays.*;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public final class StringUtilities {
|
||||
|
||||
public static boolean isEmptyValue(Object object) {
|
||||
return object == null || object.toString().length() == 0;
|
||||
}
|
||||
|
||||
|
||||
public static String joinBy(CharSequence delimiter, Object... values) {
|
||||
return join(asList(values), delimiter);
|
||||
}
|
||||
|
||||
|
||||
public static String join(Object[] values, CharSequence delimiter) {
|
||||
return join(asList(values), delimiter);
|
||||
}
|
||||
|
||||
|
||||
public static String join(Iterable<?> values, CharSequence delimiter) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
|
||||
Object value = iterator.next();
|
||||
if (!isEmptyValue(value)) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(delimiter);
|
||||
}
|
||||
|
||||
sb.append(value);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dummy constructor to prevent instantiation.
|
||||
*/
|
||||
private StringUtilities() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
|
||||
public class TeePrintStream extends PrintStream {
|
||||
|
||||
private final PrintStream cc;
|
||||
|
||||
|
||||
public TeePrintStream(OutputStream out, boolean autoFlush, String encoding, PrintStream cc) throws UnsupportedEncodingException {
|
||||
super(out, autoFlush, encoding);
|
||||
this.cc = cc;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
cc.close();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
super.flush();
|
||||
cc.flush();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(byte[] buf, int off, int len) {
|
||||
super.write(buf, off, len);
|
||||
cc.write(buf, off, len);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(int b) {
|
||||
super.write(b);
|
||||
cc.write(b);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
super.write(b);
|
||||
cc.write(b);
|
||||
}
|
||||
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
public final class TemporaryFolder {
|
||||
|
||||
private static final Map<String, TemporaryFolder> folders = new HashMap<String, TemporaryFolder>();
|
||||
|
||||
|
||||
/**
|
||||
* Get a {@link TemporaryFolder} instance for a given name. The actual directory will be
|
||||
* created lazily (e.g. when a file is created). The name of the directory will start with
|
||||
* the given name (lower-case) and contain a unique id, so multiple application instances
|
||||
* may run at the same time without the risk of interference.
|
||||
*
|
||||
* @param name case-insensitive name of a temporary folder (e.g. application name)
|
||||
* @return temporary folder for this name
|
||||
*/
|
||||
public static TemporaryFolder getFolder(String name) {
|
||||
// make name case-insensitive
|
||||
name = name.toLowerCase();
|
||||
|
||||
synchronized (folders) {
|
||||
TemporaryFolder folder = folders.get(name);
|
||||
|
||||
if (folder == null) {
|
||||
File tmpdir = new File(System.getProperty("java.io.tmpdir"));
|
||||
String subdir = String.format("%s [%s]", name, UUID.randomUUID());
|
||||
|
||||
folder = new TemporaryFolder(new File(tmpdir, subdir));
|
||||
folders.put(name, folder);
|
||||
}
|
||||
|
||||
return folder;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete all temporary folders on shutdown
|
||||
*/
|
||||
static {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread("TemporaryFolder Cleanup") {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (folders) {
|
||||
for (TemporaryFolder folder : folders.values()) {
|
||||
folder.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private final File root;
|
||||
|
||||
|
||||
private TemporaryFolder(File root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an empty file in this temporary folder.
|
||||
*
|
||||
* @param name name of the file
|
||||
* @return newly created file
|
||||
* @throws IOException if an I/O error occurred
|
||||
*/
|
||||
public File createFile(String name) throws IOException {
|
||||
|
||||
// if the directory does not exist it will be created
|
||||
File file = new File(getFolder(), name);
|
||||
file.createNewFile();
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an empty file in this temporary folder, using the given prefix and suffix to
|
||||
* generate its name.
|
||||
*
|
||||
* @param prefix The prefix string to be used in generating the file's name; must be at
|
||||
* least three characters long
|
||||
* @param suffix The suffix string to be used in generating the file's name; may be null,
|
||||
* in which case the suffix ".tmp" will be used
|
||||
* @return An abstract pathname denoting a newly-created empty file
|
||||
* @throws IOException If a file could not be created
|
||||
* @see File#createTempFile(String, String)
|
||||
*/
|
||||
public File createFile(String prefix, String suffix) throws IOException {
|
||||
return File.createTempFile(prefix, suffix, getFolder());
|
||||
}
|
||||
|
||||
|
||||
public boolean deleteFile(String name) {
|
||||
return new File(getFolder(), name).delete();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the {@link File} object for this {@link TemporaryFolder}. The actual directory
|
||||
* for the {@link TemporaryFolder} instance will be created by this method.
|
||||
*
|
||||
* @return the {@link File} object for this {@link TemporaryFolder}
|
||||
*/
|
||||
public File getFolder() {
|
||||
if (!root.exists()) {
|
||||
root.mkdirs();
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
public TemporaryFolder subFolder(String name) {
|
||||
return new TemporaryFolder(new File(getFolder(), name));
|
||||
}
|
||||
|
||||
|
||||
public List<File> list(boolean recursive) {
|
||||
List<File> list = new ArrayList<File>();
|
||||
|
||||
list(root, list, recursive);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
private void list(File file, List<File> list, boolean recursive) {
|
||||
if (file.isDirectory()) {
|
||||
for (File entry : file.listFiles()) {
|
||||
if (entry.isDirectory()) {
|
||||
if (recursive) {
|
||||
list(entry, list, recursive);
|
||||
}
|
||||
} else {
|
||||
list.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void delete() {
|
||||
delete(root);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete files/folders recursively
|
||||
*
|
||||
* @param file file/folder that will be deleted
|
||||
*/
|
||||
private void delete(File file) {
|
||||
if (file.isDirectory()) {
|
||||
for (File entry : file.listFiles()) {
|
||||
delete(entry);
|
||||
}
|
||||
}
|
||||
|
||||
file.delete();
|
||||
}
|
||||
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public abstract class Timer implements Runnable {
|
||||
|
||||
private final ThreadFactory threadFactory = new DefaultThreadFactory("Timer", Thread.NORM_PRIORITY, true);
|
||||
|
||||
private ScheduledThreadPoolExecutor executor;
|
||||
private ScheduledFuture<?> scheduledFuture;
|
||||
private Thread shutdownHook;
|
||||
|
||||
public synchronized void set(long delay, TimeUnit unit, boolean runBeforeShutdown) {
|
||||
// create executor if necessary
|
||||
if (executor == null) {
|
||||
executor = new ScheduledThreadPoolExecutor(1, threadFactory);
|
||||
}
|
||||
|
||||
// cancel existing future task
|
||||
if (scheduledFuture != null) {
|
||||
scheduledFuture.cancel(true);
|
||||
}
|
||||
|
||||
Runnable runnable = this;
|
||||
|
||||
if (runBeforeShutdown) {
|
||||
try {
|
||||
addShutdownHook();
|
||||
} catch (Exception e) {
|
||||
// may fail if running with restricted permissions
|
||||
Logger.getLogger(getClass().getName()).log(Level.WARNING, e.getClass().getName() + ": " + e.getMessage());
|
||||
}
|
||||
|
||||
// remove shutdown hook after execution
|
||||
runnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Timer.this.run();
|
||||
} finally {
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
try {
|
||||
// remove existing shutdown hook, if any
|
||||
removeShutdownHook();
|
||||
} catch (Exception e) {
|
||||
// may fail if running with restricted permissions
|
||||
Logger.getLogger(getClass().getName()).log(Level.WARNING, e.getClass().getName() + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
scheduledFuture = executor.schedule(runnable, delay, unit);
|
||||
}
|
||||
|
||||
public synchronized void cancel() {
|
||||
removeShutdownHook();
|
||||
if (executor != null) {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
scheduledFuture = null;
|
||||
executor = null;
|
||||
}
|
||||
|
||||
private synchronized void addShutdownHook() {
|
||||
if (shutdownHook == null) {
|
||||
shutdownHook = new Thread(this);
|
||||
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void removeShutdownHook() {
|
||||
if (shutdownHook != null) {
|
||||
try {
|
||||
if (shutdownHook != Thread.currentThread()) {
|
||||
// can't remove shutdown hooks anymore, once runtime is shutting down,
|
||||
// so don't remove the shutdown hook, if we are running on the shutdown hook
|
||||
Runtime.getRuntime().removeShutdownHook(shutdownHook);
|
||||
}
|
||||
} finally {
|
||||
shutdownHook = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
|
||||
public abstract class TreeIterator<T> implements Iterator<T> {
|
||||
|
||||
private final LinkedList<Iterator<T>> recursionStack = new LinkedList<Iterator<T>>();
|
||||
|
||||
|
||||
public TreeIterator(T... root) {
|
||||
recursionStack.push(Arrays.asList(root).iterator());
|
||||
}
|
||||
|
||||
|
||||
protected abstract Iterator<T> children(T node);
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return currentIterator().hasNext();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
T node = currentIterator().next();
|
||||
|
||||
Iterator<T> children = children(node);
|
||||
if (children != null && children.hasNext()) {
|
||||
// step into next recursion level
|
||||
recursionStack.push(children);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
private Iterator<T> currentIterator() {
|
||||
Iterator<T> iterator = recursionStack.peek();
|
||||
|
||||
if (iterator.hasNext() || recursionStack.size() <= 1)
|
||||
return iterator;
|
||||
|
||||
// step back one recursion level
|
||||
recursionStack.pop();
|
||||
|
||||
return currentIterator();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
// can't just use remove() on current iterator, because
|
||||
// we may have stepped into the next recursion level
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpression;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
|
||||
public final class XPathUtilities {
|
||||
|
||||
public static Node selectNode(String xpath, Object node) {
|
||||
try {
|
||||
return (Node) getXPath(xpath).evaluate(node, XPathConstants.NODE);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static List<Node> selectNodes(String xpath, Object node) {
|
||||
try {
|
||||
return new NodeListDecorator((NodeList) getXPath(xpath).evaluate(node, XPathConstants.NODESET));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String selectString(String xpath, Object node) {
|
||||
try {
|
||||
return ((String) getXPath(xpath).evaluate(node, XPathConstants.STRING)).trim();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param nodeName search for nodes with this name
|
||||
* @param parentNode search in the child nodes of this nodes
|
||||
* @return text content of the child node or null if no child with the given name was found
|
||||
*/
|
||||
public static Node getChild(String nodeName, Node parentNode) {
|
||||
for (Node child : new NodeListDecorator(parentNode.getChildNodes())) {
|
||||
if (nodeName.equals(child.getNodeName()))
|
||||
return child;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static List<Node> getChildren(String nodeName, Node parentNode) {
|
||||
List<Node> children = new ArrayList<Node>();
|
||||
|
||||
for (Node child : new NodeListDecorator(parentNode.getChildNodes())) {
|
||||
if (nodeName.equals(child.getNodeName()))
|
||||
children.add(child);
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
|
||||
public static String getAttribute(String attribute, Node node) {
|
||||
Node attributeNode = node.getAttributes().getNamedItem(attribute);
|
||||
|
||||
if (attributeNode != null)
|
||||
return attributeNode.getNodeValue().trim();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get text content of the first child node matching the given node name. Use this method
|
||||
* instead of {@link #selectString(String, Object)} whenever xpath support is not required,
|
||||
* because it is much faster, especially for large documents.
|
||||
*
|
||||
* @param childName search for nodes with this name
|
||||
* @param parentNode search in the child nodes of this nodes
|
||||
* @return text content of the child node or null if no child with the given name was found
|
||||
*/
|
||||
public static String getTextContent(String childName, Node parentNode) {
|
||||
Node child = getChild(childName, parentNode);
|
||||
|
||||
if (child == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getTextContent(child);
|
||||
}
|
||||
|
||||
|
||||
public static String getTextContent(Node node) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (Node textNode : getChildren("#text", node)) {
|
||||
sb.append(textNode.getNodeValue());
|
||||
}
|
||||
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
|
||||
public static Integer getIntegerContent(String childName, Node parentNode) {
|
||||
try {
|
||||
return new Integer(getTextContent(childName, parentNode));
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static XPathExpression getXPath(String xpath) throws XPathExpressionException {
|
||||
return XPathFactory.newInstance().newXPath().compile(xpath);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dummy constructor to prevent instantiation.
|
||||
*/
|
||||
private XPathUtilities() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
protected static class NodeListDecorator extends AbstractList<Node> {
|
||||
|
||||
private final NodeList nodes;
|
||||
|
||||
|
||||
public NodeListDecorator(NodeList nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Node get(int index) {
|
||||
return nodes.item(index);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return nodes.getLength();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,216 +0,0 @@
|
||||
// https://github.com/sonatype/nexus/blob/2f0e154ec565969b4fd8698883ab76a461210f4f/nexus/nexus-test-harness/nexus-it-helper-plugin/src/main/java/org/sonatype/nexus/rt/prefs/FilePreferences.java
|
||||
|
||||
package net.sourceforge.tuned.prefs;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeMap;
|
||||
import java.util.prefs.AbstractPreferences;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Preferences implementation that stores to a user-defined file. See FilePreferencesFactory. Modified by cstamas,
|
||||
* switched to SLF4J logging, and exposed preferences file property.
|
||||
*
|
||||
* Modified to use '/' as path separator and not '.' because it breaks when keys containing '.' are used.
|
||||
*
|
||||
* @author David Croft (<a href="http://www.davidc.net">www.davidc.net</a>)
|
||||
* @version $Id: FilePreferences.java 283 2009-06-18 17:06:58Z david $
|
||||
*/
|
||||
public class FilePreferences extends AbstractPreferences {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FilePreferences.class.getName());
|
||||
|
||||
private Map<String, String> root;
|
||||
|
||||
private Map<String, FilePreferences> children;
|
||||
|
||||
private boolean isRemoved = false;
|
||||
|
||||
|
||||
public FilePreferences(AbstractPreferences parent, String name) {
|
||||
super(parent, name);
|
||||
|
||||
log.debug("Instantiating node {}", name);
|
||||
|
||||
root = new TreeMap<String, String>();
|
||||
children = new TreeMap<String, FilePreferences>();
|
||||
|
||||
try {
|
||||
sync();
|
||||
} catch (BackingStoreException e) {
|
||||
log.error("Unable to sync on creation of node " + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void putSpi(String key, String value) {
|
||||
root.put(key, value);
|
||||
try {
|
||||
flush();
|
||||
} catch (BackingStoreException e) {
|
||||
log.error("Unable to flush after putting " + key, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getSpi(String key) {
|
||||
return root.get(key);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void removeSpi(String key) {
|
||||
root.remove(key);
|
||||
try {
|
||||
flush();
|
||||
} catch (BackingStoreException e) {
|
||||
log.error("Unable to flush after removing " + key, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void removeNodeSpi() throws BackingStoreException {
|
||||
isRemoved = true;
|
||||
flush();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String[] keysSpi() throws BackingStoreException {
|
||||
return root.keySet().toArray(new String[root.keySet().size()]);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String[] childrenNamesSpi() throws BackingStoreException {
|
||||
return children.keySet().toArray(new String[children.keySet().size()]);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected FilePreferences childSpi(String name) {
|
||||
FilePreferences child = children.get(name);
|
||||
if (child == null || child.isRemoved()) {
|
||||
child = new FilePreferences(this, name);
|
||||
children.put(name, child);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void syncSpi() throws BackingStoreException {
|
||||
if (isRemoved()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final File file = FilePreferencesFactory.getPreferencesFile();
|
||||
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (file) {
|
||||
Properties p = new Properties();
|
||||
try {
|
||||
p.load(new FileInputStream(file));
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
getPath(sb);
|
||||
String path = sb.toString();
|
||||
|
||||
final Enumeration<?> pnen = p.propertyNames();
|
||||
while (pnen.hasMoreElements()) {
|
||||
String propKey = (String) pnen.nextElement();
|
||||
if (propKey.startsWith(path)) {
|
||||
String subKey = propKey.substring(path.length());
|
||||
// Only load immediate descendants
|
||||
if (subKey.indexOf('/') == -1) {
|
||||
root.put(subKey, p.getProperty(propKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new BackingStoreException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void getPath(StringBuilder sb) {
|
||||
final FilePreferences parent = (FilePreferences) parent();
|
||||
if (parent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent.getPath(sb);
|
||||
sb.append(name()).append('/');
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void flushSpi() throws BackingStoreException {
|
||||
final File file = FilePreferencesFactory.getPreferencesFile();
|
||||
|
||||
synchronized (file) {
|
||||
Properties p = new Properties();
|
||||
try {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
getPath(sb);
|
||||
String path = sb.toString();
|
||||
|
||||
if (file.exists()) {
|
||||
p.load(new FileInputStream(file));
|
||||
|
||||
List<String> toRemove = new ArrayList<String>();
|
||||
|
||||
// Make a list of all direct children of this node to be removed
|
||||
final Enumeration<?> pnen = p.propertyNames();
|
||||
while (pnen.hasMoreElements()) {
|
||||
String propKey = (String) pnen.nextElement();
|
||||
if (propKey.startsWith(path)) {
|
||||
String subKey = propKey.substring(path.length());
|
||||
// Only do immediate descendants
|
||||
if (subKey.indexOf('/') == -1) {
|
||||
toRemove.add(propKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove them now that the enumeration is done with
|
||||
for (String propKey : toRemove) {
|
||||
p.remove(propKey);
|
||||
}
|
||||
}
|
||||
|
||||
// If this node hasn't been removed, add back in any values
|
||||
if (!isRemoved) {
|
||||
for (String s : root.keySet()) {
|
||||
p.setProperty(path + s, root.get(s));
|
||||
}
|
||||
}
|
||||
|
||||
p.store(new FileOutputStream(file), "FilePreferences");
|
||||
} catch (IOException e) {
|
||||
throw new BackingStoreException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
// https://github.com/sonatype/nexus/blob/2f0e154ec565969b4fd8698883ab76a461210f4f/nexus/nexus-test-harness/nexus-it-helper-plugin/src/main/java/org/sonatype/nexus/rt/prefs/FilePreferencesFactory.java
|
||||
|
||||
package net.sourceforge.tuned.prefs;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.prefs.Preferences;
|
||||
import java.util.prefs.PreferencesFactory;
|
||||
|
||||
|
||||
/**
|
||||
* PreferencesFactory implementation that stores the preferences in a user-defined file. To use it, set the system
|
||||
* property <tt>java.util.prefs.PreferencesFactory</tt> to <tt>net.sourceforge.tuned.pref.FilePreferencesFactory</tt>
|
||||
* <p/>
|
||||
* The file defaults to [user.home]/.fileprefs, but may be overridden with the system property
|
||||
* <tt>net.sourceforge.tuned.pref.FilePreferencesFactory.file</tt>. Modified by cstamas, switched to SLF4J logging, and
|
||||
* exposed preferences file property.
|
||||
*
|
||||
* @author David Croft (<a href="http://www.davidc.net">www.davidc.net</a>)
|
||||
* @version $Id: FilePreferencesFactory.java 282 2009-06-18 17:05:18Z david $
|
||||
*/
|
||||
public class FilePreferencesFactory implements PreferencesFactory {
|
||||
|
||||
Preferences rootPreferences;
|
||||
|
||||
public static final String SYSTEM_PROPERTY_FILE = "net.sourceforge.tuned.prefs.file";
|
||||
|
||||
|
||||
public Preferences systemRoot() {
|
||||
return userRoot();
|
||||
}
|
||||
|
||||
|
||||
public Preferences userRoot() {
|
||||
if (rootPreferences == null) {
|
||||
rootPreferences = new FilePreferences(null, "");
|
||||
}
|
||||
|
||||
return rootPreferences;
|
||||
}
|
||||
|
||||
private static File preferencesFile;
|
||||
|
||||
|
||||
public static File getPreferencesFile() {
|
||||
if (preferencesFile == null) {
|
||||
String prefsFile = System.getProperty(SYSTEM_PROPERTY_FILE);
|
||||
|
||||
if (prefsFile == null || prefsFile.length() == 0) {
|
||||
prefsFile = System.getProperty("user.home") + File.separator + ".fileprefs";
|
||||
}
|
||||
|
||||
preferencesFile = new File(prefsFile).getAbsoluteFile();
|
||||
}
|
||||
|
||||
return preferencesFile;
|
||||
}
|
||||
|
||||
|
||||
public static void setPreferencesFile(File file) {
|
||||
preferencesFile = file;
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
|
||||
import javax.swing.event.SwingPropertyChangeSupport;
|
||||
|
||||
|
||||
public abstract class AbstractBean {
|
||||
|
||||
private final PropertyChangeSupport pcs;
|
||||
|
||||
|
||||
public AbstractBean() {
|
||||
// always notify on EDT
|
||||
pcs = new SwingPropertyChangeSupport(this, true);
|
||||
}
|
||||
|
||||
|
||||
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
|
||||
pcs.firePropertyChange(propertyName, oldValue, newValue);
|
||||
}
|
||||
|
||||
|
||||
protected void firePropertyChange(PropertyChangeEvent e) {
|
||||
pcs.firePropertyChange(e);
|
||||
}
|
||||
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
pcs.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
pcs.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
|
||||
public PropertyChangeListener[] getPropertyChangeListeners() {
|
||||
return pcs.getPropertyChangeListeners();
|
||||
}
|
||||
|
||||
}
|
@ -1,312 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
|
||||
public abstract class AbstractFancyListCellRenderer extends JPanel implements ListCellRenderer {
|
||||
|
||||
private Color gradientBeginColor;
|
||||
private Color gradientEndColor;
|
||||
|
||||
private Color highlightColor;
|
||||
|
||||
private boolean borderPainted = false;
|
||||
private boolean gradientPainted = false;
|
||||
|
||||
private GradientStyle gradientStyle = GradientStyle.TOP_TO_BOTTOM;
|
||||
private boolean highlightingEnabled = true;
|
||||
|
||||
private final Insets margin;
|
||||
|
||||
private static final Insets DEFAULT_PADDING = new Insets(7, 7, 7, 7);
|
||||
private static final Insets DEFAULT_MARGIN = new Insets(1, 1, 0, 1);
|
||||
|
||||
|
||||
public AbstractFancyListCellRenderer() {
|
||||
this(DEFAULT_PADDING, DEFAULT_MARGIN, null);
|
||||
}
|
||||
|
||||
|
||||
public AbstractFancyListCellRenderer(Insets padding) {
|
||||
this(padding, DEFAULT_MARGIN, null);
|
||||
}
|
||||
|
||||
|
||||
public AbstractFancyListCellRenderer(Insets padding, Insets margin) {
|
||||
this(padding, margin, null);
|
||||
}
|
||||
|
||||
|
||||
public AbstractFancyListCellRenderer(Insets padding, Insets margin, Color borderColor) {
|
||||
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
|
||||
|
||||
Border border = null;
|
||||
|
||||
if (padding != null)
|
||||
border = new EmptyBorder(padding);
|
||||
|
||||
if (borderColor != null)
|
||||
border = new CompoundBorder(new LineBorder(borderColor, 1), border);
|
||||
|
||||
if (margin != null) {
|
||||
this.margin = margin;
|
||||
border = new CompoundBorder(new EmptyBorder(margin), border);
|
||||
} else {
|
||||
this.margin = new Insets(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
setBorder(border);
|
||||
setOpaque(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void paintBorder(Graphics g) {
|
||||
if (borderPainted) {
|
||||
super.paintBorder(g);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
Rectangle2D shape = new Rectangle2D.Double(margin.left, margin.top, getWidth() - (margin.left + margin.right), getHeight() - (margin.top + margin.bottom));
|
||||
|
||||
if (isOpaque()) {
|
||||
g2d.setPaint(getBackground());
|
||||
g2d.fill(shape);
|
||||
}
|
||||
|
||||
if (highlightingEnabled && (highlightColor != null)) {
|
||||
g2d.setPaint(highlightColor);
|
||||
g2d.fill(shape);
|
||||
}
|
||||
|
||||
if (gradientPainted) {
|
||||
g2d.setPaint(gradientStyle.getGradientPaint(shape, gradientBeginColor, gradientEndColor));
|
||||
g2d.fill(shape);
|
||||
}
|
||||
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
configureListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
validate();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
protected void configureListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
setGradientPainted(isSelected);
|
||||
setBorderPainted(isSelected);
|
||||
|
||||
Color sc = list.getSelectionBackground();
|
||||
|
||||
if (isSelected) {
|
||||
setGradientColors(sc.brighter(), sc);
|
||||
}
|
||||
|
||||
if (highlightingEnabled && ((index % 2) == 0)) {
|
||||
setHighlightColor(new Color(sc.getRed(), sc.getGreen(), sc.getBlue(), 28));
|
||||
} else {
|
||||
setHighlightColor(null);
|
||||
}
|
||||
|
||||
if (isSelected) {
|
||||
setBackground(list.getSelectionBackground());
|
||||
setForeground(list.getSelectionForeground());
|
||||
} else {
|
||||
setBackground(list.getBackground());
|
||||
setForeground(list.getForeground());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setGradientColors(Color gradientBeginColor, Color gradientEndColor) {
|
||||
this.gradientBeginColor = gradientBeginColor;
|
||||
this.gradientEndColor = gradientEndColor;
|
||||
}
|
||||
|
||||
|
||||
public Color getGradientBeginColor() {
|
||||
return gradientBeginColor;
|
||||
}
|
||||
|
||||
|
||||
public Color getGradientEndColor() {
|
||||
return gradientEndColor;
|
||||
}
|
||||
|
||||
|
||||
public void setHighlightColor(Color highlightColor) {
|
||||
this.highlightColor = highlightColor;
|
||||
}
|
||||
|
||||
|
||||
public void setGradientStyle(GradientStyle gradientStyle) {
|
||||
this.gradientStyle = gradientStyle;
|
||||
}
|
||||
|
||||
|
||||
public void setHighlightingEnabled(boolean highlightingEnabled) {
|
||||
this.highlightingEnabled = highlightingEnabled;
|
||||
}
|
||||
|
||||
|
||||
public void setBorderPainted(boolean borderPainted) {
|
||||
this.borderPainted = borderPainted;
|
||||
}
|
||||
|
||||
|
||||
public void setGradientPainted(boolean gradientPainted) {
|
||||
this.gradientPainted = gradientPainted;
|
||||
}
|
||||
|
||||
|
||||
public Color getHighlightColor() {
|
||||
return highlightColor;
|
||||
}
|
||||
|
||||
|
||||
public boolean isBorderPainted() {
|
||||
return borderPainted;
|
||||
}
|
||||
|
||||
|
||||
public GradientStyle getGradientStyle() {
|
||||
return gradientStyle;
|
||||
}
|
||||
|
||||
|
||||
public boolean isHighlightingEnabled() {
|
||||
return highlightingEnabled;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
// validate children, yet avoid flickering of the mouse cursor
|
||||
synchronized (getTreeLock()) {
|
||||
validateTree();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void repaint() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void repaint(long tm, int x, int y, int width, int height) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void repaint(Rectangle r) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, char oldValue, char newValue) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, short oldValue, short newValue) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, int oldValue, int newValue) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, long oldValue, long newValue) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, float oldValue, float newValue) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, double oldValue, double newValue) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
|
||||
}
|
||||
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JSeparator;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
public class ActionPopup extends JPopupMenu {
|
||||
|
||||
protected final JLabel headerLabel = new JLabel();
|
||||
protected final JLabel descriptionLabel = new JLabel();
|
||||
protected final JLabel statusLabel = new JLabel();
|
||||
|
||||
protected final JPanel actionPanel = new JPanel(new MigLayout("nogrid, insets 0, fill"));
|
||||
|
||||
public ActionPopup(String label, Icon icon) {
|
||||
headerLabel.setText(label);
|
||||
headerLabel.setIcon(icon);
|
||||
headerLabel.setIconTextGap(5);
|
||||
|
||||
actionPanel.setOpaque(false);
|
||||
|
||||
statusLabel.setFont(statusLabel.getFont().deriveFont(10f));
|
||||
statusLabel.setForeground(Color.GRAY);
|
||||
|
||||
setLayout(new MigLayout("nogrid, fill, insets 0"));
|
||||
|
||||
add(headerLabel, "gapx 5px 5px, gapy 3px 1px, wrap 3px");
|
||||
add(new JSeparator(), "growx, wrap 1px");
|
||||
add(actionPanel, "growx, wrap 0px");
|
||||
add(new JSeparator(), "growx, wrap 0px");
|
||||
add(statusLabel, "growx, h 11px!, gapx 3px, wrap 1px");
|
||||
|
||||
// make it look better (e.g. window shadows) by forcing heavy-weight windows
|
||||
setLightWeightPopupEnabled(false);
|
||||
}
|
||||
|
||||
public void addDescription(JComponent component) {
|
||||
actionPanel.add(component, "gapx 4px, wrap 3px");
|
||||
}
|
||||
|
||||
public void addAction(JComponent component) {
|
||||
actionPanel.add(component, "gapx 12px 12px, growx, wrap");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSeparator() {
|
||||
actionPanel.add(new JSeparator(), "growx, wrap 1px");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JMenuItem add(Action a) {
|
||||
LinkButton link = new LinkButton(a);
|
||||
|
||||
// underline text
|
||||
link.setText(String.format("<html><nobr><u>%s</u></nobr></html>", link.getText()));
|
||||
|
||||
// use rollover color
|
||||
link.setRolloverEnabled(false);
|
||||
link.setColor(link.getRolloverColor());
|
||||
|
||||
// close popup when action is triggered
|
||||
link.addActionListener(closeListener);
|
||||
|
||||
addAction(link);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
actionPanel.removeAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLabel(String label) {
|
||||
headerLabel.setText(label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return headerLabel.getText();
|
||||
}
|
||||
|
||||
public void setStatus(String string) {
|
||||
statusLabel.setText(string);
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return statusLabel.getText();
|
||||
}
|
||||
|
||||
private final ActionListener closeListener = new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setVisible(false);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.RGBImageFilter;
|
||||
|
||||
|
||||
public class ColorTintImageFilter extends RGBImageFilter {
|
||||
|
||||
private Color color;
|
||||
private float intensity;
|
||||
|
||||
|
||||
public ColorTintImageFilter(Color color, float intensity) {
|
||||
this.color = color;
|
||||
this.intensity = intensity;
|
||||
|
||||
canFilterIndexColorModel = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int filterRGB(int x, int y, int rgb) {
|
||||
Color c = new Color(rgb, true);
|
||||
|
||||
int red = (int) ((c.getRed() * (1 - intensity)) + color.getRed() * intensity);
|
||||
int green = (int) ((c.getGreen() * (1 - intensity)) + color.getGreen() * intensity);
|
||||
int blue = (int) ((c.getBlue() * (1 - intensity)) + color.getBlue() * intensity);
|
||||
|
||||
return new Color(red, green, blue, c.getAlpha()).getRGB();
|
||||
}
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import static java.awt.BasicStroke.*;
|
||||
import static java.awt.RenderingHints.*;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.border.Border;
|
||||
|
||||
|
||||
public class DashedSeparator implements Border {
|
||||
|
||||
private final int height;
|
||||
private final int dash;
|
||||
|
||||
private final Color foreground;
|
||||
private final Color background;
|
||||
|
||||
|
||||
public DashedSeparator(int height, int dash, Color foreground, Color background) {
|
||||
this.height = height;
|
||||
this.dash = dash;
|
||||
this.foreground = foreground;
|
||||
this.background = background;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return new Insets(0, 0, height, 0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
|
||||
Graphics2D g2d = (Graphics2D) g.create(x, h - this.height, w, h);
|
||||
|
||||
// fill background
|
||||
g2d.setPaint(background);
|
||||
g2d.fillRect(0, 0, w, h);
|
||||
|
||||
// draw dashed line
|
||||
g2d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
|
||||
g2d.setColor(foreground);
|
||||
g2d.setStroke(new BasicStroke(1, CAP_ROUND, JOIN_ROUND, 1, new float[] { dash }, 0));
|
||||
|
||||
g2d.drawLine(dash, this.height / 2, w - dash, this.height / 2);
|
||||
|
||||
g2d.dispose();
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
|
||||
|
||||
public class DefaultFancyListCellRenderer extends AbstractFancyListCellRenderer {
|
||||
|
||||
private final JLabel label = new DefaultListCellRenderer();
|
||||
|
||||
|
||||
public DefaultFancyListCellRenderer() {
|
||||
add(label);
|
||||
}
|
||||
|
||||
|
||||
public DefaultFancyListCellRenderer(int padding) {
|
||||
super(new Insets(padding, padding, padding, padding));
|
||||
add(label);
|
||||
}
|
||||
|
||||
|
||||
public DefaultFancyListCellRenderer(Insets padding) {
|
||||
super(padding);
|
||||
add(label);
|
||||
}
|
||||
|
||||
|
||||
protected DefaultFancyListCellRenderer(int padding, int margin, Color selectedBorderColor) {
|
||||
super(new Insets(padding, padding, padding, padding), new Insets(margin, margin, margin, margin), selectedBorderColor);
|
||||
add(label);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void configureListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
super.configureListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
label.setOpaque(false);
|
||||
setText(String.valueOf(value));
|
||||
}
|
||||
|
||||
|
||||
public void setIcon(Icon icon) {
|
||||
label.setIcon(icon);
|
||||
}
|
||||
|
||||
|
||||
public void setText(String text) {
|
||||
label.setText(text);
|
||||
}
|
||||
|
||||
|
||||
public void setHorizontalTextPosition(int textPosition) {
|
||||
label.setHorizontalTextPosition(textPosition);
|
||||
}
|
||||
|
||||
|
||||
public void setVerticalTextPosition(int textPosition) {
|
||||
label.setVerticalTextPosition(textPosition);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setForeground(Color fg) {
|
||||
super.setForeground(fg);
|
||||
|
||||
// label is null while in super constructor
|
||||
if (label != null) {
|
||||
label.setForeground(fg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
|
||||
public class EmptySelectionModel implements ListSelectionModel {
|
||||
|
||||
@Override
|
||||
public void addListSelectionListener(ListSelectionListener x) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addSelectionInterval(int from, int to) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clearSelection() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getAnchorSelectionIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getLeadSelectionIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaxSelectionIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMinSelectionIndex() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getSelectionMode() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean getValueIsAdjusting() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void insertIndexInterval(int index, int length, boolean before) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSelectedIndex(int index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSelectionEmpty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeIndexInterval(int from, int to) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeListSelectionListener(ListSelectionListener listener) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeSelectionInterval(int from, int to) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setAnchorSelectionIndex(int index) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setLeadSelectionIndex(int index) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSelectionInterval(int from, int to) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSelectionMode(int selectionMode) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setValueIsAdjusting(boolean valueIsAdjusting) {
|
||||
}
|
||||
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
|
||||
|
||||
public class FancyTreeCellRenderer extends DefaultTreeCellRenderer {
|
||||
|
||||
private Color gradientBeginColor;
|
||||
private Color gradientEndColor;
|
||||
private GradientStyle gradientStyle;
|
||||
private boolean paintGradient;
|
||||
|
||||
private Color backgroundSelectionColor;
|
||||
|
||||
|
||||
public FancyTreeCellRenderer() {
|
||||
this(GradientStyle.TOP_TO_BOTTOM);
|
||||
}
|
||||
|
||||
|
||||
public FancyTreeCellRenderer(GradientStyle gradientStyle) {
|
||||
this.gradientStyle = gradientStyle;
|
||||
|
||||
backgroundSelectionColor = getBackgroundSelectionColor();
|
||||
|
||||
// disable default selection background
|
||||
setBackgroundSelectionColor(null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
||||
super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, false);
|
||||
|
||||
setIconTextGap(5);
|
||||
|
||||
if (selected) {
|
||||
setPaintGradient(true);
|
||||
setGradientBeginColor(backgroundSelectionColor.brighter());
|
||||
setGradientEndColor(backgroundSelectionColor);
|
||||
} else {
|
||||
setPaintGradient(false);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
if (isPaintGradient()) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
int imageOffset = getLabelStart() - 2;
|
||||
|
||||
int arch = 16;
|
||||
RoundRectangle2D shape = new RoundRectangle2D.Double(imageOffset, 1, getWidth() - imageOffset, getHeight() - 2, arch, arch);
|
||||
|
||||
g2d.setPaint(gradientStyle.getGradientPaint(shape, gradientBeginColor, gradientEndColor));
|
||||
g2d.fill(shape);
|
||||
}
|
||||
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
|
||||
protected int getLabelStart() {
|
||||
Icon icon = getIcon();
|
||||
|
||||
if ((icon != null) && (getText() != null)) {
|
||||
return icon.getIconWidth() + Math.max(0, getIconTextGap() - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public Color getGradientBeginColor() {
|
||||
return gradientBeginColor;
|
||||
}
|
||||
|
||||
|
||||
public void setGradientBeginColor(Color gradientBeginColor) {
|
||||
this.gradientBeginColor = gradientBeginColor;
|
||||
}
|
||||
|
||||
|
||||
public boolean isPaintGradient() {
|
||||
return paintGradient;
|
||||
}
|
||||
|
||||
|
||||
public void setPaintGradient(boolean gradientEnabled) {
|
||||
this.paintGradient = gradientEnabled;
|
||||
}
|
||||
|
||||
|
||||
public Color getGradientEndColor() {
|
||||
return gradientEndColor;
|
||||
}
|
||||
|
||||
|
||||
public void setGradientEndColor(Color gradientEndColor) {
|
||||
this.gradientEndColor = gradientEndColor;
|
||||
}
|
||||
|
||||
|
||||
public GradientStyle getGradientStyle() {
|
||||
return gradientStyle;
|
||||
}
|
||||
|
||||
|
||||
public void setGradientStyle(GradientStyle gradientStyle) {
|
||||
this.gradientStyle = gradientStyle;
|
||||
}
|
||||
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.LinearGradientPaint;
|
||||
import java.awt.MultipleGradientPaint.CycleMethod;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.RectangularShape;
|
||||
|
||||
|
||||
public enum GradientStyle {
|
||||
TOP_TO_BOTTOM,
|
||||
BOTTOM_TO_TOP,
|
||||
LEFT_TO_RIGHT,
|
||||
RIGHT_TO_LEFT,
|
||||
TOP_LEFT_TO_BOTTOM_RIGHT,
|
||||
BOTTOM_RIGHT_TO_TOP_LEFT,
|
||||
TOP_RIGHT_TO_BOTTOM_LEFT,
|
||||
BOTTOM_LEFT_TO_TOP_RIGHT;
|
||||
|
||||
public LinearGradientPaint getGradientPaint(RectangularShape shape, Color gradientBeginColor, Color gradientEndColor) {
|
||||
Point2D start = null;
|
||||
Point2D end = null;
|
||||
|
||||
switch (this) {
|
||||
case BOTTOM_TO_TOP:
|
||||
start = new Point2D.Double(shape.getCenterX(), shape.getMaxY());
|
||||
end = new Point2D.Double(shape.getCenterX(), shape.getMinY());
|
||||
break;
|
||||
|
||||
case TOP_TO_BOTTOM:
|
||||
end = new Point2D.Double(shape.getCenterX(), shape.getMaxY());
|
||||
start = new Point2D.Double(shape.getCenterX(), shape.getMinY());
|
||||
break;
|
||||
|
||||
case LEFT_TO_RIGHT:
|
||||
start = new Point2D.Double(shape.getMinX(), shape.getCenterY());
|
||||
end = new Point2D.Double(shape.getMaxX(), shape.getCenterY());
|
||||
break;
|
||||
|
||||
case RIGHT_TO_LEFT:
|
||||
end = new Point2D.Double(shape.getMinX(), shape.getCenterY());
|
||||
start = new Point2D.Double(shape.getMaxX(), shape.getCenterY());
|
||||
break;
|
||||
|
||||
case TOP_LEFT_TO_BOTTOM_RIGHT:
|
||||
start = new Point2D.Double(shape.getMinX(), shape.getMinY());
|
||||
end = new Point2D.Double(shape.getMaxX(), shape.getMaxY());
|
||||
break;
|
||||
|
||||
case BOTTOM_RIGHT_TO_TOP_LEFT:
|
||||
end = new Point2D.Double(shape.getMinX(), shape.getMinY());
|
||||
start = new Point2D.Double(shape.getMaxX(), shape.getMaxY());
|
||||
break;
|
||||
|
||||
case TOP_RIGHT_TO_BOTTOM_LEFT:
|
||||
start = new Point2D.Double(shape.getMaxX(), shape.getMinY());
|
||||
end = new Point2D.Double(shape.getMinX(), shape.getMaxY());
|
||||
break;
|
||||
|
||||
case BOTTOM_LEFT_TO_TOP_RIGHT:
|
||||
end = new Point2D.Double(shape.getMaxX(), shape.getMinY());
|
||||
start = new Point2D.Double(shape.getMinX(), shape.getMaxY());
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
Color[] colors = { gradientBeginColor, gradientEndColor };
|
||||
float[] fractions = { 0.0f, 1.0f };
|
||||
return new LinearGradientPaint(start, end, fractions, colors, CycleMethod.NO_CYCLE);
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
|
||||
public interface LabelProvider<T> {
|
||||
|
||||
public String getText(T value);
|
||||
|
||||
|
||||
public Icon getIcon(T value);
|
||||
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
|
||||
public abstract class LazyDocumentListener implements DocumentListener {
|
||||
|
||||
private DocumentEvent lastEvent;
|
||||
|
||||
private Timer timer;
|
||||
|
||||
|
||||
public LazyDocumentListener() {
|
||||
this(200);
|
||||
}
|
||||
|
||||
|
||||
public LazyDocumentListener(int delay) {
|
||||
if (delay >= 0) {
|
||||
timer = new Timer(delay, new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
update(lastEvent);
|
||||
|
||||
// we don't need it anymore
|
||||
lastEvent = null;
|
||||
}
|
||||
});
|
||||
|
||||
timer.setRepeats(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void defer(DocumentEvent e) {
|
||||
lastEvent = e;
|
||||
|
||||
if (timer != null) {
|
||||
// defer update
|
||||
timer.restart();
|
||||
} else {
|
||||
// update immediately
|
||||
update(lastEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
defer(e);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
defer(e);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
defer(e);
|
||||
}
|
||||
|
||||
|
||||
public abstract void update(DocumentEvent e);
|
||||
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.net.URI;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
|
||||
|
||||
public class LinkButton extends JButton {
|
||||
|
||||
private Color color = getForeground();
|
||||
private Color rolloverColor = new Color(0x3399FF);
|
||||
|
||||
|
||||
public LinkButton(String text, Icon icon, URI uri) {
|
||||
this(new OpenUriAction(text, icon, uri));
|
||||
}
|
||||
|
||||
|
||||
public LinkButton(Action action) {
|
||||
setAction(action);
|
||||
|
||||
setFocusPainted(false);
|
||||
setOpaque(false);
|
||||
setContentAreaFilled(false);
|
||||
setBorder(null);
|
||||
|
||||
setHorizontalAlignment(LEFT);
|
||||
setIconTextGap(6);
|
||||
setRolloverEnabled(true);
|
||||
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setRolloverEnabled(boolean enabled) {
|
||||
super.setRolloverEnabled(enabled);
|
||||
|
||||
// always remove listener if there is one
|
||||
removeMouseListener(rolloverListener);
|
||||
|
||||
if (enabled) {
|
||||
// add listener again, if enabled
|
||||
addMouseListener(rolloverListener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
this.setForeground(color);
|
||||
}
|
||||
|
||||
|
||||
public Color getRolloverColor() {
|
||||
return rolloverColor;
|
||||
}
|
||||
|
||||
|
||||
public void setRolloverColor(Color rolloverColor) {
|
||||
this.rolloverColor = rolloverColor;
|
||||
}
|
||||
|
||||
protected final MouseListener rolloverListener = new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
setForeground(rolloverColor);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
setForeground(color);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
protected static class OpenUriAction extends AbstractAction {
|
||||
|
||||
public static final String URI = "uri";
|
||||
|
||||
|
||||
public OpenUriAction(String text, Icon icon, URI uri) {
|
||||
super(text, icon);
|
||||
putValue(URI, uri);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
try {
|
||||
URI uri = (URI) getValue(URI);
|
||||
|
||||
if (uri != null) {
|
||||
Desktop.getDesktop().browse(uri);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// should not happen
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import static java.lang.Math.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.FilteredImageSource;
|
||||
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.DropMode;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.MouseInputAdapter;
|
||||
|
||||
|
||||
public class ListView extends JList {
|
||||
|
||||
protected final BlockSelectionHandler blockSelectionHandler = new BlockSelectionHandler();
|
||||
|
||||
|
||||
public ListView(ListModel dataModel) {
|
||||
super(dataModel);
|
||||
setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
|
||||
// better selection behaviour
|
||||
putClientProperty("List.isFileList", Boolean.TRUE);
|
||||
setDropMode(DropMode.ON);
|
||||
|
||||
setLayoutOrientation(JList.VERTICAL_WRAP);
|
||||
setVisibleRowCount(-1);
|
||||
setCellRenderer(new ListViewRenderer());
|
||||
|
||||
addMouseListener(blockSelectionHandler);
|
||||
addMouseMotionListener(blockSelectionHandler);
|
||||
}
|
||||
|
||||
|
||||
public void addSelectionInterval(Rectangle selection) {
|
||||
Point p1 = selection.getLocation();
|
||||
Point p2 = new Point(p1.x + selection.width, p1.y + selection.height);
|
||||
|
||||
int startIndex = locationToIndex(p1);
|
||||
int endIndex = locationToIndex(p2);
|
||||
|
||||
for (int i = startIndex; i <= endIndex; i++) {
|
||||
Rectangle cell = getCellBounds(i, i);
|
||||
|
||||
if (cell != null && selection.intersects(cell)) {
|
||||
addSelectionInterval(i, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
Rectangle selection = blockSelectionHandler.getSelection();
|
||||
|
||||
// paint block selection
|
||||
if (selection != null) {
|
||||
paintBlockSelection((Graphics2D) g, selection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void paintBlockSelection(Graphics2D g2d, Rectangle selection) {
|
||||
g2d.setPaint(TunedUtilities.derive(getSelectionBackground(), 0.3f));
|
||||
g2d.fill(selection);
|
||||
|
||||
g2d.setPaint(getSelectionBackground());
|
||||
g2d.draw(selection);
|
||||
}
|
||||
|
||||
|
||||
protected String convertValueToText(Object value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
|
||||
protected Icon convertValueToIcon(Object value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected class ListViewRenderer extends DefaultListCellRenderer {
|
||||
|
||||
public ListViewRenderer() {
|
||||
setOpaque(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
Icon icon = convertValueToIcon(value);
|
||||
|
||||
if (isSelected && icon != null) {
|
||||
// apply selection color tint
|
||||
icon = new ImageIcon(createImage(new FilteredImageSource(TunedUtilities.getImage(icon).getSource(), new ColorTintImageFilter(list.getSelectionBackground(), 0.5f))));
|
||||
}
|
||||
|
||||
setText(convertValueToText(value));
|
||||
setIcon(icon);
|
||||
|
||||
if (isSelected) {
|
||||
setBackground(list.getSelectionBackground());
|
||||
setForeground(list.getSelectionForeground());
|
||||
} else {
|
||||
setBackground(list.getBackground());
|
||||
setForeground(list.getForeground());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
// paint selection background for the text area only, not the whole cell
|
||||
int iconWidth = (getIcon() == null ? 0 : getIcon().getIconHeight());
|
||||
int startX = iconWidth + getIconTextGap();
|
||||
Rectangle2D text = getFontMetrics(getFont()).getStringBounds(getText(), g);
|
||||
|
||||
g.setColor(getBackground());
|
||||
g.fillRect(startX - 2, 1, (int) (text.getWidth() + 6), getHeight() - 1);
|
||||
|
||||
super.paintComponent(g);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
protected class BlockSelectionHandler extends MouseInputAdapter {
|
||||
|
||||
private Rectangle selection;
|
||||
|
||||
private Point origin;
|
||||
|
||||
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (SwingUtilities.isLeftMouseButton(e) && !isSelectedIndex(locationToIndex(e.getPoint()))) {
|
||||
origin = e.getPoint();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if (origin == null)
|
||||
return;
|
||||
|
||||
// begin selection
|
||||
if (selection == null)
|
||||
selection = new Rectangle();
|
||||
|
||||
// keep point within component bounds
|
||||
Point p2 = e.getPoint();
|
||||
p2.x = max(0, min(getWidth() - 1, p2.x));
|
||||
p2.y = max(0, min(getHeight() - 1, p2.y));
|
||||
|
||||
// update selection bounds
|
||||
selection.setFrameFromDiagonal(origin, p2);
|
||||
|
||||
// auto-scroll
|
||||
ensureIndexIsVisible(locationToIndex(p2));
|
||||
|
||||
// update list selection
|
||||
clearSelection();
|
||||
addSelectionInterval(selection);
|
||||
|
||||
// update view
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
origin = null;
|
||||
|
||||
// end selection
|
||||
selection = null;
|
||||
|
||||
// update view
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
public Rectangle getSelection() {
|
||||
return selection;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
|
||||
public class LoadingOverlayPane extends JComponent {
|
||||
|
||||
public static final String LOADING_PROPERTY = "loading";
|
||||
|
||||
private final JComponent animationComponent;
|
||||
|
||||
private boolean overlayEnabled = false;
|
||||
|
||||
private int millisToOverlay = 400;
|
||||
|
||||
|
||||
public LoadingOverlayPane(JComponent component, JComponent propertyChangeSource) {
|
||||
this(component, propertyChangeSource, null, null);
|
||||
}
|
||||
|
||||
|
||||
public LoadingOverlayPane(JComponent component, JComponent propertyChangeSource, String offsetX, String offsetY) {
|
||||
setLayout(new MigLayout("insets 0, fill"));
|
||||
|
||||
animationComponent = new ProgressIndicator();
|
||||
animationComponent.setVisible(false);
|
||||
|
||||
add(animationComponent, String.format("pos n %s 100%%-%s n", offsetY != null ? offsetY : "8px", offsetX != null ? offsetX : "20px"));
|
||||
add(component, "grow");
|
||||
|
||||
if (propertyChangeSource != null) {
|
||||
propertyChangeSource.addPropertyChangeListener(LOADING_PROPERTY, new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
setOverlayVisible((Boolean) evt.getNewValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isOptimizedDrawingEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void setOverlayVisible(boolean b) {
|
||||
overlayEnabled = b;
|
||||
|
||||
if (overlayEnabled) {
|
||||
TunedUtilities.invokeLater(millisToOverlay, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (overlayEnabled) {
|
||||
animationComponent.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
animationComponent.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
|
||||
public class NullLabelProvider<T extends Object> implements LabelProvider<T> {
|
||||
|
||||
@Override
|
||||
public Icon getIcon(T value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getText(T value) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
|
||||
public class ProgressDialog extends JDialog {
|
||||
|
||||
private final JProgressBar progressBar = new JProgressBar(0, 100);
|
||||
private final JLabel iconLabel = new JLabel();
|
||||
private final JLabel headerLabel = new JLabel();
|
||||
|
||||
private final Cancellable cancellable;
|
||||
|
||||
|
||||
public ProgressDialog(Window owner, Cancellable cancellable) {
|
||||
super(owner, ModalityType.DOCUMENT_MODAL);
|
||||
|
||||
this.cancellable = cancellable;
|
||||
|
||||
// disable window close button
|
||||
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||
|
||||
headerLabel.setFont(headerLabel.getFont().deriveFont(18f));
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setStringPainted(true);
|
||||
JPanel c = (JPanel) getContentPane();
|
||||
c.setLayout(new MigLayout("insets dialog, nogrid, fill"));
|
||||
|
||||
c.add(iconLabel, "h pref!, w pref!");
|
||||
c.add(headerLabel, "gap 3mm, wrap paragraph");
|
||||
c.add(progressBar, "hmin 25px, grow, wrap paragraph");
|
||||
|
||||
c.add(new JButton(cancelAction), "align center");
|
||||
|
||||
setSize(240, 155);
|
||||
}
|
||||
|
||||
|
||||
public void setIcon(Icon icon) {
|
||||
iconLabel.setIcon(icon);
|
||||
}
|
||||
|
||||
|
||||
public void setIndeterminate(boolean b) {
|
||||
progressBar.setIndeterminate(b);
|
||||
}
|
||||
|
||||
|
||||
public void setProgress(int value, int max) {
|
||||
progressBar.setIndeterminate(false);
|
||||
progressBar.setMinimum(0);
|
||||
progressBar.setValue(value);
|
||||
progressBar.setMaximum(max);
|
||||
}
|
||||
|
||||
|
||||
public void setNote(String text) {
|
||||
progressBar.setString(text);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setTitle(String text) {
|
||||
super.setTitle(text);
|
||||
headerLabel.setText(text);
|
||||
}
|
||||
|
||||
|
||||
public void setWindowTitle(String text) {
|
||||
super.setTitle(text);
|
||||
}
|
||||
|
||||
|
||||
public void close() {
|
||||
setVisible(false);
|
||||
dispose();
|
||||
}
|
||||
|
||||
|
||||
protected final Action cancelAction = new AbstractAction("Cancel") {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
cancelAction.setEnabled(false);
|
||||
cancellable.cancel();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static interface Cancellable {
|
||||
|
||||
boolean isCancelled();
|
||||
|
||||
|
||||
boolean cancel();
|
||||
}
|
||||
|
||||
}
|
@ -1,157 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.Timer;
|
||||
|
||||
|
||||
public class ProgressIndicator extends JComponent {
|
||||
|
||||
private float radius = 4.0f;
|
||||
private int shapeCount = 3;
|
||||
|
||||
private float strokeWidth = 2f;
|
||||
private Stroke stroke = new BasicStroke(strokeWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
|
||||
|
||||
private Color progressShapeColor = Color.orange;
|
||||
private Color backgroundShapeColor = new Color(0f, 0f, 0f, 0.25f);
|
||||
|
||||
private final Rectangle2D frame = new Rectangle2D.Double();
|
||||
private final Ellipse2D circle = new Ellipse2D.Double();
|
||||
private final Dimension baseSize = new Dimension(32, 32);
|
||||
|
||||
private double alpha = 0;
|
||||
private double speed = 24;
|
||||
|
||||
private Timer updateTimer;
|
||||
|
||||
|
||||
public ProgressIndicator() {
|
||||
setPreferredSize(baseSize);
|
||||
|
||||
addComponentListener(new ComponentAdapter() {
|
||||
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {
|
||||
startAnimation();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
stopAnimation();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void animateOnce() {
|
||||
if ((alpha += (speed / 1000)) >= 1) {
|
||||
alpha -= Math.floor(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
double a = Math.min(getWidth(), getHeight());
|
||||
|
||||
g2d.scale(a / baseSize.width, a / baseSize.height);
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
frame.setFrame(radius, radius, baseSize.width - radius * 2 - 1, baseSize.height - radius * 2 - 1);
|
||||
|
||||
paintShapes(g2d);
|
||||
}
|
||||
|
||||
|
||||
private void paintShapes(Graphics2D g2d) {
|
||||
circle.setFrame(frame);
|
||||
|
||||
g2d.setStroke(stroke);
|
||||
g2d.setPaint(backgroundShapeColor);
|
||||
|
||||
g2d.draw(circle);
|
||||
|
||||
Point2D center = new Point2D.Double(frame.getCenterX(), frame.getMinY());
|
||||
|
||||
circle.setFrameFromCenter(center, new Point2D.Double(center.getX() + radius, center.getY() + radius));
|
||||
|
||||
g2d.setStroke(stroke);
|
||||
g2d.setPaint(progressShapeColor);
|
||||
|
||||
// base rotation
|
||||
g2d.rotate(getTheta(alpha, 1.0), frame.getCenterX(), frame.getCenterY());
|
||||
|
||||
double theta = getTheta(1, shapeCount);
|
||||
|
||||
for (int i = 0; i < shapeCount; i++) {
|
||||
g2d.rotate(theta, frame.getCenterX(), frame.getCenterY());
|
||||
g2d.fill(circle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private double getTheta(double value, double max) {
|
||||
return (value / max) * 2 * Math.PI;
|
||||
}
|
||||
|
||||
|
||||
public void startAnimation() {
|
||||
if (updateTimer == null) {
|
||||
updateTimer = new Timer(20, new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
animateOnce();
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
|
||||
updateTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stopAnimation() {
|
||||
if (updateTimer != null) {
|
||||
updateTimer.stop();
|
||||
updateTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setShapeCount(int indeterminateShapeCount) {
|
||||
this.shapeCount = indeterminateShapeCount;
|
||||
}
|
||||
|
||||
|
||||
public void setSpeed(double speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
|
||||
public double getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
import javax.swing.border.AbstractBorder;
|
||||
|
||||
|
||||
public class RoundBorder extends AbstractBorder {
|
||||
|
||||
private final Color color;
|
||||
private final Insets insets;
|
||||
private final int arc;
|
||||
|
||||
|
||||
public RoundBorder() {
|
||||
this.color = new Color(0xACACAC);
|
||||
this.arc = 12;
|
||||
this.insets = new Insets(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
public RoundBorder(Color color, int arc, Insets insets) {
|
||||
this.color = color;
|
||||
this.arc = arc;
|
||||
this.insets = insets;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
Graphics2D g2d = (Graphics2D) g.create();
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
g2d.setPaint(c.getBackground());
|
||||
g2d.fillRoundRect(x, y, width - 1, height - 1, arc, arc);
|
||||
|
||||
g2d.setPaint(color);
|
||||
g2d.drawRoundRect(x, y, width - 1, height - 1, arc, arc);
|
||||
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return new Insets(insets.top, insets.left, insets.bottom, insets.right);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
insets.top = this.insets.top;
|
||||
insets.left = this.insets.left;
|
||||
insets.bottom = this.insets.bottom;
|
||||
insets.right = this.insets.right;
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.DefaultSingleSelectionModel;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.SingleSelectionModel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
public class SelectButton<T> extends JButton {
|
||||
|
||||
public static final String SELECTED_VALUE = "selected value";
|
||||
|
||||
private final Color beginColor = new Color(0xF0EEE4);
|
||||
private final Color endColor = new Color(0xE0DED4);
|
||||
|
||||
private final Color beginColorHover = beginColor;
|
||||
private final Color endColorHover = new Color(0xD8D7CD);
|
||||
|
||||
private final SelectIcon selectIcon = new SelectIcon();
|
||||
|
||||
private List<T> model = Collections.emptyList();
|
||||
private SingleSelectionModel selectionModel = new DefaultSingleSelectionModel();
|
||||
|
||||
private LabelProvider<T> labelProvider = new NullLabelProvider<T>();
|
||||
|
||||
private boolean hover = false;
|
||||
|
||||
public SelectButton() {
|
||||
setContentAreaFilled(false);
|
||||
setFocusable(false);
|
||||
|
||||
super.setIcon(selectIcon);
|
||||
|
||||
setHorizontalAlignment(SwingConstants.CENTER);
|
||||
setVerticalAlignment(SwingConstants.CENTER);
|
||||
|
||||
setBorder(BorderFactory.createLineBorder(new Color(0xA4A4A4), 1));
|
||||
setPreferredSize(new Dimension(32, 22));
|
||||
|
||||
addActionListener(new OpenPopupOnClick());
|
||||
}
|
||||
|
||||
public void setModel(Collection<T> model) {
|
||||
this.model = new ArrayList<T>(model);
|
||||
setSelectedIndex(0);
|
||||
}
|
||||
|
||||
public LabelProvider<T> getLabelProvider() {
|
||||
return labelProvider;
|
||||
}
|
||||
|
||||
public void setLabelProvider(LabelProvider<T> labelProvider) {
|
||||
this.labelProvider = labelProvider;
|
||||
|
||||
// update icon
|
||||
this.setIcon(labelProvider.getIcon(getSelectedValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIcon(Icon icon) {
|
||||
selectIcon.setInnerIcon(icon);
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void setSelectedValue(T value) {
|
||||
setSelectedIndex(model.indexOf(value));
|
||||
}
|
||||
|
||||
public T getSelectedValue() {
|
||||
if (!selectionModel.isSelected())
|
||||
return null;
|
||||
|
||||
return model.get(selectionModel.getSelectedIndex());
|
||||
}
|
||||
|
||||
public void setSelectedIndex(int i) {
|
||||
if (i < 0 || i >= model.size()) {
|
||||
selectionModel.clearSelection();
|
||||
setIcon(null);
|
||||
return;
|
||||
}
|
||||
|
||||
selectionModel.setSelectedIndex(i);
|
||||
T value = model.get(i);
|
||||
setIcon(labelProvider.getIcon(value));
|
||||
firePropertyChange(SELECTED_VALUE, null, value);
|
||||
}
|
||||
|
||||
public int getSelectedIndex() {
|
||||
return selectionModel.getSelectedIndex();
|
||||
}
|
||||
|
||||
public SingleSelectionModel getSelectionModel() {
|
||||
return selectionModel;
|
||||
}
|
||||
|
||||
public void spinValue(int spin) {
|
||||
int size = model.size();
|
||||
|
||||
spin = spin % size;
|
||||
|
||||
int next = getSelectedIndex() + spin;
|
||||
|
||||
if (next < 0)
|
||||
next += size;
|
||||
else if (next >= size)
|
||||
next -= size;
|
||||
|
||||
setSelectedIndex(next);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
Rectangle bounds = new Rectangle(getSize());
|
||||
|
||||
if (hover)
|
||||
g2d.setPaint(GradientStyle.TOP_TO_BOTTOM.getGradientPaint(bounds, beginColorHover, endColorHover));
|
||||
else
|
||||
g2d.setPaint(GradientStyle.TOP_TO_BOTTOM.getGradientPaint(bounds, beginColor, endColor));
|
||||
|
||||
g2d.fill(bounds);
|
||||
|
||||
super.paintComponent(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processMouseEvent(MouseEvent e) {
|
||||
switch (e.getID()) {
|
||||
case MouseEvent.MOUSE_ENTERED:
|
||||
hover = true;
|
||||
repaint();
|
||||
break;
|
||||
case MouseEvent.MOUSE_EXITED:
|
||||
hover = false;
|
||||
repaint();
|
||||
break;
|
||||
}
|
||||
|
||||
super.processMouseEvent(e);
|
||||
}
|
||||
|
||||
private class OpenPopupOnClick implements ActionListener {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JPopupMenu popup = new JPopupMenu();
|
||||
|
||||
for (T value : model) {
|
||||
SelectPopupMenuItem item = new SelectPopupMenuItem(labelProvider.getText(value), labelProvider.getIcon(value), value);
|
||||
|
||||
if (value == getSelectedValue())
|
||||
item.setSelected(true);
|
||||
|
||||
popup.add(item);
|
||||
}
|
||||
|
||||
popup.show(SelectButton.this, 0, getHeight() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
private class SelectPopupMenuItem extends JMenuItem implements ActionListener {
|
||||
|
||||
private final T value;
|
||||
|
||||
public SelectPopupMenuItem(String text, Icon icon, T value) {
|
||||
super(text, icon);
|
||||
|
||||
this.value = value;
|
||||
|
||||
setMargin(new Insets(3, 0, 3, 0));
|
||||
addActionListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(boolean selected) {
|
||||
setFont(getFont().deriveFont(selected ? Font.BOLD : Font.PLAIN));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setSelectedValue(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class SelectIcon implements Icon {
|
||||
|
||||
private final GeneralPath arrow;
|
||||
|
||||
private Icon icon;
|
||||
|
||||
public SelectIcon() {
|
||||
arrow = new GeneralPath(Path2D.WIND_EVEN_ODD, 3);
|
||||
int x = 25;
|
||||
int y = 10;
|
||||
|
||||
arrow.moveTo(x - 2, y);
|
||||
arrow.lineTo(x, y + 3);
|
||||
arrow.lineTo(x + 3, y);
|
||||
arrow.lineTo(x - 2, y);
|
||||
}
|
||||
|
||||
public void setInnerIcon(Icon icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
if (icon != null) {
|
||||
icon.paintIcon(c, g2d, 4, 3);
|
||||
}
|
||||
|
||||
g2d.setPaint(Color.BLACK);
|
||||
g2d.fill(arrow);
|
||||
}
|
||||
|
||||
public int getIconWidth() {
|
||||
return 30;
|
||||
}
|
||||
|
||||
public int getIconHeight() {
|
||||
return 20;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.RadialGradientPaint;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RectangularShape;
|
||||
|
||||
import javax.swing.border.AbstractBorder;
|
||||
|
||||
|
||||
public class ShadowBorder extends AbstractBorder {
|
||||
|
||||
private int smoothness;
|
||||
|
||||
private int smoothnessOffset;
|
||||
|
||||
private int offset;
|
||||
|
||||
|
||||
public ShadowBorder() {
|
||||
this(2, 2, 12);
|
||||
}
|
||||
|
||||
|
||||
public ShadowBorder(int offset, int smoothness, int smoothnessOffset) {
|
||||
this.offset = offset;
|
||||
this.smoothness = smoothness;
|
||||
this.smoothnessOffset = smoothnessOffset;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
Color bg = new Color(0, 0, 0, 81);
|
||||
Color faded = new Color(0, 0, 0, 0);
|
||||
|
||||
int a = smoothness + smoothnessOffset;
|
||||
|
||||
Rectangle2D main = new Rectangle2D.Double(a, a, width - a * 2, height - a * 2);
|
||||
|
||||
g2d.setPaint(bg);
|
||||
g2d.fill(main);
|
||||
|
||||
Rectangle2D right = new Rectangle2D.Double(main.getMaxX(), a, a, main.getHeight());
|
||||
Rectangle2D left = new Rectangle2D.Double(0, a, a, main.getHeight());
|
||||
Rectangle2D top = new Rectangle2D.Double(a, 0, main.getWidth(), a);
|
||||
Rectangle2D bottom = new Rectangle2D.Double(a, main.getMaxY(), main.getWidth(), a);
|
||||
|
||||
g2d.setPaint(GradientStyle.LEFT_TO_RIGHT.getGradientPaint(right, bg, faded));
|
||||
g2d.fill(right);
|
||||
|
||||
g2d.setPaint(GradientStyle.RIGHT_TO_LEFT.getGradientPaint(left, bg, faded));
|
||||
g2d.fill(left);
|
||||
|
||||
g2d.setPaint(GradientStyle.BOTTOM_TO_TOP.getGradientPaint(top, bg, faded));
|
||||
g2d.fill(top);
|
||||
|
||||
g2d.setPaint(GradientStyle.TOP_TO_BOTTOM.getGradientPaint(bottom, bg, faded));
|
||||
g2d.fill(bottom);
|
||||
|
||||
Rectangle2D topLeftCorner = new Rectangle2D.Double(0, 0, a, a);
|
||||
Rectangle2D topRightCorner = new Rectangle2D.Double(width - a, 0, a, a);
|
||||
Rectangle2D bottomLeftCorner = new Rectangle2D.Double(0, height - a, a, a);
|
||||
Rectangle2D bottomRightCorner = new Rectangle2D.Double(width - a, height - a, a, a);
|
||||
|
||||
g2d.setPaint(CornerGradientStyle.TOP_LEFT.getGradientPaint(topLeftCorner, a, bg, faded));
|
||||
g2d.fill(topLeftCorner);
|
||||
|
||||
g2d.setPaint(CornerGradientStyle.TOP_RIGHT.getGradientPaint(topRightCorner, a, bg, faded));
|
||||
g2d.fill(topRightCorner);
|
||||
|
||||
g2d.setPaint(CornerGradientStyle.BOTTOM_LEFT.getGradientPaint(bottomLeftCorner, a, bg, faded));
|
||||
g2d.fill(bottomLeftCorner);
|
||||
|
||||
g2d.setPaint(CornerGradientStyle.BOTTOM_RIGHT.getGradientPaint(bottomRightCorner, a, bg, faded));
|
||||
g2d.fill(bottomRightCorner);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return getBorderInsets(c, new Insets(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
insets.top = insets.left = Math.max(smoothness - offset, 4);
|
||||
insets.bottom = insets.right = Math.max(smoothness + offset, 4);
|
||||
return insets;
|
||||
}
|
||||
|
||||
|
||||
private static enum CornerGradientStyle {
|
||||
TOP_LEFT,
|
||||
TOP_RIGHT,
|
||||
BOTTOM_LEFT,
|
||||
BOTTOM_RIGHT;
|
||||
|
||||
public RadialGradientPaint getGradientPaint(RectangularShape shape, float radius, Color gradientBeginColor, Color gradientEndColor) {
|
||||
Point2D center = null;
|
||||
|
||||
switch (this) {
|
||||
case TOP_LEFT:
|
||||
center = new Point2D.Double(shape.getX() + radius, shape.getY() + radius);
|
||||
break;
|
||||
|
||||
case TOP_RIGHT:
|
||||
center = new Point2D.Double(shape.getX() + 0, shape.getY() + radius);
|
||||
break;
|
||||
|
||||
case BOTTOM_LEFT:
|
||||
center = new Point2D.Double(shape.getX() + radius, shape.getY() + 0);
|
||||
break;
|
||||
|
||||
case BOTTOM_RIGHT:
|
||||
center = new Point2D.Double(shape.getX() + 0, shape.getY() + 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
float[] dist = { 0.0f, 1.0f };
|
||||
Color[] colors = { gradientBeginColor, gradientEndColor };
|
||||
|
||||
return new RadialGradientPaint(center, radius, dist, colors);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import net.sourceforge.tuned.ExceptionUtilities;
|
||||
|
||||
|
||||
/**
|
||||
* <code>LabelProvider</code> based on reflection.
|
||||
*/
|
||||
public class SimpleLabelProvider<T> implements LabelProvider<T> {
|
||||
|
||||
private final Method getIconMethod;
|
||||
private final Method getTextMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Factory method for {@link #SimpleLabelProvider(Class)}.
|
||||
*
|
||||
* @return new <code>LabelProvider</code>
|
||||
*/
|
||||
public static <T> SimpleLabelProvider<T> forClass(Class<T> type) {
|
||||
return new SimpleLabelProvider<T>(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new LabelProvider which will use the <code>getText</code>, <code>getName</code> or <code>toString</code>
|
||||
* method for text and the <code>getIcon</code> method for the
|
||||
* icon.
|
||||
*
|
||||
* @param type a class that has one of the text methods and the icon method
|
||||
*/
|
||||
public SimpleLabelProvider(Class<T> type) {
|
||||
getTextMethod = findAnyMethod(type, "getText", "getName", "toString");
|
||||
getIconMethod = findAnyMethod(type, "getIcon");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new LabelProvider which will use a specified method of a given class
|
||||
*
|
||||
* @param type a class with the specified method
|
||||
* @param getText a method name such as <code>getText</code>
|
||||
* @param getIcon a method name such as <code>getIcon</code>
|
||||
*/
|
||||
public SimpleLabelProvider(Class<T> type, String getText, String getIcon) {
|
||||
getTextMethod = findAnyMethod(type, getText);
|
||||
getIconMethod = findAnyMethod(type, getIcon);
|
||||
}
|
||||
|
||||
|
||||
private Method findAnyMethod(Class<T> type, String... names) {
|
||||
for (String name : names) {
|
||||
try {
|
||||
return type.getMethod(name);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// try next method name
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Method not found: " + Arrays.toString(names));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getText(T value) {
|
||||
try {
|
||||
return (String) getTextMethod.invoke(value);
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtilities.asRuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Icon getIcon(T value) {
|
||||
try {
|
||||
return (Icon) getIconMethod.invoke(value);
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtilities.asRuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.swing.SwingWorker.StateValue;
|
||||
|
||||
|
||||
public abstract class SwingWorkerPropertyChangeAdapter implements PropertyChangeListener {
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getPropertyName().equals("progress")) {
|
||||
progress(evt);
|
||||
} else if (evt.getPropertyName().equals("state")) {
|
||||
state(evt);
|
||||
} else {
|
||||
event(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void state(PropertyChangeEvent evt) {
|
||||
switch ((StateValue) evt.getNewValue()) {
|
||||
case STARTED:
|
||||
started(evt);
|
||||
break;
|
||||
case DONE:
|
||||
done(evt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void progress(PropertyChangeEvent evt) {
|
||||
}
|
||||
|
||||
|
||||
protected void started(PropertyChangeEvent evt) {
|
||||
}
|
||||
|
||||
|
||||
protected void done(PropertyChangeEvent evt) {
|
||||
}
|
||||
|
||||
|
||||
protected void event(String name, Object oldValue, Object newValue) {
|
||||
}
|
||||
|
||||
}
|
@ -1,280 +0,0 @@
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
import static javax.swing.JOptionPane.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.awt.Window;
|
||||
import java.awt.dnd.DnDConstants;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.event.MouseInputListener;
|
||||
import javax.swing.plaf.basic.BasicTableUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.undo.UndoManager;
|
||||
|
||||
public final class TunedUtilities {
|
||||
|
||||
public static final Color TRANSLUCENT = new Color(255, 255, 255, 0);
|
||||
|
||||
public static void checkEventDispatchThread() {
|
||||
if (!SwingUtilities.isEventDispatchThread()) {
|
||||
throw new IllegalStateException("Method must be accessed from the Swing Event Dispatch Thread, but was called on Thread \"" + Thread.currentThread().getName() + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
public static Color interpolateHSB(Color c1, Color c2, float f) {
|
||||
float[] hsb1 = Color.RGBtoHSB(c1.getRed(), c1.getGreen(), c1.getBlue(), null);
|
||||
float[] hsb2 = Color.RGBtoHSB(c2.getRed(), c2.getGreen(), c2.getBlue(), null);
|
||||
float[] hsb = new float[3];
|
||||
|
||||
for (int i = 0; i < hsb.length; i++) {
|
||||
hsb[i] = hsb1[i] + ((hsb2[i] - hsb1[i]) * f);
|
||||
}
|
||||
|
||||
return Color.getHSBColor(hsb[0], hsb[1], hsb[2]);
|
||||
}
|
||||
|
||||
public static String escapeHTML(String s) {
|
||||
char[] sc = new char[] { '&', '<', '>', '"', '\'' };
|
||||
for (char c : sc) {
|
||||
s = s.replace(Character.toString(c), String.format("&#%d;", (int) c)); // e.g. &
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public static Color derive(Color color, float alpha) {
|
||||
return new Color(((int) ((alpha * 255)) << 24) | (color.getRGB() & 0x00FFFFFF), true);
|
||||
}
|
||||
|
||||
public static String toHex(Color c) {
|
||||
return String.format("#%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue());
|
||||
}
|
||||
|
||||
public static boolean isShiftOrAltDown(ActionEvent evt) {
|
||||
return checkModifiers(evt.getModifiers(), ActionEvent.SHIFT_MASK) || checkModifiers(evt.getModifiers(), ActionEvent.ALT_MASK);
|
||||
}
|
||||
|
||||
public static boolean checkModifiers(int modifiers, int mask) {
|
||||
return ((modifiers & mask) == mask);
|
||||
}
|
||||
|
||||
public static JButton createImageButton(Action action) {
|
||||
JButton button = new JButton(action);
|
||||
button.setHideActionText(true);
|
||||
button.setOpaque(false);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
public static void installAction(JComponent component, KeyStroke keystroke, Action action) {
|
||||
Object key = action.getValue(Action.NAME);
|
||||
|
||||
if (key == null)
|
||||
throw new IllegalArgumentException("Action must have a name");
|
||||
|
||||
component.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(keystroke, key);
|
||||
component.getActionMap().put(key, action);
|
||||
}
|
||||
|
||||
public static UndoManager installUndoSupport(JTextComponent component) {
|
||||
final UndoManager undoSupport = new UndoManager();
|
||||
|
||||
// install undo listener
|
||||
component.getDocument().addUndoableEditListener(undoSupport);
|
||||
|
||||
// install undo action
|
||||
installAction(component, KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_MASK), new AbstractAction("Undo") {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (undoSupport.canUndo())
|
||||
undoSupport.undo();
|
||||
}
|
||||
});
|
||||
|
||||
// install redo action
|
||||
installAction(component, KeyStroke.getKeyStroke(KeyEvent.VK_Y, KeyEvent.CTRL_MASK), new AbstractAction("Redo") {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (undoSupport.canRedo())
|
||||
undoSupport.redo();
|
||||
}
|
||||
});
|
||||
|
||||
return undoSupport;
|
||||
}
|
||||
|
||||
public static boolean isMaximized(Frame frame) {
|
||||
return (frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0;
|
||||
}
|
||||
|
||||
public static List<String> showMultiValueInputDialog(final String text, final String initialValue, final String title, final Component parent) throws InvocationTargetException, InterruptedException {
|
||||
String input = showInputDialog(text, initialValue, title, parent);
|
||||
if (input == null || input.isEmpty()) {
|
||||
return emptyList();
|
||||
}
|
||||
|
||||
for (char separator : new char[] { '|', ';' }) {
|
||||
if (input.indexOf(separator) >= 0) {
|
||||
List<String> values = new ArrayList<String>();
|
||||
for (String field : input.split(Pattern.quote(Character.toString(separator)))) {
|
||||
field = field.trim();
|
||||
|
||||
if (field.length() > 0) {
|
||||
values.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
if (values.size() > 0) {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return singletonList(input);
|
||||
}
|
||||
|
||||
public static String showInputDialog(final String text, final String initialValue, final String title, final Component parent) throws InvocationTargetException, InterruptedException {
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Object value = JOptionPane.showInputDialog(parent, text, title, PLAIN_MESSAGE, null, null, initialValue);
|
||||
if (value != null) {
|
||||
buffer.append(value.toString().trim());
|
||||
}
|
||||
}
|
||||
};
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
SwingUtilities.invokeAndWait(runnable);
|
||||
}
|
||||
|
||||
return buffer.length() == 0 ? null : buffer.toString();
|
||||
}
|
||||
|
||||
public static Window getWindow(Object component) {
|
||||
if (component instanceof Window)
|
||||
return (Window) component;
|
||||
|
||||
if (component instanceof Component)
|
||||
return SwingUtilities.getWindowAncestor((Component) component);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Point getOffsetLocation(Window owner) {
|
||||
if (owner == null) {
|
||||
Window[] toplevel = Window.getOwnerlessWindows();
|
||||
|
||||
if (toplevel.length == 0)
|
||||
return new Point(120, 80);
|
||||
|
||||
// assume first top-level window as point of reference
|
||||
owner = toplevel[0];
|
||||
}
|
||||
|
||||
Point p = owner.getLocation();
|
||||
Dimension d = owner.getSize();
|
||||
|
||||
return new Point(p.x + d.width / 4, p.y + d.height / 7);
|
||||
}
|
||||
|
||||
public static Image getImage(Icon icon) {
|
||||
if (icon == null)
|
||||
return null;
|
||||
|
||||
if (icon instanceof ImageIcon)
|
||||
return ((ImageIcon) icon).getImage();
|
||||
|
||||
// draw icon into a new image
|
||||
BufferedImage image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
Graphics2D g2d = image.createGraphics();
|
||||
icon.paintIcon(null, g2d, 0, 0);
|
||||
g2d.dispose();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
public static Dimension getDimension(Icon icon) {
|
||||
return new Dimension(icon.getIconWidth(), icon.getIconHeight());
|
||||
}
|
||||
|
||||
public static Timer invokeLater(int delay, final Runnable runnable) {
|
||||
Timer timer = new Timer(delay, new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
runnable.run();
|
||||
}
|
||||
});
|
||||
|
||||
timer.setRepeats(false);
|
||||
timer.start();
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
/**
|
||||
* When trying to drag a row of a multi-select JTable, it will start selecting rows instead of initiating a drag. This TableUI will give the JTable proper dnd behaviour.
|
||||
*/
|
||||
public static class DragDropRowTableUI extends BasicTableUI {
|
||||
|
||||
@Override
|
||||
protected MouseInputListener createMouseInputListener() {
|
||||
return new DragDropRowMouseInputHandler();
|
||||
}
|
||||
|
||||
protected class DragDropRowMouseInputHandler extends MouseInputHandler {
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
// Only do special handling if we are drag enabled with multiple selection
|
||||
if (table.getDragEnabled() && table.getSelectionModel().getSelectionMode() == ListSelectionModel.MULTIPLE_INTERVAL_SELECTION) {
|
||||
table.getTransferHandler().exportAsDrag(table, e, DnDConstants.ACTION_COPY);
|
||||
} else {
|
||||
super.mouseDragged(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy constructor to prevent instantiation.
|
||||
*/
|
||||
private TunedUtilities() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui.notification;
|
||||
|
||||
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
|
||||
public enum Direction {
|
||||
CENTER(0, 0, 0.5, 0.5, SwingConstants.CENTER),
|
||||
NORTH(0, -1, 0.5, 0.0, SwingConstants.NORTH),
|
||||
NORTH_EAST(1, -1, 1.0, 0.0, SwingConstants.NORTH_EAST),
|
||||
EAST(1, 0, 1.0, 0.5, SwingConstants.EAST),
|
||||
SOUTH_EAST(1, 1, 1.0, 1.0, SwingConstants.SOUTH_EAST),
|
||||
SOUTH(0, 1, 0.5, 1.0, SwingConstants.SOUTH),
|
||||
SOUTH_WEST(-1, 1, 0.0, 1.0, SwingConstants.SOUTH_WEST),
|
||||
WEST(-1, 0, 0.0, 0.5, SwingConstants.WEST),
|
||||
NORTH_WEST(-1, -1, 0.0, 0.0, SwingConstants.NORTH_WEST);
|
||||
|
||||
public final int vx;
|
||||
public final int vy;
|
||||
public final double ax;
|
||||
public final double ay;
|
||||
public final int swingConstant;
|
||||
|
||||
|
||||
private Direction(int vx, int vy, double ax, double ay, int swingConstant) {
|
||||
this.vx = vx;
|
||||
this.vy = vy;
|
||||
this.ax = ax;
|
||||
this.ay = ay;
|
||||
this.swingConstant = swingConstant;
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Created on 16.03.2005
|
||||
*/
|
||||
|
||||
package net.sourceforge.tuned.ui.notification;
|
||||
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Window;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.Border;
|
||||
|
||||
|
||||
public class MessageNotification extends NotificationWindow {
|
||||
|
||||
public MessageNotification(String head, String text, Icon icon, int timeout) {
|
||||
this((Window) null, head, text, icon, timeout);
|
||||
}
|
||||
|
||||
|
||||
public MessageNotification(String head, String text, Icon icon) {
|
||||
this(head, text, icon, -1);
|
||||
}
|
||||
|
||||
private int margin = 10;
|
||||
private Border marginBorder = BorderFactory.createEmptyBorder(margin, margin, margin, margin);
|
||||
private Border border = BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(new Color(245, 155, 15), Color.WHITE), marginBorder);
|
||||
|
||||
private JLabel headLabel;
|
||||
private JTextPane textArea;
|
||||
private JLabel imageLabel;
|
||||
|
||||
|
||||
public MessageNotification(Window owner, String head, String text, Icon icon, int timeout) {
|
||||
super(owner, timeout);
|
||||
|
||||
JComponent c = (JComponent) getContentPane();
|
||||
|
||||
c.setLayout(new BorderLayout(5, 2));
|
||||
c.setBackground(Color.WHITE);
|
||||
c.setBorder(border);
|
||||
|
||||
JPanel textPanel = new JPanel(new BorderLayout());
|
||||
textPanel.setOpaque(false);
|
||||
textPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
|
||||
|
||||
headLabel = new JLabel(head);
|
||||
headLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
headLabel.setFont(headLabel.getFont().deriveFont(Font.BOLD));
|
||||
textPanel.add(headLabel, BorderLayout.NORTH);
|
||||
|
||||
textArea = new JTextPane();
|
||||
textArea.setText(text);
|
||||
textArea.setEditable(false);
|
||||
textArea.setOpaque(false);
|
||||
textPanel.add(textArea, BorderLayout.CENTER);
|
||||
|
||||
if (icon != null) {
|
||||
imageLabel = new JLabel(icon);
|
||||
c.add(imageLabel, BorderLayout.WEST);
|
||||
}
|
||||
|
||||
c.add(textPanel, BorderLayout.CENTER);
|
||||
|
||||
pack();
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Created on 19.03.2005
|
||||
*/
|
||||
|
||||
package net.sourceforge.tuned.ui.notification;
|
||||
|
||||
|
||||
public interface NotificationLayout {
|
||||
|
||||
public void add(NotificationWindow notification);
|
||||
|
||||
|
||||
public void remove(NotificationWindow notification);
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Created on 19.03.2005
|
||||
*/
|
||||
|
||||
package net.sourceforge.tuned.ui.notification;
|
||||
|
||||
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
import net.sourceforge.tuned.ui.TunedUtilities;
|
||||
|
||||
|
||||
public class NotificationManager {
|
||||
|
||||
private final NotificationLayout layout;
|
||||
|
||||
|
||||
public NotificationManager() {
|
||||
this(new QueueNotificationLayout());
|
||||
}
|
||||
|
||||
|
||||
public NotificationManager(NotificationLayout layout) {
|
||||
this.layout = layout;
|
||||
}
|
||||
|
||||
|
||||
public void show(NotificationWindow notification) {
|
||||
TunedUtilities.checkEventDispatchThread();
|
||||
|
||||
notification.addWindowListener(new RemoveListener());
|
||||
layout.add(notification);
|
||||
|
||||
notification.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
private class RemoveListener extends WindowAdapter {
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
layout.remove((NotificationWindow) e.getWindow());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Created on 19.03.2005
|
||||
*/
|
||||
|
||||
package net.sourceforge.tuned.ui.notification;
|
||||
|
||||
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
import javax.swing.JWindow;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import net.sourceforge.tuned.ui.TunedUtilities;
|
||||
|
||||
|
||||
public class NotificationWindow extends JWindow {
|
||||
|
||||
private final int timeout;
|
||||
|
||||
|
||||
public NotificationWindow(Window owner, int timeout) {
|
||||
this(owner, timeout, true);
|
||||
}
|
||||
|
||||
|
||||
public NotificationWindow(Window owner, int timeout, boolean closeOnClick) {
|
||||
super(owner);
|
||||
this.timeout = timeout;
|
||||
|
||||
setAlwaysOnTop(true);
|
||||
|
||||
if (closeOnClick) {
|
||||
getGlassPane().addMouseListener(clickListener);
|
||||
getGlassPane().setVisible(true);
|
||||
}
|
||||
|
||||
addComponentListener(closeOnTimeout);
|
||||
}
|
||||
|
||||
|
||||
public NotificationWindow(Window owner) {
|
||||
this(owner, -1);
|
||||
}
|
||||
|
||||
|
||||
public final void close() {
|
||||
TunedUtilities.checkEventDispatchThread();
|
||||
|
||||
// window events are not fired automatically, required for layout updates
|
||||
processWindowEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
|
||||
|
||||
setVisible(false);
|
||||
|
||||
// component events are not fired automatically, used to cancel timeout timer
|
||||
processComponentEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_HIDDEN));
|
||||
|
||||
dispose();
|
||||
}
|
||||
|
||||
private final ComponentListener closeOnTimeout = new ComponentAdapter() {
|
||||
|
||||
private Timer timer = null;
|
||||
|
||||
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {
|
||||
if (timeout >= 0) {
|
||||
timer = TunedUtilities.invokeLater(timeout, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
close();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
if (timer != null) {
|
||||
timer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private final MouseAdapter clickListener = new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
close();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Created on 19.03.2005
|
||||
*/
|
||||
|
||||
package net.sourceforge.tuned.ui.notification;
|
||||
|
||||
|
||||
import static net.sourceforge.tuned.ui.notification.Direction.*;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class QueueNotificationLayout implements NotificationLayout {
|
||||
|
||||
private final List<NotificationWindow> notifications = new ArrayList<NotificationWindow>();
|
||||
|
||||
private final Direction alignment;
|
||||
private final Direction direction;
|
||||
private final Direction growAnchor;
|
||||
|
||||
|
||||
public QueueNotificationLayout() {
|
||||
this(SOUTH_EAST, WEST);
|
||||
}
|
||||
|
||||
|
||||
public QueueNotificationLayout(Direction alignment, Direction direction) {
|
||||
this.alignment = alignment;
|
||||
this.growAnchor = alignment;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
|
||||
public QueueNotificationLayout(Direction orientation, Direction direction, Direction growAnchor) {
|
||||
this.alignment = orientation;
|
||||
this.direction = direction;
|
||||
this.growAnchor = growAnchor;
|
||||
}
|
||||
|
||||
|
||||
private Point getBaseAnchor(Dimension screen, Insets insets) {
|
||||
Point p = new Point();
|
||||
|
||||
screen.height -= insets.top + insets.bottom;
|
||||
screen.width -= insets.left + insets.right;
|
||||
|
||||
p.x = (int) (alignment.ax * screen.width);
|
||||
p.y = (int) (alignment.ay * screen.height);
|
||||
|
||||
p.x += insets.left;
|
||||
p.y += insets.top;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
private Point getLocation(Point anchor, Dimension size) {
|
||||
Point p = new Point();
|
||||
|
||||
p.x = (int) (anchor.x - size.width * growAnchor.ax);
|
||||
p.y = (int) (anchor.y - size.height * growAnchor.ay);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
private Point getNextAnchor(Point anchor, Dimension size) {
|
||||
Point p = new Point();
|
||||
|
||||
p.x = anchor.x + size.width * direction.vx;
|
||||
p.y = anchor.y + size.height * direction.vy;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
public void add(NotificationWindow notification) {
|
||||
notifications.add(notification);
|
||||
align(notification.getGraphicsConfiguration());
|
||||
}
|
||||
|
||||
|
||||
private void align(GraphicsConfiguration gc) {
|
||||
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
|
||||
|
||||
Point anchor = getBaseAnchor(screen, insets);
|
||||
|
||||
for (NotificationWindow window : notifications) {
|
||||
Dimension size = window.getSize();
|
||||
|
||||
Point p = getLocation(anchor, size);
|
||||
window.setLocation(p);
|
||||
|
||||
anchor = getNextAnchor(anchor, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void remove(NotificationWindow notification) {
|
||||
if (notifications.remove(notification)) {
|
||||
align(notification.getGraphicsConfiguration());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned.ui.notification;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RectangularShape;
|
||||
|
||||
import javax.swing.border.AbstractBorder;
|
||||
|
||||
import net.sourceforge.tuned.ui.GradientStyle;
|
||||
|
||||
|
||||
public class SeparatorBorder extends AbstractBorder {
|
||||
|
||||
private int borderWidth;
|
||||
|
||||
private Color beginColor;
|
||||
|
||||
private Color endColor;
|
||||
|
||||
private GradientStyle gradientStyle;
|
||||
|
||||
private Position position;
|
||||
|
||||
|
||||
public static enum Position {
|
||||
TOP,
|
||||
BOTTOM,
|
||||
LEFT,
|
||||
RIGHT;
|
||||
|
||||
public Rectangle2D getRectangle(RectangularShape shape, int borderWidth) {
|
||||
switch (this) {
|
||||
case TOP:
|
||||
return new Rectangle2D.Double(shape.getX(), shape.getY(), shape.getWidth(), borderWidth);
|
||||
case BOTTOM:
|
||||
return new Rectangle2D.Double(shape.getX(), shape.getMaxY() - borderWidth, shape.getWidth(), borderWidth);
|
||||
case LEFT:
|
||||
return new Rectangle2D.Double(shape.getX(), shape.getY(), borderWidth, shape.getHeight());
|
||||
case RIGHT:
|
||||
return new Rectangle2D.Double(shape.getMaxX() - borderWidth, shape.getY(), borderWidth, shape.getHeight());
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Insets getInsets(Insets insets, int borderWidth) {
|
||||
switch (this) {
|
||||
case TOP:
|
||||
insets.top = borderWidth;
|
||||
insets.left = insets.right = insets.bottom = 0;
|
||||
return insets;
|
||||
case BOTTOM:
|
||||
insets.bottom = borderWidth;
|
||||
insets.left = insets.right = insets.top = 0;
|
||||
return insets;
|
||||
case LEFT:
|
||||
insets.left = borderWidth;
|
||||
insets.right = insets.top = insets.bottom = 0;
|
||||
return insets;
|
||||
case RIGHT:
|
||||
insets.right = borderWidth;
|
||||
insets.left = insets.top = insets.bottom = 0;
|
||||
return insets;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SeparatorBorder(int height, Color color, Position position) {
|
||||
this(height, color, null, null, position);
|
||||
}
|
||||
|
||||
|
||||
public SeparatorBorder(int height, Color color, GradientStyle gradientStyle, Position position) {
|
||||
this(height, color, new Color(color.getRed(), color.getGreen(), color.getBlue(), 0), gradientStyle, position);
|
||||
}
|
||||
|
||||
|
||||
public SeparatorBorder(int height, Color beginColor, Color endColor, GradientStyle gradientStyle, Position position) {
|
||||
this.borderWidth = height;
|
||||
this.beginColor = beginColor;
|
||||
this.endColor = endColor;
|
||||
this.gradientStyle = gradientStyle;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
Rectangle2D shape = position.getRectangle(new Rectangle2D.Double(x, y, width, height), this.borderWidth);
|
||||
|
||||
if (gradientStyle != null && endColor != null)
|
||||
g2d.setPaint(gradientStyle.getGradientPaint(shape, beginColor, endColor));
|
||||
else
|
||||
g2d.setPaint(beginColor);
|
||||
|
||||
g2d.fill(shape);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return getBorderInsets(c, new Insets(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
return position.getInsets(insets, borderWidth);
|
||||
}
|
||||
|
||||
|
||||
public Color getBeginColor() {
|
||||
return beginColor;
|
||||
}
|
||||
|
||||
|
||||
public void setBeginColor(Color beginColor) {
|
||||
this.beginColor = beginColor;
|
||||
}
|
||||
|
||||
|
||||
public Color getEndColor() {
|
||||
return endColor;
|
||||
}
|
||||
|
||||
|
||||
public void setEndColor(Color endColor) {
|
||||
this.endColor = endColor;
|
||||
}
|
||||
|
||||
|
||||
public GradientStyle getGradientStyle() {
|
||||
return gradientStyle;
|
||||
}
|
||||
|
||||
|
||||
public void setGradientStyle(GradientStyle gradientStyle) {
|
||||
this.gradientStyle = gradientStyle;
|
||||
}
|
||||
|
||||
|
||||
public int getBorderWidth() {
|
||||
return borderWidth;
|
||||
}
|
||||
|
||||
|
||||
public void setBorderWidth(int height) {
|
||||
this.borderWidth = height;
|
||||
}
|
||||
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
public void setPosition(Position position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Created on 20.03.2005
|
||||
*/
|
||||
|
||||
package net.sourceforge.tuned.ui.notification;
|
||||
|
||||
|
||||
import static net.sourceforge.tuned.ui.notification.Direction.*;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
|
||||
public class SimpleNotificationLayout implements NotificationLayout {
|
||||
|
||||
private NotificationWindow currentNotification;
|
||||
private Direction alignment;
|
||||
|
||||
|
||||
public SimpleNotificationLayout() {
|
||||
this(NORTH);
|
||||
}
|
||||
|
||||
|
||||
public SimpleNotificationLayout(Direction alignment) {
|
||||
this.alignment = alignment;
|
||||
}
|
||||
|
||||
|
||||
private Point getBaseAnchor(Dimension screen, Insets insets) {
|
||||
Point p = new Point();
|
||||
|
||||
screen.height -= insets.top + insets.bottom;
|
||||
screen.width -= insets.left + insets.right;
|
||||
|
||||
p.x = (int) (alignment.ax * screen.width);
|
||||
p.y = (int) (alignment.ay * screen.height);
|
||||
|
||||
p.x += insets.left;
|
||||
p.y += insets.top;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
private Point getLocation(Point anchor, Dimension size) {
|
||||
Point p = new Point();
|
||||
|
||||
p.x = (int) (anchor.x - size.width * alignment.ax);
|
||||
p.y = (int) (anchor.y - size.height * alignment.ay);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
public void add(NotificationWindow notification) {
|
||||
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(notification.getGraphicsConfiguration());
|
||||
Dimension size = notification.getSize();
|
||||
|
||||
Point anchor = getBaseAnchor(screen, insets);
|
||||
notification.setLocation(getLocation(anchor, size));
|
||||
|
||||
if (currentNotification != null) {
|
||||
currentNotification.close();
|
||||
}
|
||||
|
||||
currentNotification = notification;
|
||||
}
|
||||
|
||||
|
||||
public void remove(NotificationWindow notification) {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class ByteBufferOutputStreamTest {
|
||||
|
||||
@Test
|
||||
public void growBufferAsNeeded() throws Exception {
|
||||
// initial buffer size of 1, increase size by a factor of 2 if a bigger buffer is needed
|
||||
ByteBufferOutputStream buffer = new ByteBufferOutputStream(1, 1.0f);
|
||||
|
||||
buffer.write("asdf".getBytes("utf-8"));
|
||||
|
||||
// check content
|
||||
assertEquals("asdf", Charset.forName("utf-8").decode(buffer.getByteBuffer()).toString());
|
||||
|
||||
// check capacity
|
||||
assertEquals(4, buffer.capacity());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void transferFrom() throws Exception {
|
||||
InputStream in = new ByteArrayInputStream("asdf".getBytes("utf-8"));
|
||||
|
||||
ByteBufferOutputStream buffer = new ByteBufferOutputStream(4);
|
||||
|
||||
int n = buffer.transferFrom(Channels.newChannel(in));
|
||||
|
||||
// check number of bytes transfered
|
||||
assertEquals(4, n);
|
||||
|
||||
// check content
|
||||
assertEquals("asdf", Charset.forName("utf-8").decode(buffer.getByteBuffer()).toString());
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class FileUtilitiesTest {
|
||||
|
||||
@Test
|
||||
public void hasExtension() {
|
||||
assertTrue(FileUtilities.hasExtension("abc.txt", "txt"));
|
||||
assertFalse(FileUtilities.hasExtension(".hidden", "txt"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getExtension() {
|
||||
assertEquals("txt", FileUtilities.getExtension("abc.txt"));
|
||||
assertEquals("out", FileUtilities.getExtension("a.out"));
|
||||
assertEquals(null, FileUtilities.getExtension(".hidden"));
|
||||
assertEquals(null, FileUtilities.getExtension("a."));
|
||||
|
||||
assertEquals("r00", FileUtilities.getExtension("archive.r00"));
|
||||
assertEquals(null, FileUtilities.getExtension("archive.r??"));
|
||||
assertEquals(null, FileUtilities.getExtension("archive.invalid extension"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getNameWithoutExtension() {
|
||||
assertEquals("abc", FileUtilities.getNameWithoutExtension("abc.txt"));
|
||||
assertEquals("a", FileUtilities.getNameWithoutExtension("a.out"));
|
||||
assertEquals(".hidden", FileUtilities.getNameWithoutExtension(".hidden"));
|
||||
assertEquals("a.", FileUtilities.getNameWithoutExtension("a."));
|
||||
|
||||
assertEquals("archive", FileUtilities.getNameWithoutExtension("archive.r00"));
|
||||
assertEquals("archive.r??", FileUtilities.getNameWithoutExtension("archive.r??"));
|
||||
assertEquals("archive.invalid extension", FileUtilities.getNameWithoutExtension("archive.invalid extension"));
|
||||
}
|
||||
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class FilterIteratorTest {
|
||||
|
||||
private List<String> list = new ArrayList<String>();
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
list.add("first one");
|
||||
list.add("2");
|
||||
list.add("third space");
|
||||
list.add("four square");
|
||||
list.add("5");
|
||||
list.add("last order");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void iterateAndRemove() {
|
||||
Iterator<Integer> integers = new FilterIterator<String, Integer>(list) {
|
||||
|
||||
@Override
|
||||
protected Integer filter(String sourceValue) {
|
||||
if (sourceValue.matches("\\d+"))
|
||||
return Integer.valueOf(sourceValue);
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
assertEquals(Integer.valueOf(2), integers.next());
|
||||
integers.remove();
|
||||
assertEquals(Integer.valueOf(5), integers.next());
|
||||
integers.remove();
|
||||
|
||||
assertFalse(integers.hasNext());
|
||||
|
||||
// check if remove() worked
|
||||
Iterator<String> strings = list.iterator();
|
||||
assertEquals("first one", strings.next());
|
||||
assertEquals("third space", strings.next());
|
||||
assertEquals("four square", strings.next());
|
||||
assertEquals("last order", strings.next());
|
||||
|
||||
assertFalse(strings.hasNext());
|
||||
}
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import net.sourceforge.tuned.PreferencesMap.SimpleAdapter;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class PreferencesListTest {
|
||||
|
||||
private static Preferences root;
|
||||
private static Preferences strings;
|
||||
private static Preferences numbers;
|
||||
private static Preferences temp;
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
root = Preferences.userRoot().node("junit-test");
|
||||
|
||||
strings = root.node("strings");
|
||||
strings.put("0", "Rei");
|
||||
strings.put("1", "Firefly");
|
||||
strings.put("2", "Roswell");
|
||||
strings.put("3", "Angel");
|
||||
strings.put("4", "Dead like me");
|
||||
strings.put("5", "Babylon");
|
||||
|
||||
numbers = root.node("numbers");
|
||||
numbers.putInt("0", 4);
|
||||
numbers.putInt("1", 5);
|
||||
numbers.putInt("2", 2);
|
||||
|
||||
temp = root.node("temp");
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception {
|
||||
root.removeNode();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void get() {
|
||||
List<String> list = PreferencesList.map(strings);
|
||||
|
||||
assertEquals("Rei", list.get(0));
|
||||
assertEquals("Roswell", list.get(2));
|
||||
assertEquals("Babylon", list.get(5));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void add() {
|
||||
List<Integer> list = PreferencesList.map(numbers, SimpleAdapter.forClass(Integer.class));
|
||||
|
||||
list.add(3);
|
||||
|
||||
assertEquals("3", numbers.get("3", null));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void remove() {
|
||||
|
||||
ArrayList<String> compareValues = new ArrayList<String>();
|
||||
|
||||
compareValues.add("Gladiator 1");
|
||||
compareValues.add("Gladiator 2");
|
||||
compareValues.add("Gladiator 3");
|
||||
compareValues.add("Gladiator 4");
|
||||
compareValues.add("Gladiator 5");
|
||||
|
||||
List<String> prefs = PreferencesList.map(temp);
|
||||
prefs.addAll(compareValues);
|
||||
|
||||
for (int index : new int[] { 4, 0, 1 }) {
|
||||
prefs.remove(index);
|
||||
compareValues.remove(index);
|
||||
|
||||
assertArrayEquals(compareValues.toArray(), prefs.toArray());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void setEntry() {
|
||||
List<String> list = PreferencesList.map(strings);
|
||||
|
||||
list.set(3, "Buffy");
|
||||
|
||||
assertEquals(strings.get("3", null), "Buffy");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void toArray() throws Exception {
|
||||
List<String> list = PreferencesList.map(strings);
|
||||
|
||||
assertArrayEquals(list.subList(0, 3).toArray(), new Object[] { "Rei", "Firefly", "Roswell" });
|
||||
}
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import net.sourceforge.tuned.PreferencesMap.SerializableAdapter;
|
||||
import net.sourceforge.tuned.PreferencesMap.SimpleAdapter;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class PreferencesMapTest {
|
||||
|
||||
private static Preferences root;
|
||||
private static Preferences strings;
|
||||
private static Preferences numbers;
|
||||
private static Preferences temp;
|
||||
private static Preferences sequence;
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
root = Preferences.userRoot().node("junit-test");
|
||||
|
||||
strings = root.node("strings");
|
||||
strings.put("1", "Firefly");
|
||||
strings.put("2", "Roswell");
|
||||
strings.put("3", "Angel");
|
||||
strings.put("4", "Dead like me");
|
||||
strings.put("5", "Babylon");
|
||||
|
||||
numbers = root.node("numbers");
|
||||
numbers.putInt("M", 4);
|
||||
numbers.putInt("A", 5);
|
||||
numbers.putInt("X", 2);
|
||||
|
||||
sequence = root.node("sequence");
|
||||
sequence.putInt("1", 1);
|
||||
sequence.putInt("2", 2);
|
||||
sequence.putInt("3", 3);
|
||||
|
||||
temp = root.node("temp");
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception {
|
||||
root.removeNode();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void get() {
|
||||
Map<String, String> stringMap = PreferencesMap.map(strings);
|
||||
|
||||
assertEquals("Firefly", stringMap.get("1"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void put() {
|
||||
Map<String, String> stringMap = PreferencesMap.map(temp);
|
||||
|
||||
stringMap.put("key", "snake");
|
||||
|
||||
assertEquals("snake", temp.get("key", null));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void remove() throws Exception {
|
||||
Map<String, Integer> map = PreferencesMap.map(numbers, SimpleAdapter.forClass(Integer.class));
|
||||
|
||||
map.remove("A");
|
||||
|
||||
assertFalse(Arrays.asList(numbers.keys()).contains("A"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void clear() throws Exception {
|
||||
Map<String, Integer> map = PreferencesMap.map(temp, SimpleAdapter.forClass(Integer.class));
|
||||
|
||||
map.put("X", 42);
|
||||
|
||||
map.clear();
|
||||
|
||||
assertTrue(temp.keys().length == 0);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void containsKey() {
|
||||
temp.put("name", "kaya");
|
||||
|
||||
Map<String, String> map = PreferencesMap.map(temp);
|
||||
|
||||
assertTrue(map.containsKey("name"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void values() {
|
||||
|
||||
Map<String, Integer> map = PreferencesMap.map(sequence, SimpleAdapter.forClass(Integer.class));
|
||||
|
||||
Collection<Integer> list = map.values();
|
||||
|
||||
assertTrue(list.contains(1));
|
||||
assertTrue(list.contains(2));
|
||||
assertTrue(list.contains(3));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void containsValue() {
|
||||
Map<String, String> map = PreferencesMap.map(strings);
|
||||
|
||||
assertTrue(map.containsValue("Firefly"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void entrySet() {
|
||||
Map<String, Integer> map = PreferencesMap.map(numbers, SimpleAdapter.forClass(Integer.class));
|
||||
|
||||
for (Entry<String, Integer> entry : map.entrySet()) {
|
||||
Integer v = entry.getValue();
|
||||
entry.setValue(v + 1);
|
||||
}
|
||||
|
||||
assertEquals(5, numbers.getInt("M", -1));
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = NumberFormatException.class)
|
||||
public void adapterException() {
|
||||
PreferencesMap.map(strings, SimpleAdapter.forClass(Integer.class)).values();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void containsKeyWithObjectKey() throws Exception {
|
||||
Map<String, String> map = PreferencesMap.map(strings);
|
||||
|
||||
assertFalse(map.containsKey(new Object()));
|
||||
}
|
||||
|
||||
|
||||
public void getWithObjectKey() throws Exception {
|
||||
Map<String, String> map = PreferencesMap.map(strings);
|
||||
|
||||
assertEquals(null, map.get(new Object()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void serializableAdapter() {
|
||||
Map<String, Color> map = PreferencesMap.map(temp, new SerializableAdapter<Color>());
|
||||
Color color = new Color(0.25f, 0.50f, 1.00f);
|
||||
|
||||
map.put("color", color);
|
||||
assertEquals(color, map.get("color"));
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class TestUtil {
|
||||
|
||||
public static List<Object[]> asParameters(Object... parameters) {
|
||||
List<Object[]> list = new ArrayList<Object[]>();
|
||||
|
||||
for (Object parameter : parameters) {
|
||||
list.add(new Object[] { parameter });
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public static List<Object[]> asParameters(Collection<?> parameters) {
|
||||
return asParameters(parameters.toArray());
|
||||
}
|
||||
|
||||
|
||||
public static <T> List<List<T>> rotations(Collection<T> source) {
|
||||
List<List<T>> rotations = new ArrayList<List<T>>();
|
||||
|
||||
for (int i = 0; i < source.size(); i++) {
|
||||
List<T> copy = new ArrayList<T>(source);
|
||||
Collections.rotate(copy, i);
|
||||
rotations.add(copy);
|
||||
}
|
||||
|
||||
return rotations;
|
||||
}
|
||||
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
public class TreeIteratorTest {
|
||||
|
||||
private List<Object> tree;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
tree = new ArrayList<Object>();
|
||||
|
||||
tree.add("r1");
|
||||
|
||||
List<Object> branch = new ArrayList<Object>();
|
||||
branch.add("b1");
|
||||
branch.add("b2");
|
||||
|
||||
tree.add(branch);
|
||||
|
||||
tree.add("r2");
|
||||
|
||||
List<Object> treetop = new ArrayList<Object>();
|
||||
treetop.add("t1");
|
||||
treetop.add("t2");
|
||||
treetop.add("t3");
|
||||
|
||||
List<Object> trunk = new ArrayList<Object>();
|
||||
trunk.add(treetop);
|
||||
|
||||
tree.add(trunk);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void iterate() {
|
||||
TreeIterator<Object> treeIterator = new TreeIterator<Object>(tree) {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected Iterator<Object> children(Object node) {
|
||||
if (node instanceof Iterable)
|
||||
return ((Iterable) node).iterator();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// check leafs (String) and nodes (Iterable)
|
||||
assertTrue(treeIterator.next() instanceof Iterable); // root
|
||||
assertEquals("r1", treeIterator.next());
|
||||
assertTrue(treeIterator.next() instanceof Iterable); // branch
|
||||
assertEquals("b1", treeIterator.next());
|
||||
assertEquals("b2", treeIterator.next());
|
||||
assertEquals("r2", treeIterator.next());
|
||||
assertTrue(treeIterator.next() instanceof Iterable); // trunk
|
||||
assertTrue(treeIterator.next() instanceof Iterable); // treetop
|
||||
assertEquals("t1", treeIterator.next());
|
||||
assertEquals("t2", treeIterator.next());
|
||||
assertEquals("t3", treeIterator.next());
|
||||
|
||||
assertFalse(treeIterator.hasNext());
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
|
||||
package net.sourceforge.tuned;
|
||||
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses( { FileUtilitiesTest.class, ByteBufferOutputStreamTest.class, PreferencesMapTest.class, PreferencesListTest.class, TreeIteratorTest.class, FilterIteratorTest.class })
|
||||
public class TunedTestSuite {
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user