Switched to using nekohtml as html parser, externalized simmetrics (just copied the sourcefiles before), lots of buxfixes and improvements. Also started using an ant.

This commit is contained in:
Reinhard Pointner 2007-12-23 19:28:04 +00:00
commit b6b18e89b6
186 changed files with 10334 additions and 0 deletions

86
build.xml Normal file
View File

@ -0,0 +1,86 @@
<?xml version="1.0"?>
<project name="FileBot" basedir="." default="fatjar">
<property name="title" value="${ant.project.name}" />
<property name="version" value="2.1" />
<property name="url" value="http://sourceforge.net/projects/filebot/" />
<property name="source" location="${basedir}/source" />
<property name="build" location="${basedir}/build" />
<property name="lib" location="${basedir}/lib" />
<property name="executable" location="${basedir}/${title}.jar" />
<property name="lib.nekohtml" value="nekohtml.jar" />
<property name="lib.xerces" value="xercesImpl.jar" />
<property name="lib.simmetrics" value="simmetrics_jar_v1_6_2_d07_02_07.jar" />
<target name="jar" depends="build">
<jar destfile="${executable}" duplicate="fail">
<fileset dir="${build}" />
<manifest>
<attribute name="Built-By" value="${user.name}" />
<attribute name="Main-Class" value="Main" />
<attribute name="Title" value="${title}" />
<attribute name="Version" value="${version}" />
<attribute name="URL" value="${url}" />
</manifest>
<!-- include libs if fatjar is set -->
<zipfileset src="${lib}/${lib.nekohtml}">
<include if="fatjar" name="**/*.class" />
<include if="fatjar" name="**/*.properties" />
</zipfileset>
<zipfileset src="${lib}/${lib.xerces}">
<include if="fatjar" name="**/*.class" />
</zipfileset>
<zipfileset src="${lib}/${lib.simmetrics}">
<include if="fatjar" name="**/*.class" />
<exclude name="**/*Test*" />
</zipfileset>
</jar>
</target>
<target name="fatjar">
<antcall target="jar">
<param name="fatjar" value="true" />
</antcall>
</target>
<target name="build" depends="clean">
<!-- create build dir -->
<mkdir dir="${build}" />
<!-- compile -->
<javac srcdir="${source}" destdir="${build}">
<classpath>
<fileset dir="${lib}" includes="*.jar" />
</classpath>
</javac>
<!-- copy resources -->
<copy todir="${build}">
<fileset dir="${source}">
<include name="**/*.png" />
<include name="**/*.gif" />
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="${build}" />
<delete file="${executable}" verbose="true" />
</target>
<target name="run" depends="fatjar">
<java jar="${executable}" fork="true" />
</target>
</project>

BIN
fw/action.clear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/action.down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/action.find.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/action.load.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/action.rename.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
fw/action.save.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/action.up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/decoration.header.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
fw/design.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

BIN
fw/message.info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
fw/message.warning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
fw/panel.analyze.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
fw/panel.create.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
fw/panel.list.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
fw/panel.rename.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
fw/panel.search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
fw/panel.sfv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
fw/search.anidb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/search.tvdotcom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
fw/search.tvrage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/status.error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
fw/status.ok.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
fw/status.unknown.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
fw/status.warning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
fw/tab.close.hover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/tab.close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/tree.closed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/tree.collapse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
fw/tree.expand.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
fw/tree.leaf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
fw/tree.open.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
fw/window.icon.big.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
fw/window.icon.small.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
lib/nekohtml.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/xercesImpl.jar Normal file

Binary file not shown.

27
source/Main.java Normal file
View File

@ -0,0 +1,27 @@
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import net.sourceforge.filebot.ui.FileBotWindow;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new FileBotWindow().setVisible(true);
}
});
}
}

View File

