aboutsummaryrefslogtreecommitdiffstats
path: root/netx
diff options
context:
space:
mode:
Diffstat (limited to 'netx')
-rw-r--r--netx/net/sourceforge/jnlp/controlpanel/CachePane.java328
-rw-r--r--netx/net/sourceforge/jnlp/controlpanel/CacheViewer.java39
-rw-r--r--netx/net/sourceforge/jnlp/util/ui/NonEditableTableModel.java124
-rw-r--r--netx/net/sourceforge/jnlp/util/ui/package-info.java41
4 files changed, 427 insertions, 105 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);
}
}
diff --git a/netx/net/sourceforge/jnlp/controlpanel/CacheViewer.java b/netx/net/sourceforge/jnlp/controlpanel/CacheViewer.java
index fc63b60..bbdcad4 100644
--- a/netx/net/sourceforge/jnlp/controlpanel/CacheViewer.java
+++ b/netx/net/sourceforge/jnlp/controlpanel/CacheViewer.java
@@ -1,5 +1,5 @@
/* CacheViewer.java -- Display the GUI for viewing and deleting cache files.
-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
@@ -22,7 +22,10 @@ import java.awt.Dimension;
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,11 @@ public class CacheViewer extends JDialog {
*/
public CacheViewer(DeploymentConfiguration config) {
super((Frame) null, dialogTitle, true); // Don't need a parent.
- setIconImages(ImageResources.INSTANCE.getApplicationImages());
this.config = config;
+ if (config == null) {
+ throw new IllegalArgumentException("config: " + config);
+ }
+ setIconImages(ImageResources.INSTANCE.getApplicationImages());
/* Prepare for adding components to dialog box */
Container contentPane = getContentPane();
@@ -70,11 +76,13 @@ public class CacheViewer extends JDialog {
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 +93,33 @@ public class CacheViewer extends JDialog {
};
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.
+ * @return {@code true} after an {@link KeyEvent#VK_ESCAPE
+ * VK_ESCAPE} has been processed, otherwise {@code false}
+ * @see 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;
}
diff --git a/netx/net/sourceforge/jnlp/util/ui/NonEditableTableModel.java b/netx/net/sourceforge/jnlp/util/ui/NonEditableTableModel.java
new file mode 100644
index 0000000..4f2c409
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/util/ui/NonEditableTableModel.java
@@ -0,0 +1,124 @@
+/* NonEditableTableModel.java
+ Copyright (C) 2013 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea 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, version 2.
+
+IcedTea 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
+IcedTea; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is making a
+combined work based on this library. Thus, the terms and conditions of the GNU
+General Public License cover the whole combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent modules, and
+to copy and distribute the resulting executable under terms of your choice,
+provided that you also meet, for each linked independent module, the terms and
+conditions of the license of that module. An independent module is a module
+which is not derived from or based on this library. If you modify this
+library, you may extend this exception to your version of the library, but you
+are not obligated to do so. If you do not wish to do so, delete this exception
+statement from your version.
+*/
+package net.sourceforge.jnlp.util.ui;
+
+import java.util.Vector;
+import javax.swing.table.DefaultTableModel;
+
+/**
+ * A table model that in effect is a {@link DefaultTableModel} except for no
+ * cell being editable.
+ * @see DefaultTableModel
+ * @since IcedTea-Web 1.5
+ */
+public class NonEditableTableModel extends DefaultTableModel {
+ /**
+ * Constructs a {@link javax.swing.table.TableModel} that serves only one
+ * purpose: make cells of certificate tables not editable.
+ * @see DefaultTableModel#DefaultTableModel()
+ */
+ public NonEditableTableModel() {
+ super();
+ }
+
+ /**
+ * Constructs a {@link javax.swing.table.TableModel} that serves only one
+ * purpose: make cells of certificate tables not editable.
+ * @param rowCount the number of rows the table holds
+ * @param columnCount the number of columns the table holds
+ * @see DefaultTableModel#DefaultTableModel(int,int)
+ */
+ public NonEditableTableModel(final int rowCount, final int columnCount) {
+ super(rowCount, columnCount);
+ }
+
+ /**
+ * Constructs a {@link javax.swing.table.TableModel} that serves only one
+ * purpose: make cells of certificate tables not editable.
+ * @param data the data of the table
+ * @param columnNames the names of the columns
+ * @see DefaultTableModel#DefaultTableModel(Object[][],Object[])
+ */
+ public NonEditableTableModel(final Object[][] data, final Object[] columnNames) {
+ super(data, columnNames);
+ }
+
+ /**
+ * Constructs a {@link javax.swing.table.TableModel} that serves only one
+ * purpose: make cells of certificate tables not editable.
+ * @param columnNames {@code array} containing the names of the new columns;
+ * if this is {@code null} then the model has no columns
+ * @param rowCount the number of rows the table holds
+ * @see DefaultTableModel#DefaultTableModel(Object[],int)
+ */
+ public NonEditableTableModel(final Object[] columnNames, final int rowCount) {
+ super(columnNames, rowCount);
+ }
+
+ /**
+ * Constructs a {@link javax.swing.table.TableModel} that serves only one
+ * purpose: make cells of certificate tables not editable.
+ * @param columnNames {@code vector} containing the names of the new columns;
+ * if this is {@code null} then the model has no columns
+ * @param rowCount the number of rows the table holds
+ * @see DefaultTableModel#DefaultTableModel(Vector,int)
+ */
+ public NonEditableTableModel(final Vector columnNames, final int rowCount) {
+ super(columnNames, rowCount);
+ }
+
+ /**
+ * Constructs a {@link javax.swing.table.TableModel} that serves only one
+ * purpose: make cells of certificate tables not editable.
+ * @param data the data of the table, a {@code Vector} of {@code Vector}s
+ * of {@code Object} values
+ * @param columnNames {@code vector} containing the names of the new columns
+ * @see DefaultTableModel#DefaultTableModel(Vector,Vector)
+ */
+ public NonEditableTableModel(final Vector data, final Vector columnNames) {
+ super(data, columnNames);
+ }
+
+ /**
+ * This method always returns {@code false} to make the table's cells not
+ * editable.
+ * @param row the row whose value to be queried
+ * @param column the column whose value to be queried
+ * @return always {@code false}
+ */
+ @Override
+ public boolean isCellEditable(final int row, final int column) {
+ return false;
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/util/ui/package-info.java b/netx/net/sourceforge/jnlp/util/ui/package-info.java
new file mode 100644
index 0000000..ddb2621
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/util/ui/package-info.java
@@ -0,0 +1,41 @@
+/* package-info.java
+ Copyright (C) 2013 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea 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, version 2.
+
+IcedTea 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
+IcedTea; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is making a
+combined work based on this library. Thus, the terms and conditions of the GNU
+General Public License cover the whole combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent modules, and
+to copy and distribute the resulting executable under terms of your choice,
+provided that you also meet, for each linked independent module, the terms and
+conditions of the license of that module. An independent module is a module
+which is not derived from or based on this library. If you modify this
+library, you may extend this exception to your version of the library, but you
+are not obligated to do so. If you do not wish to do so, delete this exception
+statement from your version.
+*/
+/**
+ * Contains classes that deal with common and recurring UI tasks.
+ * <p>
+ * <b>NOTE:</b> Before adding new self-sufficient {@code public static} methods
+ * to this package please evaluate thier suitability for {@link UI} first.</p>
+ * @since IcedTea-Web 1.5
+ */
+package net.sourceforge.jnlp.util.ui;