[rfc][icedtea-web] Cache viewer cleanup
Jiri Vanek
jvanek at redhat.com
Fri Sep 6 03:22:19 PDT 2013
On 07/31/2013 01:47 AM, Jacob Wisor wrote:
> Hello,
>
> * Added closing of cache viewer by ESC key
> * Added proper dis-/enabling of cache viewer's buttons
> * Added busy mouse cursor indicator when populating the cache viewer
>
> Everything is done on purpose on the AWT thread as before. Although I am personally not in favour of anonymous classes, I have tried to stick to the prevalent coding style.
>
> Unfortunatelly, I was unable to test the cache viewer's behavior because I do not know how to put synthetic cache entries into the cache. Can anyone help me with that? What does a the cache look like when filled with resources? Is there any index file that keeps track of the cache?
>
> Regards,
> Jacob
>
>
> ESC closing of Cache viewer + cleanup.patch
>
>
> diff --git a/netx/net/sourceforge/jnlp/controlpanel/CachePane.java b/netx/net/sourceforge/jnlp/controlpanel/CachePane.java
> --- a/netx/net/sourceforge/jnlp/controlpanel/CachePane.java
> +++ b/netx/net/sourceforge/jnlp/controlpanel/CachePane.java
> @@ -19,13 +19,18 @@
>
> 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;
> @@ -45,6 +50,8 @@
> import javax.swing.JScrollPane;
> import javax.swing.JTable;
> import javax.swing.ListSelectionModel;
> +import javax.swing.event.ListSelectionEvent;
> +import javax.swing.event.ListSelectionListener;
> import javax.swing.table.DefaultTableModel;
> import javax.swing.table.TableRowSorter;
>
> @@ -57,19 +64,20 @@
> import net.sourceforge.jnlp.util.PropertiesFile;
>
> 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.
> @@ -102,13 +110,22 @@
>
> 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);
> + }
> + });
Oh yes, this small enhancement is highly appreciated!
> 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
> @@ -138,7 +155,6 @@
> topPanel.add(scrollPane, c);
> this.add(topPanel, BorderLayout.CENTER);
> this.add(createButtonPanel(), BorderLayout.SOUTH);
> -
> }
>
> /**
> @@ -153,7 +169,7 @@
>
> 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) {
> @@ -216,22 +232,29 @@
> pf.store();
> }
> });
> + 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 handled
> + 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));
> }
> });
>
> @@ -250,6 +273,7 @@
> }
>
> doneButton.setPreferredSize(new Dimension(wantedWidth, wantedHeight));
> + doneButton.setEnabled(false);
> rightPanel.add(doneButton);
> buttonPanel.add(leftPanel);
> buttonPanel.add(rightPanel);
> @@ -257,14 +281,48 @@
> return buttonPanel;
> }
>
> + /**
> + * Posts an event to the event queue to later invoke populating the
> + * {@link CachePane#cacheTable}.
> + * @see CachePane#populateTable
> + */
> + final void invokeLaterPopulateTable() {
> + EventQueue.invokeLater(new Runnable() {
> + public void run() {
> + 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.window);
> + }
> +
Those should be in finally block
> + 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
> + // Populating the cacheTable may take a while, so indicate busy by cursor
> + parent.getContentPane().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
> +
> + DefaultTableModel defaultTableModel;
> + (defaultTableModel = (DefaultTableModel)cacheTable.getModel()).setRowCount(0); //Clears the table
> for (Object[] v : generateData(root))
> - ((DefaultTableModel) cacheTable.getModel()).addRow(v);
> + defaultTableModel.addRow(v);
> +
> + // Reset cursor
Those should be in finally block
> + parent.getContentPane().setCursor(Cursor.getDefaultCursor());
> }
>
> /**
> @@ -305,4 +363,4 @@
> defaultFocusComponent.requestFocusInWindow();
> }
> }
> -}
> +}
> \ No newline at end of file
> diff --git a/netx/net/sourceforge/jnlp/controlpanel/CacheViewer.java b/netx/net/sourceforge/jnlp/controlpanel/CacheViewer.java
> --- a/netx/net/sourceforge/jnlp/controlpanel/CacheViewer.java
> +++ b/netx/net/sourceforge/jnlp/controlpanel/CacheViewer.java
> @@ -22,7 +22,10 @@
> import java.awt.Frame;
> import java.awt.GridBagConstraints;
> import java.awt.GridBagLayout;
> +import java.awt.KeyEventDispatcher;
> +import java.awt.KeyboardFocusManager;
> import java.awt.Toolkit;
> +import java.awt.event.KeyEvent;
> import java.awt.event.WindowAdapter;
> import java.awt.event.WindowEvent;
>
> @@ -53,8 +56,9 @@
> */
> public CacheViewer(DeploymentConfiguration config) {
> super((Frame) null, dialogTitle, true); // Don't need a parent.
> + if ((this.config = config) == null)
> + throw new IllegalArgumentException("config: " + config);
> setIconImages(ImageResources.INSTANCE.getApplicationImages());
> - this.config = config;
>
> /* Prepare for adding components to dialog box */
> Container contentPane = getContentPane();
> @@ -70,11 +74,13 @@
> contentPane.add(topPanel, c);
>
> pack();
> + this.topPanel.invokeLaterPopulateTable();
>
> /* Set focus to default button when first activated */
> WindowAdapter adapter = new WindowAdapter() {
> private boolean gotFocus = false;
>
> + @Override
> public void windowGainedFocus(WindowEvent we) {
> // Once window gets focus, set initial focus
> if (!gotFocus) {
> @@ -85,6 +91,29 @@
> };
> addWindowFocusListener(adapter);
>
> + // Add a KeyEventDispatcher to dispatch events when this CacheViewer has focus
> + final CacheViewer cacheViewer = this;
> + KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
> + /**
> + * Dispatches mainly the <code>VK_ESCAPE</code> key event to close the
> + * <code>CacheViewer</code> dialog.
> + * @see java.awt.KeyEventDispatcher
> + */
> + public boolean dispatchKeyEvent(final KeyEvent keyEvent) {
> + // Check if Esc key has been pressed
> + if (keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE && keyEvent.getID() == KeyEvent.KEY_PRESSED) {
> + // Exclude this key event from further processing
> + keyEvent.consume();
> + // Remove this low-level KeyEventDispatcher
> + KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(this);
> + // Post close event to CacheViewer dialog
> + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new WindowEvent(cacheViewer, WindowEvent.WINDOW_CLOSING));
> + return true;
> + }
> + return false;
> + }
> + });
> +
> initialized = true;
> }
>
> @@ -116,4 +145,4 @@
> private void centerDialog() {
> ScreenFinder.centerWindowsToCurrentScreen(this);
> }
> -}
> +}
> \ No newline at end of file
Please mention both Cache viewer cleanup and CerViewr viewer cleanup in news.
>
More information about the distro-pkg-dev
mailing list