@ -0,0 +1,91 @@
package net.sourceforge.filebot.resources;
import java.awt.Image;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class ResourceManager {
private static HashMap<String, URL> resourceMap = new HashMap<String, URL>();
static {
putResource("window.icon.small", "window.icon.small.png");
putResource("window.icon.big", "window.icon.big.png");
putResource("panel.analyze", "panel.analyze.png");
putResource("panel.rename", "panel.rename.png");
putResource("panel.create", "panel.create.png");
putResource("panel.list", "panel.list.png");
putResource("panel.search", "panel.search.png");
putResource("tree.open", "tree.open.png");
putResource("tree.closed", "tree.closed.png");
putResource("tree.leaf", "tree.leaf.png");
putResource("action.rename", "action.rename.png");
putResource("action.down", "action.down.png");
putResource("action.up", "action.up.png");
putResource("action.save", "action.save.png");
putResource("action.load", "action.load.png");
putResource("action.clear", "action.clear.png");
putResource("action.find", "action.find.png");
putResource("action.match.file2name", "action.match.file2name.png");
putResource("action.match.name2file", "action.match.name2file.png");
putResource("message.info", "message.info.png");
putResource("message.warning", "message.warning.png");
putResource("search.anidb", "search.anidb.png");
putResource("search.tvdotcom", "search.tvdotcom.png");
putResource("search.tvrage", "search.tvrage.png");
putResource("tab.close", "tab.close.png");
putResource("tab.close.hover", "tab.close.hover.png");
putResource("tab.loading", "tab.loading.gif");
putResource("tab.history", "action.find.png");
putResource("loading", "loading.gif");
putResource("tree.expand", "tree.expand.png");
putResource("tree.collapse", "tree.collapse.png");
putResource("panel.sfv", "panel.sfv.png");
putResource("status.error", "status.error.png");
putResource("status.ok", "status.ok.png");
putResource("status.unknown", "status.unknown.png");
putResource("status.warning", "status.warning.png");
putResource("decoration.header", "decoration.header.png");
}
private static void putResource(String name, String file) {
resourceMap.put(name, ResourceManager.class.getResource(file));
}
public static Image getImage(String name) {
if (!resourceMap.containsKey(name))
return null;
try {
return ImageIO.read(resourceMap.get(name));
} catch (IOException e) {
return null;
}
}
public static ImageIcon getIcon(String name) {
return new ImageIcon(resourceMap.get(name));
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1002 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

View File

@ -0,0 +1,294 @@
/*
* BeDecoder.java
*
* Created on May 30, 2003, 2:44 PM
* Copyright (C) 2003, 2004, 2005, 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*/
package net.sourceforge.filebot.torrent;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A set of utility methods to decode a bencoded array of byte into a Map. integer are represented as Long, String as byte[], dictionnaries as Map, and list as List.
*
* @author TdC_VgA
*
*/
public class BDecoder {
private boolean recovery_mode;
private static final Charset BINARY_CHARSET = Charset.forName("ISO-8859-1");
public static Map<?, ?> decode(byte[] data)
throws IOException {
return (new BDecoder().decodeByteArray(data));
}
public static Map<?, ?> decode(BufferedInputStream is)
throws IOException {
return (new BDecoder().decodeStream(is));
}
public BDecoder() {
}
public Map<?, ?> decodeByteArray(byte[] data)
throws IOException {
return (decode(new ByteArrayInputStream(data)));
}
public Map<?, ?> decodeStream(BufferedInputStream data)
throws IOException {
Object res = decodeInputStream(data, 0);
if (res == null)
throw (new IOException("BDecoder: zero length file"));
else if (!(res instanceof Map))
throw (new IOException("BDecoder: top level isn't a Map"));
return ((Map<?, ?>) res);
}
private Map<?, ?> decode(ByteArrayInputStream data)
throws IOException {
Object res = decodeInputStream(data, 0);
if (res == null)
throw (new IOException("BDecoder: zero length file"));
else if (!(res instanceof Map))
throw (new IOException("BDecoder: top level isn't a Map"));
return ((Map<?, ?>) res);
}
private Object decodeInputStream(InputStream bais, int nesting)
throws IOException {
if (!bais.markSupported())
throw new IOException("InputStream must support the mark() method");
// set a mark
bais.mark(Integer.MAX_VALUE);
// read a byte
int tempByte = bais.read();
// decide what to do
switch (tempByte) {
case 'd':
// create a new dictionary object
Map<String, Object> tempMap = new HashMap<String, Object>();
try {
// get the key
byte[] tempByteArray = null;
while ((tempByteArray = (byte[]) decodeInputStream(bais, nesting + 1)) != null) {
// decode some more
Object value = decodeInputStream(bais, nesting + 1);
// add the value to the map
CharBuffer cb = BINARY_CHARSET.decode(ByteBuffer.wrap(tempByteArray));
String key = new String(cb.array(), 0, cb.limit());
tempMap.put(key, value);
}
if (bais.available() < nesting)
throw (new IOException("BDecoder: invalid input data, 'e' missing from end of dictionary"));
} catch (Throwable e) {
if (!recovery_mode) {
if (e instanceof IOException)
throw ((IOException) e);
throw (new IOException(e));
}
}
// return the map
return tempMap;
case 'l':
// create the list
List<Object> tempList = new ArrayList<Object>();
try {
// create the key
Object tempElement = null;
while ((tempElement = decodeInputStream(bais, nesting + 1)) != null)
// add the element
tempList.add(tempElement);
if (bais.available() < nesting)
throw (new IOException("BDecoder: invalid input data, 'e' missing from end of list"));
} catch (Throwable e) {
if (!recovery_mode) {
if (e instanceof IOException)
throw ((IOException) e);
throw (new IOException(e));
}
}
// return the list
return tempList;
case 'e':
case -1:
return null;
case 'i':
return new Long(getNumberFromStream(bais, 'e'));
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
// move back one
bais.reset();
// get the string
return getByteArrayFromStream(bais);
default: {
int rem_len = bais.available();
if (rem_len > 256)
rem_len = 256;
byte[] rem_data = new byte[rem_len];
bais.read(rem_data);
throw (new IOException("BDecoder: unknown command '" + tempByte + ", remainder = " + new String(rem_data)));
}
}
}
private long getNumberFromStream(InputStream bais, char parseChar) throws IOException {
int length = 0;
// place a mark
bais.mark(Integer.MAX_VALUE);
int tempByte = bais.read();
while ((tempByte != parseChar) && (tempByte >= 0)) {
tempByte = bais.read();
length++;
}
// are we at the end of the stream?
if (tempByte < 0)
return -1;
// reset the mark
bais.reset();
// get the length
byte[] tempArray = new byte[length];
int count = 0;
int len = 0;
// get the string
while ((count != length) && ((len = bais.read(tempArray, count, length - count)) > 0))
count += len;
// jump ahead in the stream to compensate for the :
bais.skip(1);
// return the value
CharBuffer cb = BINARY_CHARSET.decode(ByteBuffer.wrap(tempArray));
String str_value = new String(cb.array(), 0, cb.limit());
return Long.parseLong(str_value);
}
private byte[] getByteArrayFromStream(InputStream bais) throws IOException {
int length = (int) getNumberFromStream(bais, ':');
if (length < 0)
return null;
// note that torrent hashes can be big (consider a 55GB file with 2MB
// pieces
// this generates a pieces hash of 1/2 meg
if (length > 8 * 1024 * 1024)
throw (new IOException("Byte array length too large (" + length + ")"));
byte[] tempArray = new byte[length];
int count = 0;
int len = 0;
// get the string
while ((count != length) && ((len = bais.read(tempArray, count, length - count)) > 0))
count += len;
if (count != tempArray.length)
throw (new IOException("BDecoder::getByteArrayFromStream: truncated"));
return tempArray;
}
public void setRecoveryMode(boolean r) {
recovery_mode = r;
}
}

View File

@ -0,0 +1,186 @@
package net.sourceforge.filebot.torrent;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class Torrent {
private String name;
private String encoding;
private String createdBy;
private String announce;
private String comment;
private Long creationDate;
private List<Entry> files;
private boolean singleFileTorrent;
public Torrent(File torrent) throws IOException {
FileInputStream in = new FileInputStream(torrent);
Map<?, ?> torrentMap = null;
try {
torrentMap = BDecoder.decode(new BufferedInputStream(in));
} finally {
in.close();
}
Charset charset = Charset.forName("UTF-8");
encoding = decodeString(torrentMap.get("encoding"), charset);
try {
charset = Charset.forName(encoding);
} catch (Exception e) {
}
createdBy = decodeString(torrentMap.get("created by"), charset);
announce = decodeString(torrentMap.get("announce"), charset);
comment = decodeString(torrentMap.get("comment"), charset);
creationDate = decodeLong(torrentMap.get("creation date"));
Map<?, ?> infoMap = (Map<?, ?>) torrentMap.get("info");
name = decodeString(infoMap.get("name"), charset);
if (infoMap.containsKey("files")) {
singleFileTorrent = false;
files = new ArrayList<Entry>();
for (Object fileMapObject : (List<?>) infoMap.get("files")) {
Map<?, ?> fileMap = (Map<?, ?>) fileMapObject;
List<?> pathList = (List<?>) fileMap.get("path");
StringBuffer pathBuffer = new StringBuffer();
String entryName = null;
Iterator<?> iterator = pathList.iterator();
while (iterator.hasNext()) {
String pathElement = decodeString(iterator.next(), charset);
if (iterator.hasNext()) {
pathBuffer.append(pathElement);
pathBuffer.append("/");
} else {
// the last element in the path list is the filename
entryName = pathElement;
}
}
Long length = decodeLong(fileMap.get("length"));
files.add(new Entry(entryName, length, pathBuffer.toString()));
}
} else {
// single file torrent
singleFileTorrent = true;
files = new ArrayList<Entry>(1);
Long length = decodeLong(infoMap.get("length"));
files.add(new Entry(name, length, ""));
}
}
private String decodeString(Object bytearray, Charset charset) {
if (bytearray == null)
return null;
return new String((byte[]) bytearray, charset);
}
private Long decodeLong(Object number) {
if (number == null)
return null;
return (Long) number;
}
public String getAnnounce() {
return announce;
}
public String getComment() {
return comment;
}
public String getCreatedBy() {
return createdBy;
}
public Long getCreationDate() {
return creationDate;
}
public String getEncoding() {
return encoding;
}
public List<Entry> getFiles() {
return files;
}
public String getName() {
return name;
}
public boolean isSingleFileTorrent() {
return singleFileTorrent;
}
public static class Entry {
private String name;
private long length;
private String path;
public Entry(String name, Long length, String path) {
this.name = name;
this.length = length;
this.path = path;
}
public Long getLength() {
return length;
}
public String getName() {
return name;
}
public String getPath() {
return path;
}
}
}

View File

@ -0,0 +1,174 @@
package net.sourceforge.filebot.ui;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.border.TitledBorder;
import net.sourceforge.filebot.ui.sal.FileTransferable;
import net.sourceforge.filebot.ui.sal.Saveable;
import net.sourceforge.filebot.ui.transferablepolicies.NullTransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicySupport;
import net.sourceforge.tuned.ui.FancyListCellRenderer;
public class FileBotList extends JPanel implements Saveable, TransferablePolicySupport {
private JList list = new JList(new DefaultListModel());
private TitledBorder titledBorder;
private String title;
private TransferablePolicy transferablePolicy = new NullTransferablePolicy();
public FileBotList(boolean enableDrop, boolean enableDrag, boolean initRemoveAction) {
this(enableDrop, enableDrag, initRemoveAction, true);
}
public FileBotList(boolean enableDrop, boolean enableDrag, boolean initRemoveAction, boolean border) {
super(new BorderLayout());
JScrollPane listScrollPane = new JScrollPane(list);
if (border) {
titledBorder = new TitledBorder("");
setBorder(titledBorder);
} else {
listScrollPane.setBorder(BorderFactory.createEmptyBorder());
}
list.setCellRenderer(new FancyListCellRenderer());
list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
add(listScrollPane, BorderLayout.CENTER);
TransferablePolicySupport handlerTransferablePolicySupport = null;
Saveable handlerSaveable = null;
if (enableDrop) {
handlerTransferablePolicySupport = this;
}
if (enableDrag) {
handlerSaveable = this;
}
list.setTransferHandler(new FileBotTransferHandler(handlerTransferablePolicySupport, handlerSaveable));
if (handlerSaveable != null)
MouseDragRecognizeListener.createForComponent(this.getListComponent());
if (initRemoveAction) {
// Shortcut DELETE
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("pressed DELETE"), removeAction);
}
}
public JList getListComponent() {
return list;
}
public void setTransferablePolicy(TransferablePolicy transferablePolicy) {
this.transferablePolicy = transferablePolicy;
}
public TransferablePolicy getTransferablePolicy() {
return transferablePolicy;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
if (titledBorder != null)
titledBorder.setTitle(title);
if (isVisible()) {
revalidate();
repaint();
}
}
public DefaultListModel getModel() {
return (DefaultListModel) list.getModel();
}
public void save(File file) {
try {
PrintStream out = new PrintStream(file);
DefaultListModel model = getModel();
for (int i = 0; i < model.getSize(); ++i)
out.println(model.get(i).toString());
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public String getDefaultFileName() {
return title + ".txt";
}
public boolean isSaveable() {
return !getModel().isEmpty();
}
public void load(List<File> files) {
FileTransferable tr = new FileTransferable(files);
if (transferablePolicy.accept(tr))
transferablePolicy.handleTransferable(tr, false);
}
private final AbstractAction removeAction = new AbstractAction("Remove") {
public void actionPerformed(ActionEvent e) {
int index = list.getSelectedIndex();
Object values[] = list.getSelectedValues();
for (Object value : values)
getModel().removeElement(value);
int maxIndex = list.getModel().getSize() - 1;
if (index > maxIndex)
index = maxIndex;
list.setSelectedIndex(index);
}
};
}

View File

@ -0,0 +1,40 @@
package net.sourceforge.filebot.ui;
import java.awt.BorderLayout;
import javax.swing.Icon;
import javax.swing.JPanel;
public class FileBotPanel extends JPanel {
private String text;
private Icon icon;
public FileBotPanel(String text, Icon icon) {
super(new BorderLayout(10, 20));
this.text = text;
this.icon = icon;
}
public Icon getIcon() {
return icon;
}
public String getText() {
return text;
}
@Override
public String toString() {
return getText();
}
}

View File

@ -0,0 +1,124 @@
package net.sourceforge.filebot.ui;
import java.awt.Color;
import java.awt.Component;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
import net.sourceforge.filebot.ui.panel.analyze.AnalyzePanel;
import net.sourceforge.filebot.ui.panel.create.CreatePanel;
import net.sourceforge.filebot.ui.panel.list.ListPanel;
import net.sourceforge.filebot.ui.panel.rename.RenamePanel;
import net.sourceforge.filebot.ui.panel.search.SearchPanel;
import net.sourceforge.filebot.ui.panel.sfv.SfvPanel;
import net.sourceforge.tuned.ui.FancyListCellRenderer;
import net.sourceforge.tuned.ui.GradientStyle;
public class FileBotPanelSelectionList extends JList {
private static final int SELECTDELAY_ON_DRAG_OVER = 300;
public FileBotPanelSelectionList() {
DefaultListModel model = new DefaultListModel();
setModel(model);
setCellRenderer(new PanelCellRenderer());
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
setBorder(new EmptyBorder(4, 5, 4, 5));
new DropTarget(this, new DragDropListener());
model.addElement(new ListPanel());
model.addElement(new RenamePanel());
model.addElement(new AnalyzePanel());
model.addElement(new SearchPanel());
model.addElement(new CreatePanel());
model.addElement(new SfvPanel());
}
private class PanelCellRenderer extends FancyListCellRenderer {
public PanelCellRenderer() {
super(10, Color.decode("#163264"), GradientStyle.TOP_TO_BOTTOM);
setVerticalTextPosition(SwingConstants.BOTTOM);
setHorizontalTextPosition(SwingConstants.CENTER);
}
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
FileBotPanel panel = (FileBotPanel) value;
setText(panel.getText());
setIcon(panel.getIcon());
return this;
}
}
private class DragDropListener extends DropTargetAdapter implements ActionListener {
private boolean selectEnabled = false;
private Timer timer = new Timer(SELECTDELAY_ON_DRAG_OVER, this);
public DragDropListener() {
timer.setRepeats(false);
}
public void actionPerformed(ActionEvent e) {
selectEnabled = true;
}
@Override
public void dragOver(DropTargetDragEvent dtde) {
if (selectEnabled) {
int index = locationToIndex(dtde.getLocation());
setSelectedIndex(index);
}
}
@Override
public void dragEnter(DropTargetDragEvent dtde) {
timer.start();
}
@Override
public void dragExit(DropTargetEvent dte) {
timer.stop();
selectEnabled = false;
}
public void drop(DropTargetDropEvent dtde) {
}
}
}

View File

@ -0,0 +1,181 @@
package net.sourceforge.filebot.ui;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.InvalidDnDOperationException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.TransferHandler;
import javax.swing.tree.TreePath;
import net.sourceforge.filebot.ui.sal.FileTransferable;
import net.sourceforge.filebot.ui.sal.Saveable;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicySupport;
public class FileBotTransferHandler extends TransferHandler {
private TransferablePolicySupport transferablePolicySupport;
private Saveable saveable;
private boolean dragging;
private String tmpdir = System.getProperty("java.io.tmpdir");
public FileBotTransferHandler(TransferablePolicySupport transferablePolicySupport, Saveable saveable) {
this.transferablePolicySupport = transferablePolicySupport;
this.saveable = saveable;
}
private boolean canImportCache = false;
@Override
public boolean canImport(TransferSupport support) {
// show "drop allowed" mousecursor when dragging even though drop is not allowed
if (dragging)
return true;
if (transferablePolicySupport == null)
return false;
if (support.isDrop())
support.setShowDropLocation(false);
Transferable t = support.getTransferable();
try {
canImportCache = transferablePolicySupport.getTransferablePolicy().accept(t);
} catch (InvalidDnDOperationException e) {
// for some reason the last transferable has no drop current
}
return canImportCache;
}
@Override
public boolean importData(TransferSupport support) {
if (dragging)
return false;
if (!canImport(support))
return false;
boolean add = false;
if (support.isDrop())
add = support.getDropAction() == COPY;
Transferable t = support.getTransferable();
return transferablePolicySupport.getTransferablePolicy().handleTransferable(t, add);
}
@Override
protected void exportDone(JComponent source, Transferable data, int action) {
dragging = false;
if (data == null)
return;
try {
List<?> list = (List<?>) data.getTransferData(DataFlavor.javaFileListFlavor);
for (Object object : list) {
File temporaryFile = (File) object;
temporaryFile.deleteOnExit();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public int getSourceActions(JComponent c) {
if (saveable == null || !saveable.isSaveable())
return NONE;
return MOVE | COPY;
}
@Override
public void exportToClipboard(JComponent comp, Clipboard clip, int action) throws IllegalStateException {
ArrayList<String> lines = new ArrayList<String>();
if (comp instanceof JList) {
JList list = (JList) comp;
for (Object value : list.getSelectedValues()) {
lines.add(value.toString());
}
} else if (comp instanceof JTree) {
JTree tree = (JTree) comp;
for (TreePath path : tree.getSelectionPaths()) {
lines.add(path.getPathComponent(path.getPathCount() - 1).toString());
}
} else if (comp instanceof JTable) {
JTable table = (JTable) comp;
for (int row : table.getSelectedRows()) {
StringBuffer b = new StringBuffer();
int maxCol = table.getColumnCount() - 1;
for (int col = 0; col <= maxCol; col++) {
b.append(table.getModel().getValueAt(row, col));
if (col != maxCol)
b.append("\t");
}
lines.add(b.toString());
}
}
StringBuffer b = new StringBuffer();
Iterator<String> it = lines.iterator();
while (it.hasNext()) {
b.append(it.next());
if (it.hasNext())
b.append("\n");
}
clip.setContents(new StringSelection(b.toString()), null);
}
@Override
protected Transferable createTransferable(JComponent c) {
dragging = true;
try {
File temporaryFile = new File(tmpdir, saveable.getDefaultFileName());
temporaryFile.createNewFile();
saveable.save(temporaryFile);
return new FileTransferable(temporaryFile);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,236 @@
package net.sourceforge.filebot.ui;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.Enumeration;
import java.util.LinkedList;
import javax.swing.AbstractAction;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.transferablepolicies.NullTransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicySupport;
public class FileBotTree extends JTree implements TransferablePolicySupport {
private TransferablePolicy transferablePolicy = new NullTransferablePolicy();
public FileBotTree() {
super(new DefaultTreeModel(new DefaultMutableTreeNode()));
getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
setCellRenderer(new FileBotTreeCellRenderer());
setShowsRootHandles(true);
setRootVisible(false);
setRowHeight(22);
setTransferHandler(new FileBotTransferHandler(this, null));
addMouseListener(new ExpandCollapsePopupListener());
}
public void clear() {
setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
}
public void setTransferablePolicy(TransferablePolicy transferablePolicy) {
this.transferablePolicy = transferablePolicy;
}
public TransferablePolicy getTransferablePolicy() {
return transferablePolicy;
}
public LinkedList<File> convertToList() {
LinkedList<File> list = new LinkedList<File>();
TreeModel m = getModel();
walk(m, m.getRoot(), list);
return list;
}
@Override
public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
if (value instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
Object userObject = node.getUserObject();
if (userObject != null && userObject instanceof File) {
File file = (File) node.getUserObject();
return file.getName();
}
}
return value.toString();
}
private void walk(TreeModel model, Object o, LinkedList<File> list) {
int cc = model.getChildCount(o);
for (int i = 0; i < cc; i++) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) model.getChild(o, i);
if (model.isLeaf(child))
list.add((File) child.getUserObject());
else
walk(model, child, list);
}
}
public void expandOrCollapseAll(boolean expand) {
TreeNode node = (TreeNode) getModel().getRoot();
Enumeration<?> e = node.children();
while (e.hasMoreElements()) {
TreeNode n = (TreeNode) e.nextElement();
TreePath path = new TreePath(node).pathByAddingChild(n);
expandOrCollapseAllImpl(path, expand);
}
}
private void expandOrCollapseAllImpl(TreePath parent, boolean expand) {
// Traverse children
TreeNode node = (TreeNode) parent.getLastPathComponent();
if (node.getChildCount() >= 0)
for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
TreeNode n = (TreeNode) e.nextElement();
TreePath path = parent.pathByAddingChild(n);
expandOrCollapseAllImpl(path, expand);
}
// Expansion or collapse must be done bottom-up
if (expand)
expandPath(parent);
else
collapsePath(parent);
}
private class ExpandCollapsePopup extends JPopupMenu {
public ExpandCollapsePopup() {
if (getSelectionCount() >= 1) {
Object pathComponent = getLastSelectedPathComponent();
if (pathComponent instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) pathComponent;
Object userObject = node.getUserObject();
if (userObject instanceof File) {
File file = (File) userObject;
if (file.isFile()) {
JMenuItem openItem = new JMenuItem(new OpenAction("Open", file));
openItem.setFont(openItem.getFont().deriveFont(Font.BOLD));
add(openItem);
add(new OpenAction("Open Folder", file.getParentFile()));
addSeparator();
}
}
}
}
add(new ExpandOrCollapseAction(true));
add(new ExpandOrCollapseAction(false));
}
private class OpenAction extends AbstractAction {
private File file;
public OpenAction(String text, File file) {
super(text);
this.file = file;
if (file == null)
setEnabled(false);
}
public void actionPerformed(ActionEvent e) {
try {
Desktop.getDesktop().open(file);
} catch (Exception ex) {
MessageManager.showWarning(ex.getMessage());
ex.printStackTrace();
}
}
}
private class ExpandOrCollapseAction extends AbstractAction {
private boolean expand;
public ExpandOrCollapseAction(boolean expand) {
this.expand = expand;
if (expand) {
putValue(SMALL_ICON, ResourceManager.getIcon("tree.expand"));
putValue(NAME, "Expand all");
} else {
putValue(SMALL_ICON, ResourceManager.getIcon("tree.collapse"));
putValue(NAME, "Collapse all");
}
}
public void actionPerformed(ActionEvent e) {
expandOrCollapseAll(expand);
}
}
}
private class ExpandCollapsePopupListener extends MouseAdapter {
@Override
public void mouseReleased(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
ExpandCollapsePopup popup = new ExpandCollapsePopup();
popup.show(e.getComponent(), e.getX(), e.getY());
}
}
@Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
TreePath path = getPathForLocation(e.getX(), e.getY());
setSelectionPath(path);
}
}
}
}

