aboutsummaryrefslogtreecommitdiffstats
path: root/netx/net/sourceforge/jnlp/controlpanel/CachePane.java
diff options
context:
space:
mode:
Diffstat (limited to 'netx/net/sourceforge/jnlp/controlpanel/CachePane.java')
-rw-r--r--netx/net/sourceforge/jnlp/controlpanel/CachePane.java328
1 files changed, 225 insertions, 103 deletions
diff --git a/netx/net/sourceforge/jnlp/controlpanel/CachePane.java b/netx/net/sourceforge/jnlp/controlpanel/CachePane.java
index 502cf8a..d5bb267 100644
--- a/netx/net/sourceforge/jnlp/controlpanel/CachePane.java
+++ b/netx/net/sourceforge/jnlp/controlpanel/CachePane.java
@@ -1,5 +1,5 @@
/* CachePane.java -- Displays the specified folder and allows modification to its content.
-Copyright (C) 2010 Red Hat
+Copyright (C) 2013 Red Hat
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
@@ -19,22 +19,27 @@ package net.sourceforge.jnlp.controlpanel;
import java.awt.BorderLayout;
import java.awt.Component;
+import java.awt.Cursor;
import java.awt.Dimension;
+import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
+import java.awt.SystemColor;
+import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.channels.FileLock;
import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
+import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Comparator;
+import java.util.Date;
import java.util.Enumeration;
import java.util.List;
@@ -45,7 +50,10 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
-import javax.swing.table.DefaultTableModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import net.sourceforge.jnlp.cache.CacheDirectory;
@@ -54,23 +62,25 @@ import net.sourceforge.jnlp.cache.DirectoryNode;
import net.sourceforge.jnlp.config.DeploymentConfiguration;
import net.sourceforge.jnlp.runtime.Translator;
import net.sourceforge.jnlp.util.FileUtils;
-import net.sourceforge.jnlp.util.logging.OutputController;
import net.sourceforge.jnlp.util.PropertiesFile;
+import net.sourceforge.jnlp.util.logging.OutputController;
+import net.sourceforge.jnlp.util.ui.NonEditableTableModel;
public class CachePane extends JPanel {
-
JDialog parent;
DeploymentConfiguration config;
private String location;
private JComponent defaultFocusComponent;
DirectoryNode root;
- String[] columns = { Translator.R("CVCPColName"),
+ String[] columns = {
+ Translator.R("CVCPColName"),
Translator.R("CVCPColPath"),
Translator.R("CVCPColType"),
Translator.R("CVCPColDomain"),
Translator.R("CVCPColSize"),
Translator.R("CVCPColLastModified") };
JTable cacheTable;
+ private JButton deleteButton, refreshButton, doneButton;
/**
* Creates a new instance of the CachePane.
@@ -95,42 +105,64 @@ public class CachePane extends JPanel {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
- DefaultTableModel model = new DefaultTableModel(columns, 0) {
- public boolean isCellEditable(int row, int column) {
- return false;
- }
- };
+ TableModel model = new NonEditableTableModel(columns, 0);
cacheTable = new JTable(model);
cacheTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ cacheTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ final public void valueChanged(ListSelectionEvent listSelectionEvent) {
+ // If no row has been selected, disable the delete button, else enable it
+ if (cacheTable.getSelectionModel().isSelectionEmpty())
+ // Disable delete button, since nothing selected
+ deleteButton.setEnabled(false);
+ else
+ // Enable delete button, since something selected
+ deleteButton.setEnabled(true);
+ }
+ });
cacheTable.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
cacheTable.setPreferredScrollableViewportSize(new Dimension(600, 200));
cacheTable.setFillsViewportHeight(true);
JScrollPane scrollPane = new JScrollPane(cacheTable);
- populateTable();
-
- TableRowSorter<DefaultTableModel> tableSorter = new TableRowSorter<DefaultTableModel>(model);
- tableSorter.setComparator(4, new Comparator<Long>() { // Comparator for size column.
- @Override
- public int compare(Long o1, Long o2) {
- return o1.compareTo(o2);
+ TableRowSorter<TableModel> tableSorter = new TableRowSorter<TableModel>(model);
+ final Comparator comparator = new Comparator<Comparable>() { // General purpose Comparator
+ public final int compare(final Comparable a, final Comparable b) {
+ return a.compareTo(b);
}
- });
- tableSorter.setComparator(5, new Comparator<String>() { // Comparator for date column.
+ };
+ tableSorter.setComparator(1, comparator); // Comparator for path column.
+ tableSorter.setComparator(4, comparator); // Comparator for size column.
+ tableSorter.setComparator(5, comparator); // Comparator for modified column.
+ cacheTable.setRowSorter(tableSorter);
+ final DefaultTableCellRenderer tableCellRenderer = new DefaultTableCellRenderer() {
@Override
- public int compare(String o1, String o2) {
- DateFormat format = new SimpleDateFormat("MM/dd/yyyy");
- try {
- Long time1 = format.parse(o1).getTime();
- Long time2 = format.parse(o2).getTime();
- return time1.compareTo(time2);
- } catch (ParseException e) {
- return 0;
+ public final Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) {
+ super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+
+ switch (column) {
+ case 1: // Path column
+ // Render absolute path
+ super.setText(((File)value).getAbsolutePath());
+ break;
+ case 4: // Size column
+ // Render size formatted to default locale's number format
+ super.setText(NumberFormat.getInstance().format(value));
+ break;
+ case 5: // last modified column
+ // Render modify date formatted to default locale's date format
+ super.setText(DateFormat.getDateInstance().format(value));
}
+
+ return this;
}
- });
- cacheTable.setRowSorter(tableSorter);
+ };
+ // TableCellRenderer for path column
+ cacheTable.getColumn(this.columns[1]).setCellRenderer(tableCellRenderer);
+ // TableCellRenderer for size column
+ cacheTable.getColumn(this.columns[4]).setCellRenderer(tableCellRenderer);
+ // TableCellRenderer for last modified column
+ cacheTable.getColumn(this.columns[5]).setCellRenderer(tableCellRenderer);
c.weightx = 1;
c.weighty = 1;
@@ -139,7 +171,6 @@ public class CachePane extends JPanel {
topPanel.add(scrollPane, c);
this.add(topPanel, BorderLayout.CENTER);
this.add(createButtonPanel(), BorderLayout.SOUTH);
-
}
/**
@@ -154,85 +185,45 @@ public class CachePane extends JPanel {
List<JButton> buttons = new ArrayList<JButton>();
- JButton deleteButton = new JButton(Translator.R("CVCPButDelete"));
+ this.deleteButton = new JButton(Translator.R("CVCPButDelete"));
deleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- FileLock fl = null;
- File netxRunningFile = new File(config.getProperty(DeploymentConfiguration.KEY_USER_NETX_RUNNING_FILE));
- if (!netxRunningFile.exists()) {
- try {
- FileUtils.createParentDir(netxRunningFile);
- FileUtils.createRestrictedFile(netxRunningFile, true);
- } catch (IOException e1) {
- OutputController.getLogger().log(OutputController.Level.ERROR_ALL, e1);
- }
- }
-
- try {
- fl = FileUtils.getFileLock(netxRunningFile.getPath(), false, false);
- } catch (FileNotFoundException e1) {
- }
-
- int row = cacheTable.getSelectedRow();
- try {
- if (fl == null) return;
- if (row == -1 || row > cacheTable.getRowCount() - 1)
- return;
- int modelRow = cacheTable.convertRowIndexToModel(row);
- DirectoryNode fileNode = ((DirectoryNode) cacheTable.getModel().getValueAt(modelRow, 0));
- if (fileNode.getFile().delete()) {
- updateRecentlyUsed(fileNode.getFile());
- fileNode.getParent().removeChild(fileNode);
- FileUtils.deleteWithErrMesg(fileNode.getInfoFile());
- ((DefaultTableModel) cacheTable.getModel()).removeRow(modelRow);
- cacheTable.getSelectionModel().setSelectionInterval(row, row);
- CacheDirectory.cleanParent(fileNode);
- }
- } catch (Exception exception) {
- //ignore
- }
-
- if (fl != null) {
- try {
- fl.release();
- fl.channel().close();
- } catch (IOException e1) {
- OutputController.getLogger().log(OutputController.Level.ERROR_ALL, e1);
- }
- }
- }
-
- private void updateRecentlyUsed(File f) {
- File recentlyUsedFile = new File(location + File.separator + CacheLRUWrapper.CACHE_INDEX_FILE_NAME);
- PropertiesFile pf = new PropertiesFile(recentlyUsedFile);
- pf.load();
- Enumeration<Object> en = pf.keys();
- while (en.hasMoreElements()) {
- String key = (String) en.nextElement();
- if (pf.get(key).equals(f.getAbsolutePath())) {
- pf.remove(key);
- }
- }
- pf.store();
+ // Deleting may take a while, so indicate busy by cursor
+ parent.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ // Disable dialog and buttons while deleting
+ deleteButton.setEnabled(false);
+ refreshButton.setEnabled(false);
+ doneButton.setEnabled(false);
+ // Delete on AWT thread after this action has been performed
+ // in order to allow the cache viewer to update itself
+ invokeLaterDelete();
}
});
+ deleteButton.setEnabled(false);
buttons.add(deleteButton);
- JButton refreshButton = new JButton(Translator.R("CVCPButRefresh"));
+ this.refreshButton = new JButton(Translator.R("CVCPButRefresh"));
refreshButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- populateTable();
+ // Disable all its controls when performing cacheTable refresh (populating)
+ deleteButton.setEnabled(false);
+ refreshButton.setEnabled(false);
+ doneButton.setEnabled(false);
+ // Populate cacheTable on AWT thread after this action event has been performed
+ invokeLaterPopulateTable();
}
});
+ refreshButton.setEnabled(false);
buttons.add(refreshButton);
- JButton doneButton = new JButton(Translator.R("ButDone"));
+ this.doneButton = new JButton(Translator.R("ButDone"));
doneButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- parent.dispose();
+ Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(
+ new WindowEvent(parent, WindowEvent.WINDOW_CLOSING));
}
});
@@ -251,6 +242,7 @@ public class CachePane extends JPanel {
}
doneButton.setPreferredSize(new Dimension(wantedWidth, wantedHeight));
+ doneButton.setEnabled(false);
rightPanel.add(doneButton);
buttonPanel.add(leftPanel);
buttonPanel.add(rightPanel);
@@ -259,13 +251,140 @@ public class CachePane extends JPanel {
}
/**
+ * Posts an event to the event queue to delete the currently selected
+ * resource in {@link CachePane#cacheTable} after the {@code CachePane} and
+ * {@link CacheViewer} have been instantiated and painted.
+ * @see CachePane#cacheTable
+ */
+ private final void invokeLaterDelete() {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ try {
+ FileLock fl = null;
+ File netxRunningFile = new File(config.getProperty(DeploymentConfiguration.KEY_USER_NETX_RUNNING_FILE));
+ if (!netxRunningFile.exists()) {
+ try {
+ FileUtils.createParentDir(netxRunningFile);
+ FileUtils.createRestrictedFile(netxRunningFile, true);
+ } catch (IOException e1) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL, e1);
+ }
+ }
+
+ try {
+ fl = FileUtils.getFileLock(netxRunningFile.getPath(), false, false);
+ } catch (FileNotFoundException e1) {
+ }
+
+ int row = cacheTable.getSelectedRow();
+ try {
+ if (fl == null) return;
+ int modelRow = cacheTable.convertRowIndexToModel(row);
+ DirectoryNode fileNode = ((DirectoryNode) cacheTable.getModel().getValueAt(modelRow, 0));
+ if (fileNode.getFile().delete()) {
+ updateRecentlyUsed(fileNode.getFile());
+ fileNode.getParent().removeChild(fileNode);
+ FileUtils.deleteWithErrMesg(fileNode.getInfoFile());
+ ((NonEditableTableModel) cacheTable.getModel()).removeRow(modelRow);
+ cacheTable.getSelectionModel().clearSelection();
+ CacheDirectory.cleanParent(fileNode);
+ }
+ } catch (Exception exception) {
+ // ignore
+ }
+
+ if (fl != null) {
+ try {
+ fl.release();
+ fl.channel().close();
+ } catch (IOException e1) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_ALL, e1);
+ }
+ }
+ } catch (Exception exception) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, exception);
+ } finally {
+ // If nothing selected then keep deleteButton disabled
+ if (!cacheTable.getSelectionModel().isSelectionEmpty()) deleteButton.setEnabled(true);
+ // Enable buttons
+ refreshButton.setEnabled(true);
+ doneButton.setEnabled(true);
+ // If cacheTable is empty disable it and set background
+ // color to indicate being disabled
+ if (cacheTable.getModel().getRowCount() == 0) {
+ cacheTable.setEnabled(false);
+ cacheTable.setBackground(SystemColor.control);
+ }
+ // Reset cursor
+ parent.getContentPane().setCursor(Cursor.getDefaultCursor());
+ }
+ }
+
+ private void updateRecentlyUsed(File f) {
+ File recentlyUsedFile = new File(location + File.separator + CacheLRUWrapper.CACHE_INDEX_FILE_NAME);
+ PropertiesFile pf = new PropertiesFile(recentlyUsedFile);
+ pf.load();
+ Enumeration<Object> en = pf.keys();
+ while (en.hasMoreElements()) {
+ String key = (String) en.nextElement();
+ if (pf.get(key).equals(f.getAbsolutePath())) {
+ pf.remove(key);
+ }
+ }
+ pf.store();
+ }
+ });
+ }
+
+ /**
+ * Posts an event to the event queue to populate the
+ * {@link CachePane#cacheTable} after the {@code CachePane} and
+ * {@link CacheViewer} have been instantiated and painted.
+ * @see CachePane#populateTable
+ */
+ final void invokeLaterPopulateTable() {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ try {
+ populateTable();
+ // Disable cacheTable when no data to display, so no events are generated
+ if (cacheTable.getModel().getRowCount() == 0) {
+ cacheTable.setEnabled(false);
+ cacheTable.setBackground(SystemColor.control);
+ // No data in cacheTable, so nothing to delete
+ deleteButton.setEnabled(false);
+ } else {
+ cacheTable.setEnabled(true);
+ cacheTable.setBackground(SystemColor.text);
+ }
+ } catch (Exception exception) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, exception);
+ } finally {
+ refreshButton.setEnabled(true);
+ doneButton.setEnabled(true);
+ }
+ }
+ });
+ }
+
+ /**
* Populate the table with fresh data. Any manual updates to the cache
* directory will be updated in the table.
*/
private void populateTable() {
- ((DefaultTableModel) cacheTable.getModel()).setRowCount(0); //Clears the table
- for (Object[] v : generateData(root))
- ((DefaultTableModel) cacheTable.getModel()).addRow(v);
+ try {
+ // Populating the cacheTable may take a while, so indicate busy by cursor
+ parent.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+
+ NonEditableTableModel tableModel;
+ (tableModel = (NonEditableTableModel)cacheTable.getModel()).setRowCount(0); //Clears the table
+ for (Object[] v : generateData(root)) tableModel.addRow(v);
+ } catch (Exception exception) {
+ OutputController.getLogger().log(OutputController.Level.ERROR_DEBUG, exception);
+ } finally {
+ // Reset cursor
+ parent.getContentPane().setCursor(Cursor.getDefaultCursor());
+ }
}
/**
@@ -283,12 +402,15 @@ public class CachePane extends JPanel {
for (DirectoryNode type : identifier.getChildren()) {
for (DirectoryNode domain : type.getChildren()) {
for (DirectoryNode leaf : CacheDirectory.getLeafData(domain)) {
- Object[] o = { leaf,
- leaf.getFile().getAbsolutePath(),
- type,
- domain,
- leaf.getFile().length(),
- new SimpleDateFormat("MM/dd/yyyy").format(leaf.getFile().lastModified()) };
+ final File f = leaf.getFile();
+ Object[] o = {
+ leaf,
+ f.getParentFile(),
+ type,
+ domain,
+ f.length(),
+ new Date(f.lastModified())
+ };
data.add(o);
}
}