UI Tweaks: save/load history, auto-scrolling logs
This commit is contained in:
parent
55e58b542d
commit
2d49cb2b7b
@ -177,6 +177,19 @@ public abstract class AbstractRipper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void downloadProblem(URL url, String message) {
|
||||||
|
if (observer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronized(observer) {
|
||||||
|
itemsPending.remove(url);
|
||||||
|
itemsErrored.put(url, message);
|
||||||
|
observer.update(this, new RipStatusMessage(STATUS.DOWNLOAD_WARN, url + " : " + message));
|
||||||
|
observer.notifyAll();
|
||||||
|
checkIfComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void checkIfComplete() {
|
private void checkIfComplete() {
|
||||||
if (!completed && itemsPending.size() == 0) {
|
if (!completed && itemsPending.size() == 0) {
|
||||||
completed = true;
|
completed = true;
|
||||||
@ -275,4 +288,5 @@ public abstract class AbstractRipper
|
|||||||
logger.error("Got exception while running ripper:", e);
|
logger.error("Got exception while running ripper:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -39,7 +39,7 @@ public class DownloadFileThread extends Thread {
|
|||||||
saveAs.delete();
|
saveAs.delete();
|
||||||
} else {
|
} else {
|
||||||
logger.info("[!] Skipping " + url + " -- file already exists: " + prettySaveAs);
|
logger.info("[!] Skipping " + url + " -- file already exists: " + prettySaveAs);
|
||||||
observer.downloadErrored(url, "File already exists: " + prettySaveAs);
|
observer.downloadProblem(url, "File already exists: " + prettySaveAs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,18 @@ import java.awt.GridBagConstraints;
|
|||||||
import java.awt.GridBagLayout;
|
import java.awt.GridBagLayout;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import javax.swing.DefaultListModel;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
@ -22,9 +29,9 @@ import javax.swing.JProgressBar;
|
|||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
import javax.swing.JTextPane;
|
import javax.swing.JTextPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import javax.swing.text.BadLocationException;
|
import javax.swing.text.BadLocationException;
|
||||||
import javax.swing.text.DefaultCaret;
|
|
||||||
import javax.swing.text.SimpleAttributeSet;
|
import javax.swing.text.SimpleAttributeSet;
|
||||||
import javax.swing.text.StyleConstants;
|
import javax.swing.text.StyleConstants;
|
||||||
import javax.swing.text.StyledDocument;
|
import javax.swing.text.StyledDocument;
|
||||||
@ -39,6 +46,7 @@ public class MainWindow implements Runnable {
|
|||||||
private static final Logger logger = Logger.getLogger(MainWindow.class);
|
private static final Logger logger = Logger.getLogger(MainWindow.class);
|
||||||
|
|
||||||
private static final String WINDOW_TITLE = "RipMe";
|
private static final String WINDOW_TITLE = "RipMe";
|
||||||
|
private static final String HISTORY_FILE = ".history";
|
||||||
|
|
||||||
private static JFrame mainFrame;
|
private static JFrame mainFrame;
|
||||||
private static JTextField ripTextfield;
|
private static JTextField ripTextfield;
|
||||||
@ -58,7 +66,11 @@ public class MainWindow implements Runnable {
|
|||||||
private static JButton optionHistory;
|
private static JButton optionHistory;
|
||||||
private static JPanel historyPanel;
|
private static JPanel historyPanel;
|
||||||
private static JList historyList;
|
private static JList historyList;
|
||||||
|
private static DefaultListModel historyListModel;
|
||||||
private static JScrollPane historyListScroll;
|
private static JScrollPane historyListScroll;
|
||||||
|
private static JButton historyButtonRemove,
|
||||||
|
historyButtonClear,
|
||||||
|
historyButtonRerip;
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
private static JButton optionConfiguration;
|
private static JButton optionConfiguration;
|
||||||
@ -73,6 +85,7 @@ public class MainWindow implements Runnable {
|
|||||||
mainFrame.setLayout(new GridBagLayout());
|
mainFrame.setLayout(new GridBagLayout());
|
||||||
|
|
||||||
createUI(mainFrame.getContentPane());
|
createUI(mainFrame.getContentPane());
|
||||||
|
loadHistory();
|
||||||
setupHandlers();
|
setupHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,15 +108,13 @@ public class MainWindow implements Runnable {
|
|||||||
gbc.weighty = 2; gbc.ipady = 2; gbc.gridy = 0;
|
gbc.weighty = 2; gbc.ipady = 2; gbc.gridy = 0;
|
||||||
|
|
||||||
ripTextfield = new JTextField("", 20);
|
ripTextfield = new JTextField("", 20);
|
||||||
ripButton = new JButton("rip");
|
ripButton = new JButton("Rip");
|
||||||
JPanel ripPanel = new JPanel(new GridBagLayout());
|
JPanel ripPanel = new JPanel(new GridBagLayout());
|
||||||
ripPanel.setBorder(emptyBorder);
|
ripPanel.setBorder(emptyBorder);
|
||||||
|
|
||||||
ripPanel.add(new JLabel("URL:", JLabel.RIGHT), gbc);
|
gbc.gridx = 0; ripPanel.add(new JLabel("URL:", JLabel.RIGHT), gbc);
|
||||||
gbc.gridx = 1;
|
gbc.gridx = 1; ripPanel.add(ripTextfield, gbc);
|
||||||
ripPanel.add(ripTextfield, gbc);
|
gbc.gridx = 2; ripPanel.add(ripButton, gbc);
|
||||||
gbc.gridx = 2;
|
|
||||||
ripPanel.add(ripButton, gbc);
|
|
||||||
|
|
||||||
statusLabel = new JLabel("Inactive");
|
statusLabel = new JLabel("Inactive");
|
||||||
statusLabel.setHorizontalAlignment(JLabel.CENTER);
|
statusLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||||
@ -126,12 +137,9 @@ public class MainWindow implements Runnable {
|
|||||||
optionLog = new JButton("Log");
|
optionLog = new JButton("Log");
|
||||||
optionHistory = new JButton("History");
|
optionHistory = new JButton("History");
|
||||||
optionConfiguration = new JButton("Configuration");
|
optionConfiguration = new JButton("Configuration");
|
||||||
gbc.gridx = 0;
|
gbc.gridx = 0; optionsPanel.add(optionLog, gbc);
|
||||||
optionsPanel.add(optionLog, gbc);
|
gbc.gridx = 1; optionsPanel.add(optionHistory, gbc);
|
||||||
gbc.gridx = 1;
|
gbc.gridx = 2; optionsPanel.add(optionConfiguration, gbc);
|
||||||
optionsPanel.add(optionHistory, gbc);
|
|
||||||
gbc.gridx = 2;
|
|
||||||
optionsPanel.add(optionConfiguration, gbc);
|
|
||||||
|
|
||||||
logPanel = new JPanel(new GridBagLayout());
|
logPanel = new JPanel(new GridBagLayout());
|
||||||
logPanel.setBorder(emptyBorder);
|
logPanel.setBorder(emptyBorder);
|
||||||
@ -140,16 +148,26 @@ public class MainWindow implements Runnable {
|
|||||||
logPanel.setVisible(false);
|
logPanel.setVisible(false);
|
||||||
logPanel.setPreferredSize(new Dimension(300, 300));
|
logPanel.setPreferredSize(new Dimension(300, 300));
|
||||||
logPanel.add(logTextScroll, gbc);
|
logPanel.add(logTextScroll, gbc);
|
||||||
DefaultCaret caret = (DefaultCaret) logText.getCaret();
|
|
||||||
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
|
|
||||||
|
|
||||||
historyPanel = new JPanel(new GridBagLayout());
|
historyPanel = new JPanel(new GridBagLayout());
|
||||||
historyPanel.setBorder(emptyBorder);
|
historyPanel.setBorder(emptyBorder);
|
||||||
historyList = new JList();
|
|
||||||
historyListScroll = new JScrollPane(historyList);
|
|
||||||
historyPanel.setVisible(false);
|
historyPanel.setVisible(false);
|
||||||
historyPanel.setPreferredSize(new Dimension(300, 300));
|
historyPanel.setPreferredSize(new Dimension(300, 300));
|
||||||
|
historyListModel = new DefaultListModel();
|
||||||
|
historyList = new JList(historyListModel);
|
||||||
|
historyListScroll = new JScrollPane(historyList);
|
||||||
|
historyButtonRemove = new JButton("Remove");
|
||||||
|
historyButtonClear = new JButton("Clear");
|
||||||
|
historyButtonRerip = new JButton("Re-rip All");
|
||||||
|
gbc.gridx = 0;
|
||||||
historyPanel.add(historyListScroll, gbc);
|
historyPanel.add(historyListScroll, gbc);
|
||||||
|
JPanel historyButtonPanel = new JPanel(new GridBagLayout());
|
||||||
|
historyButtonPanel.setBorder(emptyBorder);
|
||||||
|
gbc.gridx = 0; historyButtonPanel.add(historyButtonRemove, gbc);
|
||||||
|
gbc.gridx = 1; historyButtonPanel.add(historyButtonClear, gbc);
|
||||||
|
gbc.gridx = 2; historyButtonPanel.add(historyButtonRerip, gbc);
|
||||||
|
gbc.gridy = 1; gbc.gridx = 0;
|
||||||
|
historyPanel.add(historyButtonPanel, gbc);
|
||||||
|
|
||||||
configurationPanel = new JPanel(new GridBagLayout());
|
configurationPanel = new JPanel(new GridBagLayout());
|
||||||
configurationPanel.setBorder(emptyBorder);
|
configurationPanel.setBorder(emptyBorder);
|
||||||
@ -157,19 +175,13 @@ public class MainWindow implements Runnable {
|
|||||||
configurationPanel.setPreferredSize(new Dimension(300, 300));
|
configurationPanel.setPreferredSize(new Dimension(300, 300));
|
||||||
// TODO Configuration components
|
// TODO Configuration components
|
||||||
|
|
||||||
pane.add(ripPanel, gbc);
|
gbc.gridy = 0; pane.add(ripPanel, gbc);
|
||||||
gbc.gridy = 1;
|
gbc.gridy = 1; pane.add(statusPanel, gbc);
|
||||||
pane.add(statusPanel, gbc);
|
gbc.gridy = 2; pane.add(progressPanel, gbc);
|
||||||
gbc.gridy = 2;
|
gbc.gridy = 3; pane.add(optionsPanel, gbc);
|
||||||
pane.add(progressPanel, gbc);
|
gbc.gridy = 4; pane.add(logPanel, gbc);
|
||||||
gbc.gridy = 3;
|
gbc.gridy = 5; pane.add(historyPanel, gbc);
|
||||||
pane.add(optionsPanel, gbc);
|
gbc.gridy = 5; pane.add(configurationPanel, gbc);
|
||||||
gbc.gridy = 4;
|
|
||||||
pane.add(logPanel, gbc);
|
|
||||||
gbc.gridy = 5;
|
|
||||||
pane.add(historyPanel, gbc);
|
|
||||||
gbc.gridy = 5;
|
|
||||||
pane.add(configurationPanel, gbc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupHandlers() {
|
private void setupHandlers() {
|
||||||
@ -203,20 +215,75 @@ public class MainWindow implements Runnable {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendLog(String text, Color color) {
|
private void appendLog(final String text, final Color color) {
|
||||||
SimpleAttributeSet sas = new SimpleAttributeSet();
|
try {
|
||||||
StyleConstants.setForeground(sas, color);
|
SwingUtilities.invokeAndWait(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
SimpleAttributeSet sas = new SimpleAttributeSet();
|
||||||
|
StyleConstants.setForeground(sas, color);
|
||||||
|
StyledDocument sd = logText.getStyledDocument();
|
||||||
|
try {
|
||||||
|
sd.insertString(sd.getLength(), text + "\n", sas);
|
||||||
|
} catch (BadLocationException e) { }
|
||||||
|
logText.setCaretPosition(logText.getText().length());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
StyledDocument sd = logText.getStyledDocument();
|
private void loadHistory() {
|
||||||
|
File f; FileReader fr = null; BufferedReader br;
|
||||||
try {
|
try {
|
||||||
sd.insertString(sd.getLength(), text + "\n", sas);
|
f = new File(HISTORY_FILE);
|
||||||
} catch (BadLocationException e) {
|
fr = new FileReader(f);
|
||||||
e.printStackTrace();
|
br = new BufferedReader(fr);
|
||||||
|
String line;
|
||||||
|
while ( (line = br.readLine()) != null ) {
|
||||||
|
historyListModel.addElement(line);
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
// Do nothing
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("[!] Error while loading history file " + HISTORY_FILE, e);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (fr != null) {
|
||||||
|
fr.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveHistory() {
|
||||||
|
FileWriter fw = null;
|
||||||
|
try {
|
||||||
|
fw = new FileWriter(HISTORY_FILE, false);
|
||||||
|
for (int i = 0; i < historyListModel.size(); i++) {
|
||||||
|
fw.write( (String) historyListModel.get(i) );
|
||||||
|
fw.write("\n");
|
||||||
|
fw.flush();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("[!] Error while saving history file " + HISTORY_FILE, e);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (fw != null) {
|
||||||
|
fw.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RipButtonHandler implements ActionListener {
|
class RipButtonHandler implements ActionListener {
|
||||||
public void actionPerformed(ActionEvent event) {
|
public void actionPerformed(ActionEvent event) {
|
||||||
|
ripButton.setEnabled(false);
|
||||||
|
ripTextfield.setEnabled(false);
|
||||||
|
statusProgress.setValue(100);
|
||||||
openButton.setVisible(false);
|
openButton.setVisible(false);
|
||||||
statusLabel.setVisible(true);
|
statusLabel.setVisible(true);
|
||||||
mainFrame.pack();
|
mainFrame.pack();
|
||||||
@ -227,6 +294,7 @@ public class MainWindow implements Runnable {
|
|||||||
Thread t = new Thread(ripper);
|
Thread t = new Thread(ripper);
|
||||||
t.start();
|
t.start();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
logger.error("[!] Error while ripping: " + e.getMessage(), e);
|
||||||
status("Error: " + e.getMessage());
|
status("Error: " + e.getMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -253,7 +321,15 @@ public class MainWindow implements Runnable {
|
|||||||
appendLog( "Error: " + (String) msg.getObject(), Color.RED);
|
appendLog( "Error: " + (String) msg.getObject(), Color.RED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DOWNLOAD_WARN:
|
||||||
|
appendLog( "Warn: " + (String) msg.getObject(), Color.ORANGE);
|
||||||
|
break;
|
||||||
|
|
||||||
case RIP_COMPLETE:
|
case RIP_COMPLETE:
|
||||||
|
historyListModel.addElement(ripTextfield.getText());
|
||||||
|
saveHistory();
|
||||||
|
ripButton.setEnabled(true);
|
||||||
|
ripTextfield.setEnabled(true);
|
||||||
statusProgress.setValue(100);
|
statusProgress.setValue(100);
|
||||||
statusLabel.setVisible(false);
|
statusLabel.setVisible(false);
|
||||||
openButton.setVisible(true);
|
openButton.setVisible(true);
|
||||||
|
@ -7,7 +7,8 @@ public class RipStatusMessage {
|
|||||||
DOWNLOAD_STARTED("Download Started"),
|
DOWNLOAD_STARTED("Download Started"),
|
||||||
DOWNLOAD_COMPLETE("Download Complete"),
|
DOWNLOAD_COMPLETE("Download Complete"),
|
||||||
DOWNLOAD_ERRORED("Download Errored"),
|
DOWNLOAD_ERRORED("Download Errored"),
|
||||||
RIP_COMPLETE("Rip Complete");
|
RIP_COMPLETE("Rip Complete"),
|
||||||
|
DOWNLOAD_WARN("Download problem");
|
||||||
|
|
||||||
String value;
|
String value;
|
||||||
STATUS(String value) {
|
STATUS(String value) {
|
||||||
|
Loading…
Reference in New Issue
Block a user