View File

@ -0,0 +1,47 @@
package net.sourceforge.filebot.ui;
import java.awt.Component;
import java.io.File;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.tuned.ui.FancyTreeCellRenderer;
import net.sourceforge.tuned.ui.GradientStyle;
public class FileBotTreeCellRenderer extends FancyTreeCellRenderer {
public FileBotTreeCellRenderer() {
super(GradientStyle.TOP_TO_BOTTOM);
openIcon = ResourceManager.getIcon("tree.open");
closedIcon = ResourceManager.getIcon("tree.closed");
leafIcon = ResourceManager.getIcon("tree.leaf");
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
if (leaf && isFolder(value))
super.getTreeCellRendererComponent(tree, value, sel, true, false, row, hasFocus);
else
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
return this;
}
private boolean isFolder(Object value) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
Object object = node.getUserObject();
if (object instanceof File)
return ((File) object).isDirectory();
return false;
}
}

View File

@ -0,0 +1,23 @@
package net.sourceforge.filebot.ui;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
public class FileBotUtil {
private FileBotUtil() {
// hide construktor
}
public static void registerActionForKeystroke(JComponent component, KeyStroke keystroke, Action action) {
Integer key = action.hashCode();
component.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(keystroke, key);
component.getActionMap().put(key, action);
}
}

