edu.harvard.hul.ois.jhove.viewer.ConfigWindow Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jhove-apps Show documentation
Show all versions of jhove-apps Show documentation
Classes and fat JAR packaging for CLI and GUI app.
/**********************************************************************
* Jhove - JSTOR/Harvard Object Validation Environment
* Copyright 2004 by JSTOR and the President and Fellows of Harvard College
**********************************************************************/
package edu.harvard.hul.ois.jhove.viewer;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import java.text.ParseException;
import javax.swing.*;
import javax.swing.table.*;
//import javax.swing.border.*;
import edu.harvard.hul.ois.jhove.ConfigHandler;
import edu.harvard.hul.ois.jhove.ConfigWriter;
import edu.harvard.hul.ois.jhove.ModuleInfo;
/**
* Window for high-level editing of the application's
* configuration file.
*
* @author Gary McGath
*
*/
public class ConfigWindow extends JDialog {
private final static String tempDirDefault = "";
private final static String SANS_SERIF = "SansSerif";
private final static String CENTER = "Center";
private final static String CLASS = "Class";
private final static String WEST = "West";
private final static String EAST = "East";
private final static String ADD = "Add";
private final static String DELETE = "Delete";
private final static String NORTH = "North";
/* The location of the config file. */
private File _configFile;
/* List of modules. An entry in the list is an
* array of 2 Strings, which are the fully qualified
* class and the init string respectively. */
private List _modules;
/* List of handlers. This is just a list of Strings
* giving the class. */
private List _handlers;
private int _bufferSize;
private File _homeDir;
private File _tempDir;
private String _encoding;
/* Display components. */
private Box _mainBox;
private JTable _modTable;
private JTable _hanTable;
private AbstractTableModel _modTableModel;
private AbstractTableModel _hanTableModel;
private JLabel _homeLabel;
private JLabel _tempDirLabel;
private NumericField _bufSizeBox;
private JTextField _encodingBox;
final static Color _tableColor = new Color (235, 230, 210);
final static Font _pathFont = new Font (SANS_SERIF, Font.PLAIN, 10);
final static Font _infoFont = new Font (SANS_SERIF, Font.PLAIN, 12);
final static int HEIGHT = 640;
/**
* Constructor.
*
* @param configFile The file which was opened for
* configuration information, or null
* to start with a clean slate.
*
* @param handler A ConfigHandler which has already
* processed the configuration file,
* or null if configFile is null.
*/
public ConfigWindow (JFrame parent, File configFile, ConfigHandler handler)
{
super (parent, "JHOVE Configuration", true);
setDefaultCloseOperation (WindowConstants.DISPOSE_ON_CLOSE);
_configFile = configFile;
if (handler != null) {
_modules = handler.getModule ();
_handlers = handler.getHandler ();
_bufferSize = handler.getBufferSize ();
String dir = handler.getJhoveHome();
if (dir != null) {
_homeDir = new File (dir);
}
dir = handler.getTempDir();
if (dir != null) {
_tempDir = new File (dir);
}
_encoding = handler.getEncoding ();
}
else {
// Set up defaults
_modules = new ArrayList<> (10);
_handlers = new ArrayList<> (5);
_bufferSize = -1;
_homeDir = null;
_tempDir = null;
_encoding = null;
}
// Set up a Box container for the window top level
_mainBox = Box.createVerticalBox ();
getContentPane().setLayout (new BorderLayout ());
getContentPane().add (_mainBox, CENTER);
_mainBox.setBorder (BorderFactory.createLineBorder(Color.BLACK));
// Keep its size reasonable, taking screen size into account
java.awt.Rectangle screenRect = MainScreen.mainBounds ();
int maxHeight = screenRect.height - 200;
if (maxHeight > HEIGHT) {
maxHeight = HEIGHT;
}
_mainBox.setMaximumSize (new Dimension (500, maxHeight));
_mainBox.setPreferredSize (new Dimension (400, maxHeight));
addModuleTable ();
_mainBox.add(Box.createRigidArea(new Dimension(0, 6)));
addHandlerTable ();
addHomeDir ();
addTempDir ();
addEncoding ();
addBufferSize ();
addSaveCancel ();
pack ();
}
/* Create a JTable of two columns which lets the
* user add and delete modules, and add it to
* the window.
* Called by the constructor.
*/
private void addModuleTable ()
{
JPanel panel = new JPanel ();
panel.setLayout (new BorderLayout ());
_mainBox.add (panel);
// Use an anonymous class to implement the TableModel
_modTableModel = new AbstractTableModel () {
@Override
public int getRowCount ()
{
return _modules.size ();
}
@Override
public int getColumnCount ()
{
return 2;
}
@Override
public boolean isCellEditable(int row, int col)
{
return true;
}
@Override
public Object getValueAt (int row, int column)
{
ModuleInfo modInfo = _modules.get (row);
String[] tuple = { modInfo.clas, modInfo.init};
return tuple[column];
}
@Override
public void setValueAt (Object obj, int row, int column)
{
ModuleInfo modInfo = _modules.get(row);
if (column == 0 && obj instanceof String) {
modInfo.clas = (String) obj;
}
if (column == 1 && obj instanceof String) {
modInfo.init = (String) obj;
}
}
};
_modTable = new JTable (_modTableModel);
// _modTable.setMaximumSize(new Dimension (250, 150));
_modTable.setSelectionMode (ListSelectionModel.SINGLE_SELECTION);
_modTable.setCellSelectionEnabled (true);
_modTable.setBackground (_tableColor);
JScrollPane modScrollPane = new JScrollPane (_modTable);
TableColumnModel colMod = _modTable.getColumnModel();
colMod.getColumn(0).setHeaderValue(CLASS);
colMod.getColumn(1).setHeaderValue("Init");
_modTable.doLayout ();
// Add a panel with the modules caption and a couple of buttons.
JPanel topPanel = new JPanel ();
topPanel.setLayout (new BorderLayout ());
topPanel.add (new JLabel ("Modules:"), WEST);
// Squeeze the buttons over to the right
JPanel rightPanel = new JPanel ();
topPanel.add (rightPanel, EAST);
JButton addButton = new JButton (ADD);
addButton.addActionListener (
new ActionListener () {
@Override
public void actionPerformed (ActionEvent e)
{
addModule ();
}
}
);
rightPanel.add (addButton);
JButton delButton = new JButton (DELETE);
delButton.addActionListener (
new ActionListener () {
@Override
public void actionPerformed (ActionEvent e)
{
deleteModule ();
}
}
);
// Make both buttons the same size
addButton.setMinimumSize (delButton.getMinimumSize ());
addButton.setPreferredSize (delButton.getPreferredSize ());
rightPanel.add (delButton);
panel.add (topPanel, NORTH);
panel.add (modScrollPane, CENTER);
}
/* Create a JTable of one column which lets the
* user add and delete handlers, and add it to
* the window.
* Called by the constructor.
*/
private void addHandlerTable ()
{
JPanel panel = new JPanel ();
panel.setLayout (new BorderLayout ());
_mainBox.add (panel);
// Use an anonymous class to implement the TableModel
_hanTableModel = new AbstractTableModel () {
@Override
public int getRowCount ()
{
return _handlers.size ();
}
@Override
public int getColumnCount ()
{
return 1;
}
@Override
public boolean isCellEditable(int row, int col)
{
return true;
}
@Override
public Object getValueAt (int row, int column)
{
String[] tuple = _handlers.get (row);
if (tuple != null) {
return tuple[0];
}
return "";
}
@Override
public void setValueAt (Object obj, int row, int column)
{
if (obj instanceof String) {
String[] stuff = new String[] { (String) obj };
_handlers.set (row, stuff);
}
}
};
_hanTable = new JTable (_hanTableModel);
_hanTable.setSelectionMode (ListSelectionModel.SINGLE_SELECTION);
_hanTable.setCellSelectionEnabled (true);
_hanTable.setBackground (_tableColor);
JScrollPane hanScrollPane = new JScrollPane (_hanTable);
TableColumnModel colMod = _hanTable.getColumnModel();
colMod.getColumn(0).setHeaderValue(CLASS);
_hanTable.doLayout ();
// Add a panel with the modules caption and a couple of buttons.
JPanel topPanel = new JPanel ();
topPanel.setLayout (new BorderLayout ());
topPanel.add (new JLabel ("Handlers:"), WEST);
// Squeeze the buttons over to the right
JPanel rightPanel = new JPanel ();
topPanel.add (rightPanel, EAST);
JButton addButton = new JButton (ADD);
addButton.addActionListener (
new ActionListener () {
@Override
public void actionPerformed (ActionEvent e)
{
addHandler ();
}
}
);
rightPanel.add (addButton);
JButton delButton = new JButton (DELETE);
delButton.addActionListener (
new ActionListener () {
@Override
public void actionPerformed (ActionEvent e)
{
deleteHandler ();
}
}
);
// Make both buttons the same size
addButton.setMinimumSize (delButton.getMinimumSize ());
addButton.setPreferredSize (delButton.getPreferredSize ());
rightPanel.add (delButton);
panel.add (topPanel, NORTH);
panel.add (hanScrollPane, CENTER);
}
/* Add a label and text edit box for the encoding */
private void addEncoding ()
{
JPanel panel = new JPanel ();
_mainBox.add (panel);
panel.add (new JLabel ("Default encoding: "));
_encodingBox = new JTextField (_encoding == null ? "" : _encoding, 14);
panel.add (_encodingBox);
}
/* Add a label and text edit box for the buffer size */
private void addBufferSize ()
{
JPanel panel = new JPanel ();
_mainBox.add (panel);
panel.add (new JLabel ("Buffer size (-1 for default): "));
_bufSizeBox = new NumericField (_bufferSize);
panel.add (_bufSizeBox);
}
/* Add a button and file path string for home directory.
* A home directory is required, but there may not be one
* initially.
* Called by the constructor. */
private void addHomeDir ()
{
JPanel panel = new JPanel ();
_mainBox.add (panel);
panel.setLayout (new GridLayout (1, 2));
JButton homeButton = new JButton ("Home directory...");
String homeText = "";
if (_homeDir != null) {
homeText = _homeDir.getPath();
}
_homeLabel = new JLabel(homeText);
_homeLabel.setFont (_pathFont);
// Standard trick for not making button take up all available space
JPanel bpan = new JPanel ();
//panel.add (bpan);
panel.add (bpan);
bpan.add (homeButton);
homeButton.addActionListener (
new ActionListener () {
@Override
public void actionPerformed (ActionEvent e)
{
chooseHomeDir ();
}
}
);
panel.add (_homeLabel);
// Both of these probably need to be class variables
}
/* Add a button and file path string for temporary directory.
* Called by the constructor. */
private void addTempDir ()
{
JPanel panel = new JPanel ();
_mainBox.add (panel);
panel.setLayout (new GridLayout (1, 2));
JButton tempDirButton = new JButton ("Temp directory...");
String tempDirText = tempDirDefault;
if (_tempDir != null) {
tempDirText = _tempDir.getPath();
}
_tempDirLabel = new JLabel(tempDirText);
_tempDirLabel.setFont (_pathFont);
// Standard trick for not making button take up all available space
JPanel bpan = new JPanel ();
panel.add (bpan);
bpan.add (tempDirButton);
tempDirButton.addActionListener (
new ActionListener () {
@Override
public void actionPerformed (ActionEvent e)
{
chooseTempDir ();
}
}
);
panel.add (_tempDirLabel);
}
/* Add OK and cancel buttons, and a little information */
private void addSaveCancel ()
{
final ConfigWindow thiscw = this;
JPanel buttonPanel = new JPanel ();
getContentPane().add (buttonPanel, "South");
buttonPanel.setLayout (new BorderLayout ());
JLabel changesLabel = new JLabel
("Changes take effect on relaunch");
changesLabel.setFont (_infoFont);
buttonPanel.add (changesLabel, NORTH);
JPanel panel = new JPanel ();
buttonPanel.add (panel, CENTER);
panel.setLayout (new GridLayout (1, 3));
// Blank panel for positioning
JPanel bpan = new JPanel ();
panel.add (bpan);
// Add OK button
bpan = new JPanel ();
JButton saveButton = new JButton ("OK");
getRootPane().setDefaultButton (saveButton);
saveButton.addActionListener (
new ActionListener () {
@Override
public void actionPerformed (ActionEvent e)
{
doSave ();
}
}
);
bpan.add (saveButton);
panel.add (bpan);
// Add cancel button
bpan = new JPanel ();
JButton cancelButton = new JButton ("Cancel");
cancelButton.addActionListener (
new ActionListener () {
@Override
public void actionPerformed (ActionEvent e)
{
thiscw.dispose ();
}
}
);
// Make both buttons the same size
saveButton.setMinimumSize (cancelButton.getMinimumSize ());
saveButton.setPreferredSize (cancelButton.getPreferredSize ());
bpan.add (cancelButton);
panel.add (bpan);
}
/* Carry out the action of the "Save" button. */
private void doSave ()
{
// Splitting off the output to a ConfigFileWriter class
// makes sense.
try {
// Update values from the editing components
try {
_bufSizeBox.commitEdit ();
}
catch (ParseException e) {
return; // refuse to save if value is invalid
}
//Object bufSizeValue = _bufSizeBox.getValue ();
_bufferSize = ((Long) _bufSizeBox.getValue ()).intValue ();
_encoding = _encodingBox.getText ();
// *** Writes to temp file for debugging
//ConfigWriter cw = new ConfigWriter (new File (_homeDir, "temp"));
ConfigWriter cw = new ConfigWriter (_configFile, this);
cw.writeFile (_modules, _handlers,
_homeDir, _tempDir, _encoding, _bufferSize);
}
catch (IOException e) {
JOptionPane.showMessageDialog(this,
e.getMessage (),
"Can't create config",
JOptionPane.ERROR_MESSAGE);
}
// Close the window
dispose ();
}
/* Choose the home directory. Since there must be one,
* there is no "default" button. */
private void chooseHomeDir ()
{
JFileChooser chooser = new JFileChooser ();
if (_homeDir != null) {
chooser.setCurrentDirectory (_homeDir);
}
chooser.setDialogTitle ("Select Home Directory");
chooser.setFileSelectionMode (JFileChooser.DIRECTORIES_ONLY);
if (chooser.showOpenDialog (this) == JFileChooser.APPROVE_OPTION) {
_homeDir = chooser.getSelectedFile();
_homeLabel.setText (_homeDir.getPath ());
}
}
/* Choose the temp directory. Allow a "default" selection. */
private void chooseTempDir ()
{
final JFileChooser chooser = new JFileChooser ();
if (_homeDir != null) {
chooser.setCurrentDirectory (_tempDir);
}
chooser.setDialogTitle ("Select Temporary Directory");
// Create a custom panel so we can add the Default button.
JPanel accessory = new JPanel ();
accessory.setPreferredSize(new Dimension (160, 40));
JButton defaultButton = new JButton ("System Default");
defaultButton.addActionListener (
new ActionListener () {
@Override
public void actionPerformed (ActionEvent e)
{
// Exit the dialog and clear _tempDir
_tempDir = null;
_tempDirLabel.setText (tempDirDefault);
chooser.cancelSelection ();
}
}
);
accessory.add (defaultButton);
chooser.setAccessory (accessory);
chooser.setFileSelectionMode (JFileChooser.DIRECTORIES_ONLY);
if (chooser.showOpenDialog (this) == JFileChooser.APPROVE_OPTION) {
_tempDir = chooser.getSelectedFile();
_tempDirLabel.setText (_tempDir.getPath ());
}
}
/* Add a blank item for a new module */
private void addModule ()
{
ListSelectionModel ls = _modTable.getSelectionModel ();
int selRow = ls.getMinSelectionIndex();
// If there's no selection, append to the end
if (selRow < 0) {
selRow = _modules.size ();
}
// String[] tuple = new String[2];
// tuple[0] = ""; // class
// tuple[1] = null; // init
ModuleInfo modInfo = new ModuleInfo ("", null);
_modules.add (selRow, modInfo);
_modTableModel.fireTableRowsInserted(selRow, selRow);
}
/* Delete the selected module line */
private void deleteModule ()
{
ListSelectionModel ls = _modTable.getSelectionModel ();
int selRow = ls.getMinSelectionIndex();
if (selRow < 0) {
return; // no selection
}
_modules.remove (selRow);
_modTableModel.fireTableRowsDeleted (selRow, selRow);
}
/* Add a blank item for a new handler */
private void addHandler ()
{
ListSelectionModel ls = _hanTable.getSelectionModel ();
int selRow = ls.getMinSelectionIndex();
// If there's no selection, append to the end
if (selRow < 0) {
selRow = _handlers.size ();
}
String[] tuple = { "" };
_handlers.add (selRow, tuple);
_hanTableModel.fireTableRowsInserted(selRow, selRow);
}
/* Delete the selected handler line */
private void deleteHandler ()
{
ListSelectionModel ls = _hanTable.getSelectionModel ();
int selRow = ls.getMinSelectionIndex();
if (selRow < 0) {
return; // no selection
}
_handlers.remove (selRow);
_hanTableModel.fireTableRowsDeleted (selRow, selRow);
}
/* When the user chooses to close and save, or just save,
* we come here.
*
* @param configFile The location to save the file, or none
* if a simple "save" was selected. If
* configFile is non-null, it becomes the
* new default location.
*/
// private void saveConfig (File configFile)
// {
// if (configFile != null) {
// _configFile = configFile;
// }
//
// // _configFile may be null. In that case we must put up
// // a dialog to select the config file here, and exit the function
// // if the user cancels.
// try {
// FileOutputStream ostrm = new FileOutputStream (configFile);
// }
// catch (IOException e) {
// JOptionPane.showMessageDialog (this,
// e.getMessage(), "Error saving config",
// JOptionPane.ERROR_MESSAGE);
//
// }
// }
// private File doConfigFileDialog ()
// {
// JFileChooser chooser = new JFileChooser ();
// chooser.setFileSelectionMode (JFileChooser.DIRECTORIES_ONLY);
// if (chooser.showOpenDialog (this) == JFileChooser.APPROVE_OPTION) {
// return chooser.getSelectedFile();
// }
//
// return null; // placeholder
// }
}