/*-
* Copyright (C) 2008 Erik Larsson
*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.catacombae.hfsexplorer.gui;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Set;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.catacombae.io.InputStreamReadable;
import org.catacombae.io.Readable;
/**
* @author <a href="http://www.catacombae.org/" target="_top">Erik Larsson</a>
*/
public class DisplayTextFilePanel extends javax.swing.JPanel {
private static final String[] sortingPrefixes =
new String[] { "US-ASCII", "UTF-8", "ISO-8859", "UTF", "IBM4", "IBM8", "IBM" };
private byte[] fileData = new byte[] { 0 };
private final Frame parentFrame;
private final String baseTitle;
/** Creates new form DisplayTextFilePanel. */
public DisplayTextFilePanel() {
this(null);
}
/**
* Creates new form DisplayTextFilePanel. Supplying a parent frame will lead to the frame's
* title changing to reflect the currently displayed file.
*/
public DisplayTextFilePanel(final Frame parentFrame) {
this.parentFrame = parentFrame;
if(parentFrame != null)
this.baseTitle = parentFrame.getTitle();
else
this.baseTitle = "";
initComponents();
textPaneScroller.getVerticalScrollBar().setMinimum(0);
textPaneScroller.getVerticalScrollBar().setMaximum(Integer.MAX_VALUE);
textPaneScroller.getHorizontalScrollBar().setMinimum(0);
textPaneScroller.getHorizontalScrollBar().setMaximum(Integer.MAX_VALUE);
Set<String> keySet = Charset.availableCharsets().keySet();
ArrayList<String> charsets = new ArrayList<String>(keySet);
LinkedList<String> listItems = new LinkedList<String>();
for(String prefix : sortingPrefixes) {
for(int i = 0; i < charsets.size();) {
String curCharset = charsets.get(i);
if(curCharset.startsWith(prefix)) {
listItems.add(curCharset);
charsets.remove(i);
}
else
++i;
}
}
for(String curCharset : charsets)
listItems.add(curCharset);
encodingBox.removeAllItems();
for(String curItem : listItems)
encodingBox.addItem(curItem);
if(encodingBox.getItemCount() > 0)
encodingBox.setSelectedIndex(0);
encodingBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
refreshView();
}
});
}
/*
public void addFileDropListener() {
new FileDrop(textPaneScroller, new FileDrop.Listener() {
public void filesDropped(java.io.File[] files) {
// handle file drop
if(files.length == 1) {
if(files[0].isFile()) {
loadFile(files[0]);
}
else
JOptionPane.showMessageDialog(DisplayTextFilePanel.this, "You can only view files.",
"Error", JOptionPane.ERROR_MESSAGE);
}
else if(files.length > 1) {
JOptionPane.showMessageDialog(DisplayTextFilePanel.this, "You can only view one file at a time.",
"Error", JOptionPane.ERROR_MESSAGE);
}
} // end filesDropped
}); // end FileDrop.Listener
}
*/
public void loadFile(File file) {
if(file.length() < Integer.MAX_VALUE) {
try {
FileInputStream fis = new FileInputStream(file);
loadStream(fis);
fis.close();
if(parentFrame != null)
parentFrame.setTitle(baseTitle + " - [" + file.getName() + "]");
} catch(Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "Exception while loading file:\n " + e + "\"");
}
}
else
JOptionPane.showMessageDialog(this, "File too large for memory address space! (" +
file.length() + "bytes)");
}
public void loadStream(InputStream is) {
loadStream(new InputStreamReadable(is));
}
public void loadStream(Readable is) {
try {
byte[] tmp = new byte[65536];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytesRead;
while((bytesRead = is.read(tmp)) > 0)
baos.write(tmp, 0, bytesRead);
fileData = baos.toByteArray();
baos = null;
refreshView();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int vMin = textPaneScroller.getVerticalScrollBar().getMinimum();
int hMin = textPaneScroller.getHorizontalScrollBar().getMinimum();
textPaneScroller.getVerticalScrollBar().setValue(vMin);
textPaneScroller.getHorizontalScrollBar().setValue(hMin);
}
});
} catch(Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "Exception while loading file:\n " + e + "\"");
}
}
private void refreshView() {
try {
final int vValue = textPaneScroller.getVerticalScrollBar().getValue();
final int hValue = textPaneScroller.getHorizontalScrollBar().getValue();
textPane.setText(new String(fileData, getSelectedEncoding()));
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textPaneScroller.getVerticalScrollBar().setValue(vValue);
textPaneScroller.getHorizontalScrollBar().setValue(hValue);
}
});
} catch(UnsupportedEncodingException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "Exception while decoding file data:\n " + e +
"\"");
}
}
private String getSelectedEncoding() {
return encodingBox.getSelectedItem().toString();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
textPaneScroller = new javax.swing.JScrollPane();
textPane = new javax.swing.JTextArea();
encodingLabel = new javax.swing.JLabel();
encodingBox = new javax.swing.JComboBox();
textPane.setColumns(20);
textPane.setEditable(false);
textPane.setRows(5);
textPaneScroller.setViewportView(textPane);
encodingLabel.setText("Encoding:");
encodingBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(encodingLabel)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(encodingBox, 0, 650, Short.MAX_VALUE)
.addContainerGap())
.add(textPaneScroller, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 721, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(encodingLabel)
.add(encodingBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(textPaneScroller, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 445, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JComboBox encodingBox;
private javax.swing.JLabel encodingLabel;
private javax.swing.JTextArea textPane;
private javax.swing.JScrollPane textPaneScroller;
// End of variables declaration//GEN-END:variables
}