View File

@ -0,0 +1,139 @@
package net.sourceforge.filebot.ui;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.ListModel;
import javax.swing.OverlayLayout;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.tuned.ui.ShadowBorder;
public class FileBotWindow extends JFrame implements ListSelectionListener {
private JPanel pagePanel = new JPanel(new CardLayout());
private FileBotPanelSelectionList selectionListPanel = new FileBotPanelSelectionList();
private HeaderPanel headerPanel = new HeaderPanel();
public FileBotWindow() {
super("FileBot");
setLocationByPlatform(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
ArrayList<Image> icons = new ArrayList<Image>(2);
icons.add(ResourceManager.getImage("window.icon.small"));
icons.add(ResourceManager.getImage("window.icon.big"));
setIconImages(icons);
selectionListPanel.addListSelectionListener(this);
JComponent contentPane = createContentPane();
setContentPane(contentPane);
// Shortcut ESC
FileBotUtil.registerActionForKeystroke(contentPane, KeyStroke.getKeyStroke("released ESCAPE"), closeAction);
setSize(760, 615);
selectionListPanel.setSelectedIndex(3);
}
public void valueChanged(ListSelectionEvent e) {
FileBotPanel currentPanel = (FileBotPanel) selectionListPanel.getSelectedValue();
headerPanel.setTitle(currentPanel.getText());
CardLayout cardLayout = (CardLayout) pagePanel.getLayout();
cardLayout.show(pagePanel, currentPanel.getText());
JComponent c = (JComponent) getContentPane();
c.updateUI();
}
private JComponent createSelectionListLayer() {
JPanel selectionListLayer = new JPanel(new BorderLayout());
selectionListLayer.setOpaque(false);
JPanel shadowBorderPanel = new JPanel(new BorderLayout());
shadowBorderPanel.setOpaque(false);
JScrollPane selectListScrollPane = new JScrollPane(selectionListPanel);
selectListScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
selectListScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
shadowBorderPanel.add(selectListScrollPane, BorderLayout.CENTER);
shadowBorderPanel.setBorder(new ShadowBorder());
selectionListLayer.setBorder(new EmptyBorder(10, 6, 12, 0));
selectionListLayer.add(shadowBorderPanel, BorderLayout.WEST);
selectionListLayer.setAlignmentX(0.0f);
selectionListLayer.setAlignmentY(0.0f);
selectionListLayer.setMaximumSize(selectionListLayer.getPreferredSize());
return selectionListLayer;
}
private JComponent createPageLayer() {
JPanel pageLayer = new JPanel(new BorderLayout());
pagePanel.setBorder(new EmptyBorder(10, 110, 10, 10));
pageLayer.add(headerPanel, BorderLayout.NORTH);
pageLayer.add(pagePanel, BorderLayout.CENTER);
ListModel model = selectionListPanel.getModel();
for (int i = 0; i < model.getSize(); i++) {
FileBotPanel panel = (FileBotPanel) model.getElementAt(i);
panel.setVisible(false);
pagePanel.add(panel, panel.getText());
}
pageLayer.setAlignmentX(0.0f);
pageLayer.setAlignmentY(0.0f);
return pageLayer;
}
private JComponent createContentPane() {
JPanel contentPane = new JPanel();
contentPane.setLayout(new OverlayLayout(contentPane));
contentPane.add(createSelectionListLayer());
contentPane.add(createPageLayer());
return contentPane;
}
private final AbstractAction closeAction = new AbstractAction("Close") {
public void actionPerformed(ActionEvent e) {
setVisible(false);
dispose();
System.exit(0);
}
};
}

View File

@ -0,0 +1,95 @@
package net.sourceforge.filebot.ui;
import java.io.File;
import java.text.NumberFormat;
public class FileFormat {
private static NumberFormat nf = NumberFormat.getNumberInstance();
public final static long KILO = 1024;
public final static long MEGA = KILO * 1024;
public final static long GIGA = MEGA * 1024;
static {
nf.setMaximumFractionDigits(0);
}
public static String formatSize(long size) {
if (size >= MEGA)
return nf.format((double) size / MEGA) + " MB";
else if (size >= KILO)
return nf.format((double) size / KILO) + " KB";
else
return nf.format((double) size) + " Byte";
}
public static String formatName(File f) {
String name = f.getName();
if (f.isDirectory())
return name;
return getNameWithoutSuffix(name);
}
public static String formatNumberOfFiles(int n) {
if (n == 1)
return n + " file";
else
return n + " files";
}
public static String getSuffix(File f) {
return getSuffix(f, false);
}
public static String getSuffix(File f, boolean dot) {
String name = f.getName();
int dotIndex = name.lastIndexOf(".");
if (dotIndex > 1) {
String suffix = name.substring(dotIndex + 1, name.length());
if (dot)
return "." + suffix;
else
return suffix;
} else
return "";
}
public static String getNameWithoutSuffix(String name) {
int dotIndex = name.lastIndexOf(".");
if (dotIndex < 1)
return name;
return name.substring(0, dotIndex);
}
public static String getNameWithoutSuffix(File file) {
return getNameWithoutSuffix(file.getName());
}
public static String getName(File file) {
if (!file.getName().isEmpty()) {
return file.getName();
} else {
return file.toString();
}
}
}

View File

@ -0,0 +1,76 @@
package net.sourceforge.filebot.ui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.tuned.ui.GradientStyle;
import net.sourceforge.tuned.ui.notification.SeparatorBorder;
import net.sourceforge.tuned.ui.notification.SeparatorBorder.Position;
public class HeaderPanel extends JPanel {
private JLabel titleLabel = new JLabel();
private float[] gradientFractions = { 0.0f, 0.5f, 1.0f };
private Color[] gradientColors = { new Color(0xF6F6F6), new Color(0xF8F8F8), new Color(0xF3F3F3) };
public HeaderPanel() {
super(new BorderLayout());
setBackground(Color.WHITE);
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.setOpaque(false);
titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
titleLabel.setVerticalAlignment(SwingConstants.CENTER);
titleLabel.setOpaque(false);
titleLabel.setForeground(new Color(0x101010));
titleLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 24));
int margin = 9;
titleLabel.setBorder(new EmptyBorder(margin - 1, 90, margin + 1, 0));
JLabel decorationLabel = new JLabel(ResourceManager.getIcon("decoration.header"));
decorationLabel.setHorizontalAlignment(SwingConstants.CENTER);
decorationLabel.setVerticalAlignment(SwingConstants.CENTER);
centerPanel.setBorder(new EmptyBorder(0, 78, 0, 0));
centerPanel.add(decorationLabel, BorderLayout.EAST);
centerPanel.add(titleLabel, BorderLayout.CENTER);
add(centerPanel, BorderLayout.CENTER);
setBorder(new SeparatorBorder(1, new Color(0xB4B4B4), new Color(0xACACAC), GradientStyle.LEFT_TO_RIGHT, Position.BOTTOM));
}
public void setTitle(String title) {
titleLabel.setText(title);
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
LinearGradientPaint paint = new LinearGradientPaint(0, 0, getWidth(), 0, gradientFractions, gradientColors);
g2d.setPaint(paint);
g2d.fill(getBounds());
}
}

View File

@ -0,0 +1,34 @@
package net.sourceforge.filebot.ui;
import javax.swing.Icon;
import javax.swing.SwingConstants;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.tuned.ui.notification.MessageNotification;
import net.sourceforge.tuned.ui.notification.NotificationManager;
import net.sourceforge.tuned.ui.notification.QueueNotificationLayout;
public class MessageManager {
private static final int TIMEOUT = 2500;
private static final NotificationManager manager = new NotificationManager(new QueueNotificationLayout(SwingConstants.NORTH, SwingConstants.SOUTH));
public static void showInfo(String message) {
show(message, ResourceManager.getIcon("message.info"), TIMEOUT);
}
public static void showWarning(String message) {
show(message, ResourceManager.getIcon("message.warning"), TIMEOUT * 2);
}
private static void show(String message, Icon icon, int timeout) {
manager.show(new MessageNotification("FileBot", message, icon, timeout));
}
}

View File

@ -0,0 +1,57 @@
package net.sourceforge.filebot.ui;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.TransferHandler;
public class MouseDragRecognizeListener extends MouseAdapter {
private MouseEvent firstMouseEvent = null;
private int dragShift = 5;
@Override
public void mousePressed(MouseEvent e) {
firstMouseEvent = e;
e.consume();
}
@Override
public void mouseDragged(MouseEvent e) {
if (firstMouseEvent != null) {
e.consume();
int dx = Math.abs(e.getX() - firstMouseEvent.getX());
int dy = Math.abs(e.getY() - firstMouseEvent.getY());
if (dx > dragShift || dy > dragShift) {
// This is a drag, not a click.
JComponent c = (JComponent) e.getSource();
TransferHandler handler = c.getTransferHandler();
handler.exportAsDrag(c, firstMouseEvent, TransferHandler.COPY);
firstMouseEvent = null;
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
firstMouseEvent = null;
}
public static void createForComponent(JComponent component) {
MouseDragRecognizeListener l = new MouseDragRecognizeListener();
component.addMouseListener(l);
component.addMouseMotionListener(l);
}
}

View File

@ -0,0 +1,81 @@
package net.sourceforge.filebot.ui.panel.analyze;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.FileBotPanel;
import net.sourceforge.filebot.ui.panel.analyze.tools.SplitPanel;
import net.sourceforge.filebot.ui.panel.analyze.tools.ToolPanel;
import net.sourceforge.filebot.ui.panel.analyze.tools.TypePanel;
public class AnalyzePanel extends FileBotPanel {
private FileTreePanel filePanel = new FileTreePanel();
private JTabbedPane toolsPanel = new JTabbedPane(SwingConstants.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
public AnalyzePanel() {
super("Analyze", ResourceManager.getIcon("panel.analyze"));
Box panel = new Box(BoxLayout.X_AXIS);
panel.add(filePanel);
panel.add(Box.createHorizontalStrut(50));
JPanel right = new JPanel();
right.setLayout(new BorderLayout());
right.setBorder(BorderFactory.createTitledBorder("Tools"));
right.add(toolsPanel, BorderLayout.CENTER);
panel.add(right);
add(panel, BorderLayout.CENTER);
filePanel.getFileTree().addPropertyChangeListener(FileTree.CONTENT_PROPERTY, fileTreeChangeListener);
addTool(new TypePanel());
addTool(new SplitPanel());
Dimension min = new Dimension(300, 300);
filePanel.setMinimumSize(min);
toolsPanel.setMinimumSize(min);
}
private PropertyChangeListener fileTreeChangeListener = new PropertyChangeListener() {
@SuppressWarnings("unchecked")
public void propertyChange(PropertyChangeEvent evt) {
List<File> files = (List<File>) evt.getNewValue();
for (ToolPanel toolPanel : toolPanels)
toolPanel.update(files);
}
};
private LinkedList<ToolPanel> toolPanels = new LinkedList<ToolPanel>();
public void addTool(ToolPanel toolPanel) {
toolsPanel.addTab(toolPanel.getName(), toolPanel);
toolPanels.add(toolPanel);
}
}

View File

@ -0,0 +1,149 @@
package net.sourceforge.filebot.ui.panel.analyze;
import java.awt.datatransfer.Transferable;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.List;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import net.sourceforge.filebot.ui.FileBotTree;
import net.sourceforge.filebot.ui.sal.FileTransferable;
import net.sourceforge.filebot.ui.transferablepolicies.BackgroundFileTransferablePolicy;
public class FileTree extends FileBotTree {
public static final String LOADING_PROPERTY = "loading";
public static final String CONTENT_PROPERTY = "content";
public FileTree() {
setTransferablePolicy(new FileTreeTransferPolicy());
}
public void removeTreeItems(TreePath paths[]) {
for (TreePath element : paths) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) (element.getLastPathComponent());
node.removeFromParent();
}
updateUI();
firePropertyChange(LOADING_PROPERTY, null, true);
contentChanged();
firePropertyChange(LOADING_PROPERTY, null, false);
}
public void load(List<File> files) {
FileTransferable tr = new FileTransferable(files);
if (getTransferablePolicy().accept(tr))
getTransferablePolicy().handleTransferable(tr, true);
}
private void contentChanged() {
List<File> files = convertToList();
firePropertyChange(CONTENT_PROPERTY, null, files);
}
public void addFiles(DefaultMutableTreeNode parent, File files[]) {
// folders first
for (File f : files)
if (f.isDirectory()) {
// run through file tree
DefaultMutableTreeNode node = new DefaultMutableTreeNode(f);
addFiles(node, f.listFiles());
parent.add(node);
}
for (File f : files) {
if (!f.isDirectory())
parent.add(new DefaultMutableTreeNode(f));
}
}
@Override
public void clear() {
super.clear();
contentChanged();
}
private class FileTreeTransferPolicy extends BackgroundFileTransferablePolicy<Object> implements PropertyChangeListener {
public FileTreeTransferPolicy() {
addPropertyChangeListener(LOADING_PROPERTY, this);
}
@Override
protected boolean accept(File file) {
return file.isFile() || file.isDirectory();
}
@Override
public boolean handleTransferable(Transferable tr, boolean add) {
return super.handleTransferable(tr, true);
}
@Override
protected void clear() {
FileTree.this.clear();
}
@Override
protected boolean load(List<File> files) {
DefaultMutableTreeNode root = (DefaultMutableTreeNode) getModel().getRoot();
File fileArray[] = new File[files.size()];
files.toArray(fileArray);
addFiles(root, fileArray);
return true;
}
/**
* This method will not be used
*/
@Override
protected boolean load(File file) {
return false;
}
public void propertyChange(PropertyChangeEvent evt) {
Boolean loading = (Boolean) evt.getNewValue();
if (loading) {
FileTree.this.firePropertyChange(LOADING_PROPERTY, null, true);
} else {
FileTree.this.firePropertyChange(LOADING_PROPERTY, null, false);
updateUI();
contentChanged();
}
}
@Override
public String getDescription() {
return "files and folders";
}
}
}

View File

@ -0,0 +1,98 @@
package net.sourceforge.filebot.ui.panel.analyze;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.border.EmptyBorder;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.FileBotUtil;
import net.sourceforge.filebot.ui.sal.LoadAction;
import net.sourceforge.tuned.ui.LoadingOverlayPanel;
public class FileTreePanel extends JPanel {
private FileTree fileTree = new FileTree();
private LoadingOverlayPanel loadingOverlay;
public FileTreePanel() {
super(new BorderLayout());
fileTree.addPropertyChangeListener(FileTree.LOADING_PROPERTY, loadingOverlayUpdateListener);
setBorder(BorderFactory.createTitledBorder("File Tree"));
loadingOverlay = new LoadingOverlayPanel(new JScrollPane(fileTree), ResourceManager.getIcon("loading"));
Box buttons = Box.createHorizontalBox();
buttons.setBorder(new EmptyBorder(5, 5, 5, 5));
buttons.add(Box.createGlue());
buttons.add(new JButton(loadAction));
buttons.add(Box.createHorizontalStrut(5));
buttons.add(new JButton(clearAction));
buttons.add(Box.createGlue());
// Shortcut DELETE
FileBotUtil.registerActionForKeystroke(fileTree, KeyStroke.getKeyStroke("pressed DELETE"), removeAction);
add(loadingOverlay, BorderLayout.CENTER);
add(buttons, BorderLayout.SOUTH);
}
private PropertyChangeListener loadingOverlayUpdateListener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
Boolean loading = (Boolean) evt.getNewValue();
loadingOverlay.setOverlayVisible(loading);
loadingOverlay.updateOverlayUI();
}
};
public FileTree getFileTree() {
return fileTree;
}
private final LoadAction loadAction = new LoadAction(fileTree);
private final AbstractAction clearAction = new AbstractAction("Clear", ResourceManager.getIcon("action.clear")) {
public void actionPerformed(ActionEvent e) {
fileTree.clear();
}
};
private final AbstractAction removeAction = new AbstractAction("Remove") {
public void actionPerformed(ActionEvent e) {
if (fileTree.getSelectionCount() < 1)
return;
int row = fileTree.getMinSelectionRow();
fileTree.removeTreeItems(fileTree.getSelectionPaths());
int maxRow = fileTree.getRowCount() - 1;
if (row > maxRow)
row = maxRow;
fileTree.setSelectionRow(row);
}
};
}

View File

@ -0,0 +1,186 @@
package net.sourceforge.filebot.ui.panel.analyze.tools;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.io.File;
import java.util.Collection;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingWorker;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.FileBotTree;
import net.sourceforge.filebot.ui.FileFormat;
import net.sourceforge.tuned.ui.GradientStyle;
import net.sourceforge.tuned.ui.LoadingOverlayPanel;
import net.sourceforge.tuned.ui.notification.SeparatorBorder;
public class SplitPanel extends ToolPanel implements ChangeListener {
private FileBotTree tree = new FileBotTree();
private SpinnerNumberModel spinnerModel = new SpinnerNumberModel(4480, 0, Integer.MAX_VALUE, 100);
public SplitPanel() {
super("Split");
setLayout(new BorderLayout());
JScrollPane sp = new JScrollPane(tree);
sp.setBorder(BorderFactory.createEmptyBorder());
LoadingOverlayPanel loadingOverlay = new LoadingOverlayPanel(sp, ResourceManager.getIcon("loading"));
JSpinner spinner = new JSpinner(spinnerModel);
spinner.setMaximumSize(spinner.getPreferredSize());
spinner.setEditor(new JSpinner.NumberEditor(spinner, "#"));
Box spinnerBox = Box.createHorizontalBox();
spinnerBox.add(Box.createGlue());
spinnerBox.add(new JLabel("Split every"));
spinnerBox.add(Box.createHorizontalStrut(5));
spinnerBox.add(spinner);
spinnerBox.add(Box.createHorizontalStrut(5));
spinnerBox.add(new JLabel("MB."));
spinnerBox.add(Box.createGlue());
add(loadingOverlay, BorderLayout.CENTER);
add(spinnerBox, BorderLayout.SOUTH);
Color beginColor = new Color(0, 0, 0, 90);
SeparatorBorder separatorBorder = new SeparatorBorder(2, beginColor, GradientStyle.TOP_TO_BOTTOM, SeparatorBorder.Position.TOP);
spinnerBox.setBorder(new CompoundBorder(separatorBorder, new EmptyBorder(6, 5, 7, 5)));
setLoadingOverlayPane(loadingOverlay);
spinnerModel.addChangeListener(this);
spinner.setPreferredSize(new Dimension(80, 20));
}
/**
* splitsize change callback
*/
public void stateChanged(ChangeEvent e) {
if (files != null)
update();
}
private long getSplitSize() {
return spinnerModel.getNumber().intValue() * FileFormat.MEGA;
}
private UpdateTask latestUpdateTask;
private Collection<File> files;
@Override
public void update(Collection<File> files) {
this.files = files;
update();
}
private void update() {
latestUpdateTask = new UpdateTask();
firePropertyChange(LOADING_PROPERTY, null, true);
latestUpdateTask.execute();
}
private class UpdateTask extends SwingWorker<DefaultTreeModel, Object> {
private boolean isLatest() {
if (this == latestUpdateTask)
return true;
else
return false;
}
private void setLastChildUserObject(DefaultMutableTreeNode root, int part, long size) {
DefaultMutableTreeNode node = ((DefaultMutableTreeNode) root.getLastChild());
String uo = "Part " + part + " (" + FileFormat.formatSize(size) + ")";
node.setUserObject(uo);
}
@Override
protected DefaultTreeModel doInBackground() throws Exception {
long currentSize = 0;
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
DefaultMutableTreeNode first = new DefaultMutableTreeNode();
root.add(first);
DefaultMutableTreeNode remainder = new DefaultMutableTreeNode("Remainder");
int p = 1;
long splitSize = getSplitSize();
for (File f : files) {
long fileSize = f.length();
DefaultMutableTreeNode fileNode = new DefaultMutableTreeNode(f);
if (fileSize > splitSize)
remainder.add(fileNode);
else if (currentSize + fileSize <= splitSize) {
currentSize += fileSize;
((DefaultMutableTreeNode) root.getLastChild()).add(fileNode);
} else {
setLastChildUserObject(root, p, currentSize);
currentSize = fileSize;
p++;
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
node.add(fileNode);
root.add(node);
}
if (!isLatest())
return null;
}
setLastChildUserObject(root, p, currentSize);
if (!remainder.isLeaf())
root.add(remainder);
if (first.isLeaf())
first.removeFromParent();
return new DefaultTreeModel(root);
}
@Override
protected void done() {
try {
DefaultTreeModel model = get();
if (model == null)
return;
tree.setModel(model);
} catch (Exception e) {
e.printStackTrace();
}
SplitPanel.this.firePropertyChange(LOADING_PROPERTY, null, false);
}
}
}

View File

@ -0,0 +1,55 @@
package net.sourceforge.filebot.ui.panel.analyze.tools;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Collection;
import javax.swing.JComponent;
import net.sourceforge.tuned.ui.LoadingOverlayPanel;
public abstract class ToolPanel extends JComponent {
private String name = null;
private LoadingOverlayPanel loadingOverlay;
public static final String LOADING_PROPERTY = "loading";
public ToolPanel(String name) {
this.name = name;
addPropertyChangeListener(LOADING_PROPERTY, loadingOverlayUpdateListener);
}
@Override
public String getName() {
return name;
}
protected void setLoadingOverlayPane(LoadingOverlayPanel c) {
loadingOverlay = c;
}
private PropertyChangeListener loadingOverlayUpdateListener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
Boolean loading = (Boolean) evt.getNewValue();
if (loadingOverlay == null)
return;
loadingOverlay.setOverlayVisible(loading);
loadingOverlay.updateOverlayUI();
}
};
public abstract void update(Collection<File> list);
}

View File

@ -0,0 +1,134 @@
package net.sourceforge.filebot.ui.panel.analyze.tools;
import java.awt.BorderLayout;
import java.io.File;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.TreeMap;
import javax.swing.BorderFactory;
import javax.swing.JScrollPane;
import javax.swing.SwingWorker;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.FileBotTree;
import net.sourceforge.filebot.ui.FileFormat;
import net.sourceforge.tuned.ui.LoadingOverlayPanel;
public class TypePanel extends ToolPanel {
private FileBotTree tree = new FileBotTree();
public TypePanel() {
super("Types");
setLayout(new BorderLayout());
JScrollPane sp = new JScrollPane(tree);
sp.setBorder(BorderFactory.createEmptyBorder());
LoadingOverlayPanel loadingOverlay = new LoadingOverlayPanel(sp, ResourceManager.getIcon("loading"));
add(loadingOverlay, BorderLayout.CENTER);
setLoadingOverlayPane(loadingOverlay);
}
UpdateTask latestUpdateTask;
@Override
public void update(Collection<File> files) {
latestUpdateTask = new UpdateTask(files);
firePropertyChange(LOADING_PROPERTY, null, true);
latestUpdateTask.execute();
}
private class UpdateTask extends SwingWorker<DefaultTreeModel, Object> {
private Collection<File> files;
public UpdateTask(Collection<File> files) {
this.files = files;
}
private boolean isLatest() {
if (this == latestUpdateTask)
return true;
else
return false;
}
@Override
protected DefaultTreeModel doInBackground() throws Exception {
TreeMap<String, Collection<File>> map = new TreeMap<String, Collection<File>>();
for (File f : files) {
String suffix = FileFormat.getSuffix(f);
Collection<File> list = map.get(suffix);
if (list != null)
list.add(f);
else {
list = new LinkedList<File>();
list.add(f);
map.put(suffix, list);
}
if (!isLatest())
return null;
}
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
Iterator<String> i = map.keySet().iterator();
while (i.hasNext()) {
String key = i.next();
Collection<File> list = map.get(key);
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
long size = 0;
for (File f : list) {
node.add(new DefaultMutableTreeNode(f));
size += f.length();
}
node.setUserObject(key + " (" + FileFormat.formatNumberOfFiles(list.size()) + ", " + FileFormat.formatSize(size) + ")");
root.add(node);
if (!isLatest())
return null;
}
return new DefaultTreeModel(root);
}
@Override
protected void done() {
try {
DefaultTreeModel model = get();
if (model == null)
return;
tree.setModel(model);
} catch (Exception e) {
e.printStackTrace();
}
TypePanel.this.firePropertyChange(LOADING_PROPERTY, null, false);
}
}
}

View File

@ -0,0 +1,33 @@
package net.sourceforge.filebot.ui.panel.create;
import java.awt.BorderLayout;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.border.EmptyBorder;
import net.sourceforge.filebot.ui.FileBotList;
import net.sourceforge.filebot.ui.sal.SaveAction;
public class CreateList extends FileBotList {
private SaveAction saveAction = new SaveAction(this);
public CreateList() {
super(false, true, true);
setTitle("List");
Box buttons = Box.createHorizontalBox();
buttons.setBorder(new EmptyBorder(5, 5, 5, 5));
buttons.add(Box.createGlue());
buttons.add(new JButton(saveAction));
buttons.add(Box.createGlue());
add(buttons, BorderLayout.SOUTH);
}
}

View File

@ -0,0 +1,108 @@
package net.sourceforge.filebot.ui.panel.create;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.text.NumberFormat;
import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.EmptyBorder;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.FileBotPanel;
import net.sourceforge.filebot.ui.FileBotUtil;
public class CreatePanel extends FileBotPanel {
private SpinnerNumberModel fromSpinnerModel = new SpinnerNumberModel(1, 1, Integer.MAX_VALUE, 1);
private SpinnerNumberModel toSpinnerModel = new SpinnerNumberModel(20, 1, Integer.MAX_VALUE, 1);
private CreateList list = new CreateList();
private JTextField textField = new JTextField("Name - $i", 25);
public CreatePanel() {
super("Create", ResourceManager.getIcon("panel.create"));
JSpinner fromSpinner = new JSpinner(fromSpinnerModel);
JSpinner toSpinner = new JSpinner(toSpinnerModel);
fromSpinner.setEditor(new JSpinner.NumberEditor(fromSpinner, "#"));
toSpinner.setEditor(new JSpinner.NumberEditor(toSpinner, "#"));
Dimension spinnerDimension = new Dimension(50, textField.getPreferredSize().height);
fromSpinner.setPreferredSize(spinnerDimension);
toSpinner.setPreferredSize(spinnerDimension);
Box spinners = Box.createHorizontalBox();
spinners.setBorder(new EmptyBorder(5, 5, 5, 5));
spinners.add(Box.createHorizontalGlue());
spinners.add(createLabeledComponent("Pattern:", textField));
spinners.add(Box.createHorizontalStrut(15));
spinners.add(createLabeledComponent("From:", fromSpinner));
spinners.add(Box.createHorizontalStrut(10));
spinners.add(createLabeledComponent("To:", toSpinner));
spinners.add(Box.createHorizontalStrut(15));
spinners.add(new JButton(createAction));
spinners.add(Box.createHorizontalGlue());
JPanel panel = new JPanel(new BorderLayout());
panel.add(spinners, BorderLayout.NORTH);
panel.add(list, BorderLayout.CENTER);
add(panel, BorderLayout.CENTER);
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("ENTER"), createAction);
}
private JComponent createLabeledComponent(String label, JComponent component) {
Box box = Box.createHorizontalBox();
box.setBorder(new EmptyBorder(5, 5, 5, 5));
box.add(new JLabel(label));
box.add(Box.createHorizontalStrut(6));
box.add(component);
box.setMaximumSize(box.getPreferredSize());
return box;
}
private AbstractAction createAction = new AbstractAction("Create") {
public void actionPerformed(ActionEvent e) {
list.getModel().clear();
int from = fromSpinnerModel.getNumber().intValue();
int to = toSpinnerModel.getNumber().intValue();
NumberFormat format = NumberFormat.getInstance();
format.setGroupingUsed(false);
format.setMinimumIntegerDigits(Math.max(Integer.toString(to).length(), 2));
String pattern = textField.getText();
for (int i = from; i <= to; i++) {
String s = pattern.replaceAll("\\$i", format.format(i));
list.getModel().addElement(s);
}
}
};
}

View File

@ -0,0 +1,42 @@
package net.sourceforge.filebot.ui.panel.list;
import java.awt.BorderLayout;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.border.EmptyBorder;
import net.sourceforge.filebot.ui.FileBotList;
import net.sourceforge.filebot.ui.sal.LoadAction;
import net.sourceforge.filebot.ui.sal.SaveAction;
public class FileList extends FileBotList {
private SaveAction saveAction = new SaveAction(this);
private LoadAction loadAction = new LoadAction(this);
public FileList() {
super(true, true, true);
setTransferablePolicy(new FileListTransferablePolicy(this));
setTitle("Folder");
Box buttons = Box.createHorizontalBox();
buttons.setBorder(new EmptyBorder(5, 5, 5, 5));
buttons.add(Box.createHorizontalGlue());
buttons.add(new JButton(loadAction));
buttons.add(Box.createHorizontalStrut(5));
buttons.add(new JButton(saveAction));
buttons.add(Box.createHorizontalGlue());
add(buttons, BorderLayout.SOUTH);
}
}

Some files were not shown because too many files have changed in this diff Show More