Related
I'm attempting to make a code that will use JFileChooser and JPassword for getting input of encrypted code or code to be encrypted.
Here is the code to be encrypted "Be sure to drink your Ovaltine!" to be saved in a .rtf or a .txt file. The key is "annie". The output should be
"Fv '$zi (# pzm"| (wy& `%ip(zzm%".
I have two different class files under the project "Password". One class is called "File Opener". It calls the class "Password1".
Here is Password1.java.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
/* PasswordDemo.java requires no other files. */
public class Password1 extends JPanel
implements ActionListener {
private String key;
private static String OK = "ok";
private JFrame controllingFrame; //needed for dialogs
private JPasswordField passwordField;
public Password1(JFrame f) {
//Use the default FlowLayout.
controllingFrame = f;
//Create everything.
passwordField = new JPasswordField(10);
passwordField.setActionCommand(OK);
passwordField.addActionListener(this);
JLabel label = new JLabel("Enter the key: ");
label.setLabelFor(passwordField);
JComponent buttonPane = createButtonPanel();
//Lay out everything.
JPanel textPane = new JPanel(new FlowLayout(FlowLayout.TRAILING));
textPane.add(label);
textPane.add(passwordField);
add(textPane);
add(buttonPane);
}
protected JComponent createButtonPanel() {
JPanel p = new JPanel(new GridLayout(0,1));
JButton okButton = new JButton("OK");
okButton.setActionCommand(OK);
okButton.addActionListener(this);
p.add(okButton);
return p;
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
controllingFrame.dispose();
if (OK.equals(cmd)) { //Process the password.
char[] input = passwordField.getPassword();
key = new String(input);
//Zero out the possible password, for security.
Arrays.fill(input,'0');
passwordField.selectAll();
resetFocus();
} else {
System.out.println("Please enter a key.");
}
}
public String getKey(){
return key;
}
//Must be called from the event dispatch thread.
protected void resetFocus() {
passwordField.requestFocusInWindow();
}
public static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Key");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
final Password1 newContentPane = new Password1(frame);
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Make sure the focus goes to the right component
//whenever the frame is initially given the focus.
frame.addWindowListener(new WindowAdapter() {
public void windowActivated(WindowEvent e) {
newContentPane.resetFocus();
}
});
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
}
And here is the FileOpener.java.
import javax.swing.*;
import java.io.*;
import javax.swing.filechooser.*;
import java.awt.event.*;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;
public class FileOpener extends JPanel implements ActionListener {
static private final String newline = "\n";
private Password1 p1;
JButton decodeButton, encodeButton;
JFileChooser fc;
JTextArea log;
Scanner in = new Scanner(System.in);
JFrame frame;
File file;
int count;
public FileOpener(){
// create and set up the window.
frame = new JFrame("Open Your File");
// make the program close when the window closes
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create the box layout
frame.getContentPane( ).setLayout(new BoxLayout(frame.getContentPane( ), BoxLayout.Y_AXIS));
//label prompting user for input
JLabel label1 = new JLabel ("Would you like to encode or decode your file?", JLabel.CENTER);
frame.getContentPane().add(label1);
//create a filer chooser
fc = new JFileChooser();
// add a button object
decodeButton = new JButton("Decode");
decodeButton.addActionListener(this);
frame.getContentPane( ).add(decodeButton);
encodeButton = new JButton("Encode");
encodeButton.addActionListener(this);
frame.getContentPane( ).add(encodeButton);
// display the window.
frame.pack( );
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
//Handle open button action.
if (e.getSource() == encodeButton) {
frame.dispose();
int returnVal = fc.showOpenDialog(FileOpener.this);
if (returnVal == JFileChooser.APPROVE_OPTION ) {
try {
file = fc.getSelectedFile();
p1 = new Password1(frame);
p1.createAndShowGUI();
//get length of key
String key = p1.getKey();
int length3 = key.length();
count = 0;
int keyAsciiValues[] = new int[length3];
String name1 ="";
//get ascii value of each letter in key
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
FileInputStream file2= new FileInputStream(file);
//create a scanner for it
in = new Scanner(file2);
//read in message
String name;
name = in.nextLine();
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
//measure length of code message array
int length1 = name.length();
//measures length of strings in code message array
for(int j=0;j<length1;j++){
char c = name.charAt(j);
int ascii = (int)c;
ascii += keyAsciiValues[count];
if(c != ' '){
count++;
}
if(count>length3-1){
count = 0;
}
while(ascii>126){
ascii-= 93;
}
char b=(char)ascii;
if(c == ' '){
b = ' ';
}
name1 += b;
}
System.out.println(name1);
} catch (FileNotFoundException k){
//the file was not found!
System.out.println("File could not be opened!");
}
}
//Handle save button action.
} else if (e.getSource() == decodeButton) {
frame.dispose();
int returnVal = fc.showOpenDialog(FileOpener.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
try {
file = fc.getSelectedFile();
p1 = new Password1(frame);
p1.createAndShowGUI();
//open the file
//get length of key
String key = p1.getKey();
int length3 = key.length();
count = 0;
int keyAsciiValues[] = new int[length3];
String name1 ="";
//get ascii value of each letter in key
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
//create a scanner for it
in = new Scanner(file);
//read in message
String name;
name = in.nextLine();
for (int k=0; k<length3; k++){
char a = key.charAt(k);
int ascii1 = (int)a;
//put ascii value of letter in key to array
keyAsciiValues[k]= ascii1;
}
//measure length of code message array
int length1 = name.length();
//measures length of strings in code message array
for(int j=0;j<length1;j++){
char c = name.charAt(j);
int ascii = (int)c;
ascii -= keyAsciiValues[count];
if(c != ' '){
count++;
}
if(count>length3-1){
count = 0;
}
while(ascii<33){
ascii+= 93;
}
char b=(char)ascii;
if(c == ' '){
b = ' ';
}
name1 += b;
}
System.out.print(name1);
} catch (FileNotFoundException k){
//the file was not found!
System.out.println("File could not be opened!");
}
}
in.close();
log.append("Opening: " + file.getName() + "." + newline);
}
}
public static void main(String args[]) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
FileOpener f = new FileOpener();
}
}
It was working fine before I added the JFileChooser and the Password stuff aka there shouldn't be anything wrong with the actual ciphering part of the code.
It's giving me a java.lang.NullPointerException at line at line 70 in FileOpener.
int length3 = key.length();
Thanks!
In the createAndShowGUI() method, you show your Password1 instance in a JFrame, not a modal JDialog. Therefore, this display instruction is non-blocking, i.e. it does not stop code execution, nor does it wait until you click a button that closes the window.
As a result, you retrieve the Password1 instance key before its actionPerformed() method can execute and initialize the key attribute, hence the key is still null and you get a NullPointerException when you invoke any method on it.
My suggestion is using a modal JDialog in createAndShowGUI() to manage your Password1 interface (initialization using a JPanel is much like what you are already doing with a JFrame). This way, when you invoke createAndShowGUI(), the FileOpener.actionPerformed() method execution will block until you are done with the Password1 dialog, hence you will make sure key is properly initialized before you retrieve and use it in FileOpener.actionPerformed().
One last thing: be careful with frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);! Using it on your main window is OK but using it on any secondary window will make the whole program shut down completely as soon as you close it. But anyway, the JDialog version of setDefaultCloseOperation() doesn't accept EXIT_ON_CLOSE as a valid argument, so you will remain using it only on your main FileOpener window, which is fine.
Firstly, I would like to say I am not asking for an answer more so advice so I can learn from this problem. Every time I run my code I get Array Index Out of Bounds on Line 254 of the ArrayOperations java file.
if (SearchKey == tempArray[middle])
I have added as many checks as I possibly can to this code and also have commented it as much as possible for your ease. Once again I am looking for advice on this not just a direct answer if possible. The Error always seems to give me the negative version of 1/2 of my data items
ex: 100,000 data items, Array Index Out of Bounds: -49,999.
import javax.swing.*;
// File-related imports
import java.io.IOException;
import java.util.Scanner;
import java.io.File;
public class ArrayOperations
{
// File Parameters
String DataFilePath;
String DataFileName;
String KeysFilePath;
String KeysFileName;
int NumberOfDataItems;
int NumberOfKeys;
int N;
int BucketHashArraySize;
int NoBuckets;
//Array
int[] OriginalArray = new int[1000000];
int[] SortedArray = new int[1000000];
int[] HashedArray = new int[2000000];
int[] BucketHashedArray = new int[2000000];
int[] KeysArray = new int[1000000];
long SSAverageAccessTime;
long SSAverageCompSuc;
long SSAverageCompFailed;
long SSNumberKeysSuc;
long SSNumberKeysFailed ;
long BSAverageAccessTime;
long BSAverageCompSuc ;
long BSAverageCompFailed;
long BSNumberKeysSuc ;
long BSNumberKeysFailed ;
long HSAverageAccessTime;
long HSAverageCompSuc ;
long HSAverageCompFailed;
long HSNumberKeysSuc ;
long HSNumberKeysFailed ;
public ArrayOperations()
{
// File Parameters
DataFilePath = null;
DataFileName = null;
KeysFilePath = null;
KeysFileName = null;
NumberOfDataItems=0;
NumberOfKeys =0;
N =0;
BucketHashArraySize = 0;
NoBuckets =0;
// Statistics
SSAverageAccessTime = 0;
SSAverageCompSuc = 0;
SSAverageCompFailed = 0;
SSNumberKeysSuc = 0;
SSNumberKeysFailed = 0;
}
public void ReadDataFile() throws IOException
{
JFileChooser chooser = new JFileChooser();
chooser.setDialogType(JFileChooser.OPEN_DIALOG );
chooser.setDialogTitle("Open Data File");
int returnVal = chooser.showOpenDialog(null);
if( returnVal == JFileChooser.APPROVE_OPTION)
{
DataFilePath = chooser.getSelectedFile().getPath();
DataFileName = chooser.getSelectedFile().getName();
}
// read data file and copy it to original array
if (DataFilePath != null)
{
try
{
int index = 0;
Scanner integerTextFile = new Scanner(new File(DataFilePath));
while (integerTextFile.hasNext())
{
// read the next integer
OriginalArray[index] = integerTextFile.nextInt();
index++;
}
// end of file detected
integerTextFile.close();
NumberOfDataItems = index;
}
catch (IOException ioe)
{
System.exit(0);
}
}
else
NumberOfDataItems = 0;
}
public void ReadKeysFile() throws IOException
{
JFileChooser chooser = new JFileChooser();
chooser.setDialogType(JFileChooser.OPEN_DIALOG );
chooser.setDialogTitle("Open Keys File");
int returnVal = chooser.showOpenDialog(null);
if( returnVal == JFileChooser.APPROVE_OPTION)
{
KeysFilePath = chooser.getSelectedFile().getPath();
KeysFileName = chooser.getSelectedFile().getName();
}
// read data file and copy it to original array
if (KeysFilePath != null)
{
try
{
int index = 0;
Scanner integerTextFile = new Scanner(new File(KeysFilePath));
while (integerTextFile.hasNext())
{
// read the next integer
KeysArray[index]= integerTextFile.nextInt();
index++;
}
// end of file detected
integerTextFile.close();
NumberOfKeys = index;
}
catch (IOException ioe)
{
System.exit(0);
}
}
else
NumberOfKeys = 0;
}
public void SequentialSearch()
{
SSAverageAccessTime = 0;
SSAverageCompSuc = 0;
SSAverageCompFailed = 0;
SSNumberKeysSuc = 0;
SSNumberKeysFailed = 0;
int SearchKey;
int TotalNumberOfComparisons;
long startTime = System.nanoTime();
boolean found = false;
for (int k=0; k<NumberOfKeys; k++)
{
found = false;
SearchKey = KeysArray[k];
TotalNumberOfComparisons = 0;
for (int d=0; d<NumberOfDataItems; d++)
{
TotalNumberOfComparisons++;
if (SearchKey == OriginalArray[d])
{
found = true;
}
if (found)break;
}
if(found)
{
SSAverageCompSuc = SSAverageCompSuc + TotalNumberOfComparisons;
SSNumberKeysSuc ++;
}
else
{
SSAverageCompFailed = SSAverageCompFailed + TotalNumberOfComparisons;
SSNumberKeysFailed ++;
}
}
long estimatedTime = System.nanoTime() - startTime;
if (NumberOfKeys != 0)
SSAverageAccessTime = Math.round((estimatedTime/NumberOfKeys));
else
SSAverageAccessTime = 0;
if(SSNumberKeysSuc != 0)
SSAverageCompSuc = Math.round (SSAverageCompSuc / SSNumberKeysSuc) ;
else
SSAverageCompSuc = 0;
if (SSNumberKeysFailed != 0)
SSAverageCompFailed = Math.round (SSAverageCompFailed / SSNumberKeysFailed) ;
else
SSNumberKeysFailed = 0;
return;
}
public void BinarySearch()
{
// makes a temporary array the length of the number of data items we gave it int[] tempArray = new int[NumberOfDataItems];
// copies a portion of the original array (origionalArray = new int[1000000] above) that has the data inputs
// we are copying only the portion of the original array the was given the data inputs when we opened the data item .txt
for (int i = 0; i < NumberOfDataItems; i ++)
{
tempArray[i]=OriginalArray[i];
}
// takes the temporary array and sorts it
java.util.Arrays.sort(tempArray);
BSAverageAccessTime = 0;
BSAverageCompSuc = 0;
BSAverageCompFailed = 0;
BSNumberKeysSuc = 0;
BSNumberKeysFailed = 0;
int SearchKey;
int TotalNumberOfComparisons;
long startTime = System.nanoTime();
boolean found = false;
int low = 0;
int high = tempArray.length-1;
// sets the midpoint
int middle = (low-high)/2;
for(int k = 0; k<NumberOfKeys; k++)
{
SearchKey = KeysArray[k];
TotalNumberOfComparisons = 0;
for (int d=0; d< Math.log(tempArray.length -1); d++)
{
TotalNumberOfComparisons++;
// makes sure low doesn't go out of bounds
if (low < 0)
{
low = 0;
}
// make sure high doesn't go out of bounds
if(high >= tempArray.length)
{
high = tempArray.length-1;
}
// checks the midpoint against the key we are using
if (SearchKey == tempArray[middle])
{
found = true;
}
// makes sure that if the midpoint doesn't equal the key we get false
else
if (low == high && SearchKey != tempArray[middle])
{
found = false;
}
// if the key is greater than the middle we check the upper portion
else
if (SearchKey > tempArray[middle])
{
low = (middle +1);
}
// if the key is less than the middle we check the lower portion
else
if (SearchKey < tempArray[middle])
high = (middle -1);
if (found)break;
}
if(found)
{
BSAverageCompSuc = BSAverageCompSuc + TotalNumberOfComparisons;
BSNumberKeysSuc ++;
}
else
{
BSAverageCompFailed = BSAverageCompFailed + TotalNumberOfComparisons;
BSNumberKeysFailed ++;
}
}
long estimatedTime = System.nanoTime() - startTime;
if (NumberOfKeys != 0)
BSAverageAccessTime = Math.round((estimatedTime/NumberOfKeys));
else
BSAverageAccessTime = 0;
if(BSNumberKeysSuc != 0)
BSAverageCompSuc = Math.round (BSAverageCompSuc / BSNumberKeysSuc) ;
else
BSAverageCompSuc = 0;
if (BSNumberKeysFailed != 0)
BSAverageCompFailed = Math.round (BSAverageCompFailed / BSNumberKeysFailed) ;
else
BSNumberKeysFailed = 0;
return;
}
public void HashedSearch()
{
HSAverageAccessTime = 0;
HSAverageCompSuc = 0;
HSAverageCompFailed = 0;
HSNumberKeysSuc = 0;
HSNumberKeysFailed = 0;
int SearchKey;
int TotalNumberOfComparisons;
long startTime = System.nanoTime();
boolean found = false;
}
public int FindPrime()
{
return 0;
}
public void Initialize()
{
}
public void BHSearch()
{
}
}
Here is the Java GUI Code:
// GUI-related imports
import java.awt.*;
import java.awt.event.*;
// File-related imports
import java.io.IOException;
public class Project04 extends Frame implements ActionListener
{
ArrayOperations arr = new ArrayOperations();
String command = "";
public static void main(String[] args)
{
Frame frame = new Project04();
frame.setResizable(false);
frame.setSize(900,620);
frame.setVisible(true);
}
public Project04()
{
setTitle("Search Routines");
// Create Menu Bar and menu items
MenuBar mb = new MenuBar();
setMenuBar(mb);
// Create Menu Group Labeled "File"
Menu FileMenu = new Menu("File");
// Add it to Menu Bar
mb.add(FileMenu);
// Create Menu Items
// Add action Listener
// Add to "File" Menu Group
MenuItem miOpen = new MenuItem("Open");
miOpen.addActionListener(this);
FileMenu.add(miOpen);
MenuItem miExit = new MenuItem("Exit");
miExit.addActionListener(this);
FileMenu.add(miExit);
// Create Menu Group Labeled "File"
Menu SearchMenu = new Menu("Search");
// Add it to Menu Bar
mb.add(SearchMenu);
// Create Menu Items
// Add action Listener
// Add to "Search" Menu Group
MenuItem miSequentialSearch = new MenuItem("Sequential Search");
miSequentialSearch.addActionListener(this);
SearchMenu.add(miSequentialSearch);
MenuItem miBinarySearch = new MenuItem("Binary Search");
miBinarySearch.addActionListener(this);
SearchMenu.add(miBinarySearch);
MenuItem miHashedSearch = new MenuItem("Hashed Search");
miHashedSearch.addActionListener(this);
SearchMenu.add(miHashedSearch);
WindowListener l = new WindowAdapter()
{
public void windowClosing(WindowEvent ev)
{
System.exit(0);
}
public void windowActivated(WindowEvent ev)
{
repaint();
}
public void windowStateChanged(WindowEvent ev)
{
repaint();
}
};
ComponentListener k = new ComponentAdapter()
{
public void componentResized(ComponentEvent e)
{
repaint();
}
};
// register listeners
this.addWindowListener(l);
this.addComponentListener(k);
}
//******************************************************************************
// called by windows manager whenever the application window performs an action
// (select a menu item, close, resize, ....
//******************************************************************************
public void actionPerformed (ActionEvent ev)
{
// figure out which command was issued
command = ev.getActionCommand();
// take action accordingly
if("Open".equals(command))
{
try
{
arr.ReadDataFile();
arr.ReadKeysFile();
}
catch (IOException ioe)
{
System.exit(0);
}
repaint();
}
else
if("Exit".equals(command))
{
System.exit(0);
}
else
if("Sequential Search".equals(command))
{
arr.SequentialSearch();
repaint();
}
if("Binary Search".equals(command))
{
arr.BinarySearch();
repaint();
}
if("Hashed Search".equals(command))
{
arr.HashedSearch();
repaint();
}
if("Bucket Hashed Search".equals(command))
{
arr.BHSearch();
repaint();
}
}
//********************************************************
// called by repaint() to redraw the screen
//********************************************************
public void paint(Graphics g)
{
if("Open".equals(command))
{
// Acknowledge that file was opened
if (arr.DataFileName != null)
{
g.drawString("File -- "+arr.DataFileName+" -- was successfully opened", 300, 200);
g.drawString("Number of Data Items = "+Integer.toString(arr.NumberOfDataItems), 330, 250);
}
else
{
g.drawString("NO Data File is Open", 300, 200);
}
if (arr.KeysFileName != null)
{
g.drawString("File -- "+arr.KeysFileName+" -- was successfully opened", 300, 300);
g.drawString("Number of Keys = "+Integer.toString(arr.NumberOfKeys), 330, 350);
}
else
{
g.drawString("NO Keys File is Open", 300, 300);
}
return;
}
if("Sequential Search".equals(command) || "Binary Search".equals(command)||
"Hashed Search".equals(command) || "Bucket Hashed Search".equals(command) )
{
g.drawRect(100, 100, 700, 420);
g.drawString("Experiment", 135, 200);
g.drawLine(250,100,250,520);
g.drawString("Data File Attributes -- "+Integer.toString(arr.NumberOfDataItems)+" Data Items", 450, 130);
g.drawString("Key File Attributes -- "+Integer.toString(arr.NumberOfKeys)+" Keys", 450, 155);
g.drawLine(250,175,800,175);
g.drawString("Measured Criteria", 475,190 );
g.drawLine(250,215,800,215);
g.drawString("Successful Search", 410, 230);
g.drawString("Unccessful Search", 640, 230);
g.drawLine(360,245,800,245);
g.drawLine(100,310,800,310);
g.drawString("Sequential Search", 110, 325);
g.drawLine(100,340,800,340);
g.drawString("Average", 285, 260);
g.drawString("Access", 285, 275);
g.drawString("Time", 290, 290);
g.drawLine(360,215,360,520);
g.drawString("#", 400, 260);
g.drawString("Keys", 400, 275);
g.drawString("Found", 390, 290);
g.drawLine(470,245,470,520);
g.drawString("Average", 500, 260);
g.drawString("No. Of", 500, 275);
g.drawString("Comparisons", 485, 290);
g.drawLine(580,215,580,520);
g.drawString("# ", 620, 260);
g.drawString("Keys", 620, 275);
g.drawString("Not Found", 600, 290);
g.drawLine(690,245,690,520);
g.drawString("Average", 720, 260);
g.drawString("No. Of", 720, 275);
g.drawString("Comparisons", 700, 290);
g.drawString(Long.toString(arr.SSAverageAccessTime), 255, 325);
g.drawString(Long.toString(arr.SSNumberKeysSuc), 365, 325);
g.drawString(Long.toString(arr.SSAverageCompSuc), 475, 325);
g.drawString(Long.toString(arr.SSNumberKeysFailed), 585, 325);
g.drawString(Long.toString(arr.SSAverageCompFailed), 695, 325);
g.drawString("Binary Search", 110, 355);
g.drawLine(100,370,800,370);
g.drawString(Long.toString(arr.BSAverageAccessTime), 255, 355);
g.drawString(Long.toString(arr.BSNumberKeysSuc), 365, 355);
g.drawString(Long.toString(arr.BSAverageCompSuc), 475, 355);
g.drawString(Long.toString(arr.BSNumberKeysFailed), 585, 355);
g.drawString(Long.toString(arr.BSAverageCompFailed), 695, 355);
g.drawString("Hashed Search", 110, 385);
g.drawLine(100,400,800,400);
g.drawString(Long.toString(arr.HSAverageAccessTime), 255, 385);
g.drawString(Long.toString(arr.HSNumberKeysSuc), 365, 385);
g.drawString(Long.toString(arr.HSAverageCompSuc), 475, 385);
g.drawString(Long.toString(arr.HSNumberKeysFailed), 585, 385);
g.drawString(Long.toString(arr.HSAverageCompFailed), 695, 385);
// add code to display results for other searches
}
}
}
You are doing a wrong calculation
change below:
int middle = (low-high)/2;
to:
int middle = (high-low)/2;
low is always less than high so you are getting a negative number and that negative index will not exist in your array.
Although I have not checked any other possible problems or the algorithm's validity, the above is the solution to the problem you are having
What i am trying to do is when i click a button, i copy some files from a portable drive like usb and copy those files to my local drive, then i read all csv files which i copied ealier and i put it's values in an arraylist and inject it to database, and then i can delete those files, and i want to show the process in progress bar based on process completion. so this is what i do :
void main()
{
JButton btnTransfer = new JButton("Transfer");
Image transferIMG = ImageIO.read(new File("C:\\Users\\User\\Desktop\\images\\transfer.png"));
btnTransfer.setIcon(new ImageIcon(transferIMG));
btnTransfer.setPreferredSize(new Dimension(110, 90));
btnTransfer.setOpaque(false);
btnTransfer.setContentAreaFilled(false);
btnTransfer.setBorderPainted(false);
btnTransfer.setVerticalTextPosition(SwingConstants.BOTTOM);
btnTransfer.setHorizontalTextPosition(SwingConstants.CENTER);
btnTransfer.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
File csvpath = new File(fileList1.getSelectedValue() + "\\salestablet\\report\\csv");
File htmlpath = new File(fileList1.getSelectedValue() + "\\salestablet\\report\\html");
String removepath = fileList1.getSelectedValue() + "\\salestablet\\report";
if(csvpath.listFiles().length > 0 && htmlpath.listFiles().length > 0)
{
File[] csvarr = csvpath.listFiles();
File[] htmlarr = htmlpath.listFiles();
try
{
copyFileUsingStream(csvarr, htmlarr, txt.getText(), removepath);
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
JPanel ButtonCont = new JPanel(new GridLayout(4, 1, 5, 0));
ButtonCont.setBackground(Color.LIGHT_GRAY);
ButtonCont.add(btnTransfer);
gui.add(ButtonCont , BorderLayout.EAST);
frame.setContentPane(gui);
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.setMinimumSize(new Dimension(900, 100));
frame.pack();
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static void copyFileUsingStream(File[] csvsources, File[] htmlsources, String dest, String removepath) throws IOException
{
int count = 0;
int MaxCount = countprocess(csvsources, htmlsources);
progressBar = new JProgressBar(0, MaxCount);
progressBar.setStringPainted(true);
InputStream is = null;
OutputStream os = null;
String csvfolderpath = dest + "\\csv";
String htmlfolderpath = dest + "\\html";
if(!(new File(csvfolderpath)).exists())
{
(new File(csvfolderpath)).mkdirs(); //create csv folder;
}
if(!(new File(htmlfolderpath)).exists())
{
(new File(htmlfolderpath)).mkdirs(); //create csv folder;
}
for(int i= 0; i < csvsources.length; i++) //copy all csv files to csv folder
{
try
{
is = new FileInputStream(csvsources[i]);
os = new FileOutputStream(csvfolderpath + "\\" + csvsources[i].getName());
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0)
{
os.write(buffer, 0, length);
}
}
finally
{
count += 1;
progressBar.setValue((count / MaxCount) * 100);
//progressBar.repaint();
//progressBar.revalidate();
progressBar.update(progressBar.getGraphics());
is.close();
os.close();
}
}
for(int i= 0; i < htmlsources.length; i++) //copy all html, images and css to html folder
{
if(htmlsources[i].isFile())
{
try
{
is = new FileInputStream(htmlsources[i]);
os = new FileOutputStream(htmlfolderpath + "\\" + htmlsources[i].getName());
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0)
{
os.write(buffer, 0, length);
}
}
finally
{
count += 1;
progressBar.setValue((count / MaxCount) * 100);
//progressBar.repaint();
//progressBar.revalidate();
progressBar.update(progressBar.getGraphics());
is.close();
os.close();
}
}
else if(htmlsources[i].isDirectory()) //for subfolder
{
String path = dest + "\\html\\" + htmlsources[i].getName();
if(!new File(path).exists())
{
(new File(path)).mkdirs(); //create subfolder;
}
File[] arr = (new File(htmlsources[i].getAbsolutePath())).listFiles();
for(int j = 0; j < arr.length; j++)
{
if(arr[j].isFile())
{
try
{
is = new FileInputStream(arr[j]);
os = new FileOutputStream(path + "\\" + arr[j].getName());
byte[] buffer = new byte[1000000];
int length;
while ((length = is.read(buffer)) > 0)
{
os.write(buffer, 0, length);
}
}
finally
{
if(htmlsources[i].getName().contains("images"))
{
count += 1;
progressBar.setValue((count / MaxCount) * 100);
//progressBar.repaint();
//progressBar.revalidate();
progressBar.update(progressBar.getGraphics());
}
is.close();
os.close();
}
}
}
}
}
ArrayList<String > DBValues = new ArrayList<String>(); //read all csv files values
File f1 = new File(csvfolderpath);
for(int i = 0; i < f1.listFiles().length; i++)
{
if(f1.listFiles()[i].isFile())
{
FileReader fl = new FileReader(f1.listFiles()[i]);
BufferedReader bfr = new BufferedReader(fl);
for(int j = 0; j < 2; j++)
{
if(j == 1)
{
DBValues.add(bfr.readLine());
count += 1;
progressBar.setValue((count / MaxCount) * 100);
//progressBar.repaint();
//progressBar.revalidate();
progressBar.update(progressBar.getGraphics());
}
else
{
bfr.readLine();
}
}
bfr.close();
}
}
/*for(int x = 0; x < DBValues.size(); x++)
{
//System.out.println(DBValues.get(x));
}*/
//removing csv in local computer
File f2 = new File(csvfolderpath);
File[] removelist = f2.listFiles();
for(int x = 0; x < removelist.length; x++)
{
if(removelist[x].isFile())
{
removelist[x].delete();
count += 1;
progressBar.setValue((count / MaxCount) * 100);
// progressBar.repaint();
//progressBar.revalidate();
progressBar.update(progressBar.getGraphics());
}
}
//removing csv in device
File f3 = new File(removepath + "\\csv");
if(f3.isDirectory())
{
removelist = f3.listFiles();
for(int y = 0; y < removelist.length; y++)
{
try
{
if(removelist[y].isFile())
{
//System.out.println(removelist[y].getName());
removelist[y].delete();
count += 1;
progressBar.setValue((count / MaxCount) * 100);
//progressBar.repaint();
// progressBar.revalidate();
progressBar.update(progressBar.getGraphics());
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
//removing html and images in device
File f4 = new File(removepath + "\\html");
if(f4.isDirectory())
{
removelist = f4.listFiles();
for(int z = 0; z < removelist.length; z++)
{
try
{
if(removelist[z].isFile())
{
removelist[z].delete();
count += 1;
progressBar.setValue((count / MaxCount) * 100);
// progressBar.repaint();
// progressBar.revalidate();
progressBar.update(progressBar.getGraphics());
}
else if(removelist[z].isDirectory())
{
if(removelist[z].getName().contains("images"))
{
File[] subfolder = removelist[z].listFiles();
for (int idx = 0; idx < subfolder.length; idx++)
{
if(subfolder[idx].isFile())
{
subfolder[idx].delete();
count += 1;
progressBar.setValue((count / MaxCount) * 100);
// progressBar.repaint();
// progressBar.revalidate();
progressBar.update(progressBar.getGraphics());
}
}
}
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
/* JProgressBar progressBar = new JProgressBar();
progressBar.setValue(25);
progressBar.setStringPainted(true);*/
Border border = BorderFactory.createTitledBorder("Reading...");
progressBar.setBorder(border);
gui.add(progressBar, BorderLayout.SOUTH);
gui.repaint();
gui.revalidate();
// System.out.println(count);
}
private static int countprocess(File[] csv, File[] html_image)
{
int x = 0;
int y = 0;
int z = 0;
for(int i = 0; i < csv.length; i++)
{
if(csv[i].isFile())
{
x += 1;
}
} //get total count of csv files throught loop
for(int i = 0; i < html_image.length; i++)
{
if(html_image[i].isFile())
{
y += 1;
}
else if(html_image[i].isDirectory())
{
if(html_image[i].getName().contains("images"))
{
File[] flist = html_image[i].listFiles();
for(int j = 0; j < flist.length; j++)
{
z += 1;
}
}
} //get total count of html and images files throught loop
}
return ((4*x) + (2*y) + (2*z));
}
so i tried to refresh my progress bar value by setting it's value like this
progressBar.setValue((count / MaxCount) * 100);
but somehow i can't make it to work, my progress bar does not showing it's progress like 1% 2% 3%.. 10% and so on.. instead it's only show 100% when it's process completed.. what i miss here?
note : i also have tried to set my progress bar value this way progressBar.setValue(count); still no luck.
Reviewing your whole code will take a while. But, inside your btnTransfer.addActionListener's actionPerformed function you are trying to copy stream which might take a while. Any kind of event listener is performed in event dispatch thread. Please refer to this answer for more details.
Now as a quick solution:
put your copyFileUsingStream(csvarr, htmlarr, txt.getText(), removepath); function inside a in-line thread:
new Thread()
{
public void run()
{
copyFileUsingStream(csvarr, htmlarr, txt.getText(), removepath);
}
}.start();
}
Put your progress update of JProgressBar inside SwingUtilities.invokeLater and make the (count/MaxCount) computation by casting one of them to double, as follows:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
count += 1;
progressBar.setValue((int) (((double)count/ MaxCount) * 100));
}
});
as count is local to the copyFileUsingStream function, please try to declare it in your class context to access and change.
But SwingWorker is preferable for this kind of task.
Tutorial Resources:
Worker Threads and SwingWorker
How to use progress bars with swing worker
ProgressBar Demo with SwingWorker
You are setting a value in your progress bar to a percent complete. But the max value of your progress bar is actually the total number of items.
Instead, you need to just set your progressbar value to your current count and get rid of the calculation for the %.
Something like:
progressBar.setValue(count );
Also you should be doing your long running task in a SwingWorker thread so that you don't have to force repainting of the GUI.
So I was tinkering with this code that I found http://docs.oracle.com/javase/tutorial/2d/printing/examples/PaginationExample.java
I altered the page size to 300, 400 when I tried printing to XPS the first page is always default and the following is 300,400, I want to is set all printed pages to 300,400
below is the code
package app;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.print.*;
public class PaginationExample implements Printable, ActionListener {
int[] pageBreaks; // array of page break line positions.
/* Synthesise some sample lines of text */
String[] textLines;
private void initTextLines() {
if (textLines == null) {
int numLines = 200;
textLines = new String[numLines];
for (int i = 0; i < numLines; i++) {
textLines[i] = "This is line number " + i;
}
}
}
public int print(Graphics g, PageFormat pf, int pageIndex)
throws PrinterException {
pf.setPaper(paper);
Font font = new Font("Serif", Font.PLAIN, 10);
FontMetrics metrics = g.getFontMetrics(font);
int lineHeight = metrics.getHeight();
if (pageBreaks == null) {
initTextLines();
int linesPerPage = (int) (pf.getImageableHeight() / lineHeight);
int numBreaks = (textLines.length - 1) / linesPerPage;
pageBreaks = new int[numBreaks];
for (int b = 0; b < numBreaks; b++) {
pageBreaks[b] = (b + 1) * linesPerPage;
}
}
if (pageIndex > pageBreaks.length) {
return NO_SUCH_PAGE;
}
/* User (0,0) is typically outside the imageable area, so we must
* translate by the X and Y values in the PageFormat to avoid clipping
* Since we are drawing text we
*/
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
/* Draw each line that is on this page.
* Increment 'y' position by lineHeight for each line.
*/
int y = 0;
int start = (pageIndex == 0) ? 0 : pageBreaks[pageIndex - 1];
int end = (pageIndex == pageBreaks.length)
? textLines.length : pageBreaks[pageIndex];
for (int line = start; line < end; line++) {
y += lineHeight;
g.drawString(textLines[line], 0, y);
}
/* tell the caller that this page is part of the printed document */
return PAGE_EXISTS;
}
public void actionPerformed(ActionEvent e) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
boolean ok = job.printDialog();
if (ok) {
try {
job.print();
} catch (PrinterException ex) {
/* The job did not successfully complete */
}
}
}
private static Paper paper;
public static void main(String args[]) {
paper = new Paper();
paper.setSize(300, 400);
try {
String cn = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(cn); // Use the native L&F
} catch (Exception cnf) {
}
JFrame f = new JFrame("Printing Pagination Example");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JButton printButton = new JButton("Print Pages");
printButton.addActionListener(new PaginationExample());
f.add("Center", printButton);
f.pack();
f.setVisible(true);
}
}
Try to use the Book class which is used in this thread.
Book pBook = new Book();
pBook.append(this, pPageFormat);
pPrinterJob.setPageable(pBook);
pPrinterJob.print();
here is some code I'm trying to get working. Basically I need to keep the process open, and feed it new commands in a single session. Once the "exit" string command is issued the process should finish. Appreciate help....
Process process;
ArrayList<String>command;
ProcessBuilder builder;
Map<String, String> environ;
BufferedWriter bw;
BufferedReader br;
BufferedReader buffErrorStreamReader;
....
try
{
command = new ArrayList<String>();
command.add("cmd.exe");
command.add("/c");
//command.add(currentLine);
builder = new ProcessBuilder(command);
environ = builder.environment();
builder.directory(new File("C://"));
process = builder.start();
}catch(Exception e)
{
System.out.println(e);
}
//Get a System.in Stream
OutputStream output = process.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(output);
bw = new BufferedWriter(osw);
//Get a System.out Stream
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
br = new BufferedReader(isr);
//Get a System.err Stream
InputStream errorStream = process.getErrorStream();
InputStreamReader errorStreamReader = new InputStreamReader(errorStream);
buffErrorStreamReader = new BufferedReader(errorStreamReader);
....
//Read the command from my text component terminal
String currentLine = getCurrentLine();
///pass command to pipe input
bw.write(currentLine);
System.out.println("wrote: "+currentLine);
///print response
String line;
while ((line = br.readLine()) != null)
{
System.out.println(line);
//term.println(line);
}
///print any error response
String errorLine;
while ((errorLine = buffErrorStreamReader.readLine()) != null)
{
System.out.println(errorLine);
//term.println(errorLine);
}
You're reading both the error stream and the input stream until EOS, which won't happen until the process exits (or, so rarely that I've never seen it in 30+ years, closes stdout and stderr). The usual practice is to (a) merge the error and output streams and/or (b) read it/them in separate threads, so that in this case you can keep feeding input from its source without having to bother with the resulting output if any, which in the nature of things you can't know too much about in an external process.
My full code is working. I have a terminal that takes a command from the current line on a canvas. Then it assembles a process builder with: "cmd.exe", "/c" and "the command string from the current line" parameters. Finally it gets the builder environment and sets the builder directory. It then starts the process and gets both Input and Error Streams for the process. Then it prints these responses to my canvas terminal. However, the problem with my approach is that I am opening a new cmd.exe (dos command prompt) with every process. So basically, its a non interactive terminal because there is no session established between command submissions (new processes). The process just takes the command, prints the output and terminates each time. So my question is how can I implement an interactive terminal session. I have successfully implemented the ability to change directories by saving the current path and passing it to the new process with the builder.directory method. Also it may be possible to do the same thing for environment var's with the builder.environment (but I cant figure that out). That would give the impression of a real session. I have also tried the threading for the streams and it does work. But I must be doing it wrong as the process terminates after the thread prints the command response.
Here is the code for my Terminal, in two pieces. The code im talking about is located in the switch statement for the VK.ENTER key.
NB. If you are changing directories it will only work with absoulute paths. Eg "cd C://Users/Aubrey/" not "cd /Aubrey" in the Users directory!!!
/*
* Terminal.java - A convienence console.
*
* http://www.splashportal.net
* 30/09/2012
*/
package terminal;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import javax.swing.JScrollPane;
public class Terminal extends Canvas
{
static final long serialVersionUID = 5479170142892558288L;
public static int WIDTH = 80, HEIGHT = 200;
static Process process;
public static final Color
WHITE = new Color(0xffffff),
RED = new Color(0xff0000),
GREEN = new Color(0x00cc00),
BROWN = new Color(0x996600),
BLUE = new Color(0x0000ff),
DARK_GREEN = new Color(0x009900),
DARK_BLUE = new Color(0x000099),
LIGHT_GREY = new Color(0x999999),
DARK_GREY = new Color(0x666666),
CYAN = new Color(0x00ffff),
DARK_CYAN = new Color(0x009999),
DARK_YELLOW = new Color(0x999900),
MAGENTA = new Color(0xff00ff),
YELLOW = new Color(0xffff00),
PURPLE = new Color(0x990099),
BLACK = new Color(0x000000);
private static final Color[] COLORS = {
WHITE , // 0 #
RED , // 1 A
GREEN , // 2 B
BROWN , // 3 C
BLUE , // 4 D
DARK_GREEN , // 5 E
DARK_BLUE , // 6 F
LIGHT_GREY , // 7 G
DARK_GREY , // 8 H
CYAN , // 9 I
DARK_CYAN , // 10 J
DARK_YELLOW , // 11 K
MAGENTA , // 12 L
YELLOW , // 13 M
PURPLE , // 14 N
BLACK , // 15 O
};
public static final int EFFECTS_UNDERLINE = 1;
private static final int
ESC_NORMAL = 0,
ESC_ESCAPE = 1,
ESC_POS_Y = 2,
ESC_POS_X = 3,
ESC_FGCOLOR = 4,
ESC_BGCOLOR = 5;
static boolean isBreak=false;
static int heightCounter;
static ArrayList lines;
static Terminal term;
static Frame f;
static File startPath;
public static Color getColor(int i)
{
return COLORS[i & 0x0f];
}
static String newPath = System.getenv("temp");
public static void main(String[] args)
{
f = new Frame("Terminal Test");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
f.dispose();
}
} );
term = new Terminal();
//add buffer_ image to a scrollpane somehow?
scrollPane = new ScrollPane();
scrollPane.add(term, buffer_);
// disabling forward focus traversal allows TAB to reach the component
term.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
Collections.EMPTY_SET);
term.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent ke) {
// handle special keys
switch(ke.getKeyCode()) {
case KeyEvent.VK_UP:
term.print("\033A");
term.repaint();
break;
case KeyEvent.VK_DOWN:
term.print("\033B");
term.repaint();
break;
case KeyEvent.VK_RIGHT:
term.print("\033C");
term.repaint();
break;
case KeyEvent.VK_LEFT:
term.print("\033D");
term.repaint();
break;
case KeyEvent.VK_ENTER:
//flag set to block printing of ">>" prompt
isR=true;
try{
String currentLine = getCurrentLine();
ArrayList<String>command = new ArrayList<String>();
command.add("cmd.exe");
command.add("/c");
command.add(currentLine);
System.out.println("Line-IN: "+currentLine);
ProcessBuilder builder = new ProcessBuilder(command);
Map<String, String> environ = builder.environment();
if (currentLine.startsWith("cd")){
//startPath = new File(".").getAbsoluteFile();
//if an absolute path is specified and exists
if(new File(currentLine.substring(3)).exists())
newPath=currentLine.substring(3);
System.out.println("Directory : "+new File(newPath));
builder.directory(new File(newPath));
process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
InputStream errorStream = process.getErrorStream();
InputStreamReader errorStreamReader = new InputStreamReader(errorStream);
BufferedReader buffErrorStreamReader = new BufferedReader(errorStreamReader);
String line;
//term.println("");
while ((line = br.readLine()) != null) {
System.out.println(line);
term.println(line);
}
String errorLine;
term.println("");
while ((errorLine = buffErrorStreamReader.readLine()) != null) {
//System.out.println(line);
term.println(errorLine);
}
buffErrorStreamReader.close();
br.close();
//not sure how to use this method to allow for an interactive prompt?
//for example a "dir /p" command should allow the output to be paged per keypress!
process.waitFor();
//flags set to allow printing of ">>" prompt
isR=false;
isNew=true;
System.out.println("Program terminated!");
}else if(currentLine.startsWith("exit")||currentLine.startsWith("quit")){
System.exit(0);
}else if(currentLine.startsWith("dir /p")){
//try using dos batch?
System.out.println("page...");
command = new ArrayList<String>();
command.add("cmd.exe");
command.add("dir");
builder.directory(new File(newPath));
process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
//write out to a FLAT FILE.
File temp = new File("temp");
PrintWriter tempOut = new PrintWriter(new FileWriter(temp));
while ((line = br.readLine()) != null) {
System.out.println(line);
tempOut.println(line);
}
//not sure how to use this method to allow for an interactive prompt?
//for example a "dir /p" command should allow the output to be paged per keypress!
process.waitFor();
//flags set to allow printing of ">>" prompt
br.close();
tempOut.flush();
tempOut.close();
captureLines();
int index = 0;
printPage(index);
isR=false;
isNew=true;
System.out.println("Program terminated!");
}else
{
builder.directory(new File(newPath));
process = builder.start();
Thread t = new Thread() {
public void run() {
try{
System.out.println("blah");
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
InputStream errorStream = process.getErrorStream();
InputStreamReader errorStreamReader = new InputStreamReader(errorStream);
BufferedReader buffErrorStreamReader = new BufferedReader(errorStreamReader);
String line;
//term.println("");
while ((line = br.readLine()) != null) {
//System.out.println(line);
term.println(line);
}
String errorLine;
//term.println("");
while ((errorLine = buffErrorStreamReader.readLine()) != null) {
//System.out.println(line);
term.println(errorLine);
}
buffErrorStreamReader.close();
br.close();
//not sure how to use this method to allow for an interactive prompt?
//for example a "dir /p" command should allow the output to be paged per keypress!
process.waitFor();
//flags set to allow printing of ">>" prompt
isR=false;
isNew=true;
term.println("");
}catch(Exception e){System.out.println(e);}
}
};
t.start();
System.out.println("Program terminated!");
}
}catch(Exception e){System.out.println(e);}
}
}
public void keyTyped(KeyEvent ke) {
char c = ke.getKeyChar();
if( c == KeyEvent.CHAR_UNDEFINED ) {
// handle special keys
switch(ke.getKeyCode()) {
case KeyEvent.VK_TAB:
c = '\t';
break;
case KeyEvent.VK_ESCAPE:
c = (char)27;
break;
}
}
if( c != KeyEvent.CHAR_UNDEFINED ) {
term.print(c);
term.repaint();
}
}
} );
f.add(scrollPane, BorderLayout.CENTER);
term.validate();
scrollPane.setSize(598, 316);
//f.setSize(700, 400);
f.pack();
f.setVisible(true);
term.println(DARK_GREY, WHITE, "vTerminal");
//term.println(DARK_GREY, WHITE, ">>");
term.requestFocus();
}
private int tileWidth_ = 8;
private int tileHeight_ = 12;
private static TerminalLine[] line_;
private int xCursor_;
private static int yCursor_;
private int xCursorSave_;
private int yCursorSave_;
private boolean wrap_ = true;
private boolean scroll_ = true;
private boolean cursorVisible_ = true;
private int tab_ = 8;
private int xOffset_ = 0;
private int yOffset_ = 0;
private int escapeMode_ = ESC_NORMAL;
/** First character held in an ESC Y Position Cursor command. */
private int escapeHold_ = -1;
private boolean reverseVideo_;
private byte effects_;
private static Image buffer_;
private static ScrollPane scrollPane;
private static Boolean isNew = false;
private static Boolean isR = false;
//second part to the working code
/** Creates a new terminal. */
public Terminal()
{
line_ = new TerminalLine[HEIGHT];
for(int y = 0; y < HEIGHT; ++y) {
line_[y] = new TerminalLine(WIDTH);
}
setBackground(DARK_GREY);
setForeground(LIGHT_GREY);
setFont( new Font("Monospaced", Font.PLAIN, 12) );
clearScreen();
}
public static void captureLines(){
String line;
try{
heightCounter=Terminal.HEIGHT;
BufferedReader tempIn = new BufferedReader(new FileReader("temp"));
term.println("");
lines = new ArrayList();
while((line = tempIn.readLine())!=null)
{
lines.add(line);
}
tempIn.close();
}catch(Exception e){System.out.println(e);}
return;
}
public static void printPage(int index){
try{
if(index<lines.size()){
for (int i=0; i<25; i++){
if(index==lines.size())
return;
//System.out.println(index+" "+lines.get(index));
term.println(lines.get(index).toString());
index++;
}Thread.sleep(500);
printPage(index);
}else{return;}
}catch(Exception e){System.out.println(e);}
}
public static String getCurrentLine(){
TerminalLine currentLine = line_[getYCursor()];
String command="";
for(char c: currentLine.data){
command+= c;
}
String outString = command.substring(2);
return (outString.trim());
}
public synchronized void clearScreen()
{
for(int y = 0; y < HEIGHT; ++y) {
clearLine(y);
}
repaint();
}
public synchronized void clearLine(int line)
{
clearLine(line, 0, WIDTH-1);
}
public synchronized void clearLine(int y, int x0, int x1)
{
Color bg = getBackground();
Color fg = getForeground();
TerminalLine line = line_[y];
for(int x = x0; x <= x1; ++x) {
line.data[x] = ' ';
line.bgColor[x] = bg;
line.fgColor[x] = fg;
line.effects[x] = 0;
}
}
public synchronized boolean getCursorVisible()
{ return cursorVisible_; }
public synchronized char getData(int x, int y)
{
return line_[y].data[x];
}
public synchronized Color getBgColor(int x, int y)
{
return line_[y].bgColor[x];
}
public synchronized byte getEffects(int x, int y)
{
return line_[y].effects[x];
}
public synchronized Color getFgColor(int x, int y)
{
return line_[y].fgColor[x];
}
public synchronized Dimension getMaximumSize()
{
return getPreferredSize();
}
public synchronized Dimension getMinimumSize()
{
return getPreferredSize();
}
public synchronized Dimension getPreferredSize()
{
return new Dimension(WIDTH * tileWidth_, HEIGHT * tileHeight_);
}
public boolean getReverseVideo()
{ return reverseVideo_; }
public synchronized boolean getScroll()
{ return scroll_; }
public synchronized int getTab()
{ return tab_; }
public int getTileWidth()
{ return tileWidth_; }
public int getTileHeight()
{ return tileHeight_; }
public synchronized int getXOffset()
{ return xOffset_; }
public synchronized int getYOffset()
{ return yOffset_; }
public synchronized int getXCursor()
{ return xCursor_; }
public static synchronized int getYCursor()
{ return yCursor_; }
public synchronized void gotoxy(int x, int y)
{
xCursor_ = x;
yCursor_ = y;
}
public synchronized void print(String s)
{
print(null, null, s);
}
public synchronized void print(Color bg, Color fg, String s)
{
for(int i = 0, len = s.length(); i < len; ++i) {
print(bg, fg, s.charAt(i) );
}
repaint();
}
public synchronized void print(char c)
{
print(null, null, c);
}
public synchronized void print(Color bg, Color fg, char c)
{
if( escapeMode_ == ESC_NORMAL ) {
switch(c) {
case 7: // 7 = BEL, bell
bell();
break;
case '\b': // 8 = BS, backspace
--xCursor_;
break;
case '\t': // 9 = HT, tab
xCursor_ = ((xCursor_ + tab_) / tab_) * tab_;
break;
case '\n': // 10 = LF, newline
xCursor_ = 0;
++yCursor_;
//flag set to allow printing of ">>" prompt
isNew=true;
break;
case 11: // 11 = VT, vertical tab
case '\f': // 12 = FF, form feed
++yCursor_;
break;
case '\r': // 13 = CR, ignored because Java's newline is \n
break;
case 27: // 27 = ESC, enters escape mode
escapeMode_ = ESC_ESCAPE;
break;
case 127: { // 127 = DEL, right-delete
int yc = yCursor_;
TerminalLine line = line_[yc];
for(int x = xCursor_; x < WIDTH-1; ++x) {
line.setData(x, line.bgColor[x+1], line.fgColor[x+1],
line.data[x+1], line.effects[x+1] );
}
setData(WIDTH-1, yc, null, null, ' ');
break;
}
default:
if( c < 32 ) {
// unknown control character
bell();
} else {
setData(xCursor_, yCursor_, bg, fg, c);
++xCursor_;
}
}
} else {
escapeMode_ = doEscape(c);
}
// wrap cursor
if( xCursor_ < 0 ) {
if( wrap_ ) {
xCursor_ = WIDTH-1;
--yCursor_;
} else {
xCursor_ = 0;
}
} else if( xCursor_ >= WIDTH ) {
if( wrap_ ) {
xCursor_ = 0;
++yCursor_;
} else {
xCursor_ = WIDTH-1;
}
}
if( yCursor_ < 0 ) {
if( scroll_ ) {
scrollDown(0);
}
yCursor_ = 0;
} else if( yCursor_ >= HEIGHT ) {
if( scroll_ ) {
scrollUp(0);
}
yCursor_ = HEIGHT-1;
}
//cool flags here to print ">>" prompt: 1. when there is new line and 2. when the isR flag has detected the end of printing in the return event.
if(isR){
isNew=false;
}
if(isNew){
isNew=false;
print(DARK_GREY, YELLOW, ">>");
}
}
public synchronized void scrollDown(int topline)
{
// scroll down, exposing a blank line at top
// don't waste the existing array, recycle it.
TerminalLine line0 = line_[HEIGHT-1];
// move all lines down
for(int y = HEIGHT-1; y > topline; --y) {
line_[y] = line_[y-1];
}
// put it at the top
line_[topline] = line0;
clearLine(topline);
}
public synchronized void scrollUp(int topline)
{
// scroll up, exposing a blank line at bottom
// don't waste the existing array, recycle it.
TerminalLine line0 = line_[topline];
// move all lines up
for(int y = topline; y < HEIGHT-1; ++y) {
line_[y] = line_[y+1];
}
// put it at the end
line_[HEIGHT-1] = line0;
clearLine(HEIGHT-1);
}
private int doEscape(char c)
{
switch(escapeMode_) {
case ESC_NORMAL:
throw new IllegalStateException();
case ESC_ESCAPE:
// handled below
break;
case ESC_POS_Y:
escapeHold_ = Math.max(0, Math.min(HEIGHT-1, (int)(c - 32)));
return ESC_POS_X;
case ESC_POS_X:
yCursor_ = escapeHold_;
xCursor_ = Math.max(0, Math.min(WIDTH-1, (int)(c - 32)));
return ESC_NORMAL;
case ESC_FGCOLOR:
setForeground( getColor( (int)c ) );
return ESC_NORMAL;
case ESC_BGCOLOR:
setBackground( getColor( (int)c ) );
return ESC_NORMAL;
default:
throw new IllegalStateException("Unknown escape mode "+escapeMode_);
}
switch(c) {
case 24: // 24 = CAN, cancel escape
case 26: // 26 = SUB, cancel escape
case 27: // 27 = ESC, cancel escape
return ESC_NORMAL;
case 'A': // Cursor Up
if( yCursor_ > 0 ) {
--yCursor_;
}
return ESC_NORMAL;
case 'B': // Cursor Down
if( yCursor_ < HEIGHT-1 ) {
++yCursor_;
}
return ESC_NORMAL;
case 'C': // Cursor Forward
if( xCursor_ < WIDTH-1 ) {
++xCursor_;
}
return ESC_NORMAL;
case 'D': // Cursor Backward
if( xCursor_ > 0 ) {
--xCursor_;
}
return ESC_NORMAL;
case 'E': // Clear Screen, Home Cursor
clearScreen();
xCursor_ = 0;
yCursor_ = 0;
return ESC_NORMAL;
case 'H': // Home Cursor
xCursor_ = 0;
yCursor_ = 0;
return ESC_NORMAL;
case 'I': // Reverse Index
--yCursor_;
return ESC_NORMAL;
case 'J': // Erase to End of Page
clearLine(yCursor_, xCursor_, WIDTH-1);
for(int y = yCursor_+1; y < HEIGHT; ++y) {
clearLine(y);
}
return ESC_NORMAL;
case 'K': // Erase to End of Line
clearLine(yCursor_, xCursor_, WIDTH-1);
return ESC_NORMAL;
case 'L': // Insert Line
scrollDown(yCursor_);
xCursor_ = 0;
return ESC_NORMAL;
case 'M': // Delete Line
scrollUp(yCursor_);
xCursor_ = 0;
return ESC_NORMAL;
case 'N': { // Delete Character
int yc = yCursor_;
TerminalLine line = line_[yc];
for(int x = xCursor_; x < WIDTH-1; ++x) {
line.setData(x, line.bgColor[x+1], line.fgColor[x+1],
line.data[x+1], line.effects[x+1] );
}
setData(WIDTH-1, yc, null, null, ' ');
break;
}
case 'Y': // Position Cursor
return ESC_POS_Y;
case 'b': // Set Foreground Color
return ESC_FGCOLOR;
case 'c': // Set Background Color
return ESC_BGCOLOR;
case 'd': { // Erase from Beginning of Display
int xc = xCursor_, yc = yCursor_;
clearLine(yc, 0, xc);
for(int y = 0; y < yc; ++y) {
clearLine(y);
}
return ESC_NORMAL;
}
case 'j': // Save Cursor Position
xCursorSave_ = xCursor_;
yCursorSave_ = yCursor_;
return ESC_NORMAL;
case 'k': // Restore Cursor Position
xCursor_ = xCursorSave_;
yCursor_ = yCursorSave_;
return ESC_NORMAL;
case 'l': // Erase Entire Line
clearLine(yCursor_);
xCursor_ = 0;
return ESC_NORMAL;
case 'm': // Enable Cursor
cursorVisible_ = true;
return ESC_NORMAL;
case 'n': // Disable Cursor
cursorVisible_ = false;
return ESC_NORMAL;
case 'o': // Erase from Beginning of Line
clearLine(yCursor_, 0, xCursor_);
return ESC_NORMAL;
case 'p': // Enable Reverse Video
reverseVideo_ = true;
return ESC_NORMAL;
case 'q': // Disable Reverse Video
reverseVideo_ = false;
return ESC_NORMAL;
case 'r': // Enable Underlining
effects_ |= EFFECTS_UNDERLINE;
return ESC_NORMAL;
case 'u': // Disable Underlining
effects_ &= ~EFFECTS_UNDERLINE;
return ESC_NORMAL;
case 'v': // Enable Wrapping
wrap_ = true;
return ESC_NORMAL;
case 'w': // Disable Wrapping
wrap_ = false;
return ESC_NORMAL;
}
// unknown escape code
bell();
return ESC_NORMAL;
}
public synchronized void println(String s)
{
println(null, null, s);
}
public synchronized void println(Color bg, Color fg, String s)
{
print(bg, fg, s);
print(bg, fg, '\n');
repaint();
}
public synchronized void setCursorVisible(boolean c)
{ cursorVisible_ = c; }
public synchronized void setData(int x, int y, char c)
{
setData(x, y, null, null, c);
}
public synchronized void setData(int x, int y, Color bg, Color fg, char c)
{
setData(x, y, bg, fg, c, effects_);
}
public synchronized void setData(int x, int y, Color bg, Color fg, char c, byte effects)
{
if( bg == null ) {
bg = getBackground();
}
if( fg == null ) {
fg = getForeground();
}
if( reverseVideo_ ) {
Color tmp = bg;
bg = fg;
fg = tmp;
}
TerminalLine line = line_[y];
line.data[x] = c;
line.bgColor[x] = bg;
line.fgColor[x] = fg;
line.effects[x] = effects;
}
public synchronized void setBgColor(int x, int y, Color b)
{
line_[y].bgColor[x] = b;
}
public synchronized void setEffects(int x, int y, byte e)
{
line_[y].effects[x] = e;
}
public synchronized void setFgColor(int x, int y, Color f)
{
line_[y].fgColor[x] = f;
}
public void setFont(Font font)
{
super.setFont(font);
FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
tileWidth_ = fm.charWidth('W');
tileHeight_ = fm.getHeight() - fm.getDescent();
xOffset_ = 0;
yOffset_ = -fm.getDescent();
//System.out.println("tile "+tileWidth_+"x"+tileHeight_+", offset="+xOffset_+","+yOffset_);
}
public void setReverseVideo(boolean r)
{ reverseVideo_ = r; }
public synchronized void setScroll(boolean s)
{ scroll_ = s; }
public synchronized void setTab(int t)
{ tab_ = t; }
public void setTileSize(int w, int h)
{
tileWidth_ = w;
tileHeight_ = h;
buffer_ = null;
}
public synchronized void setXOffset(int x)
{ xOffset_ = x; }
public synchronized void setYOffset(int y)
{ yOffset_ = y; }
public synchronized void setXCursor(int x)
{ xCursor_ = x; }
public synchronized void setYCursor(int y)
{ yCursor_ = y; }
public synchronized void paint(Graphics g)
{
if( buffer_ != null ) {
g.drawImage(buffer_, 0, 0, null);
}
}
public synchronized void update(Graphics gg)
{
if( buffer_ == null ) {
Dimension d = getPreferredSize();
buffer_ = createImage(d.width, d.height);
if( buffer_ == null ) {
repaint(100L); //wtf?
return;
}
}
Graphics g = buffer_.getGraphics();
g.setFont( getFont() );
FontMetrics fm = g.getFontMetrics();
char[] cbuf = new char[1]; // for drawChars
for(int y = 0; y < HEIGHT; ++y) {
int sy = y * tileHeight_;
TerminalLine line = line_[y];
for(int x = 0; x < WIDTH; ++x) {
int sx = x * tileWidth_;
// background
g.setColor( line.bgColor[x] );
g.fillRect(sx, sy, tileWidth_, tileHeight_);
// character
g.setColor( line.fgColor[x] );
cbuf[0] = line.data[x];
g.drawChars(cbuf, 0, 1, sx + xOffset_,
sy + fm.getAscent() + yOffset_);
// effects
if( (line.effects[x] & EFFECTS_UNDERLINE) != 0 ) {
g.drawLine(sx, sy+tileHeight_-1,
sx+tileWidth_-1, sy+tileHeight_-1);
}
// borders for testing
//g.drawLine(sx, sy, sx+tileWidth_-1, sy);
//g.drawLine(sx, sy, sx, sy+tileHeight_-1);
}
}
if( cursorVisible_ ) {
Color bg = getBgColor(xCursor_, yCursor_);
if( bg == BLACK ) {
bg = WHITE;
}
g.setXORMode(bg);
g.fillRect(xCursor_ * tileWidth_, yCursor_ * tileHeight_,
tileWidth_, tileHeight_);
g.setPaintMode();
}
paint(gg);
}
}
class TerminalLine
{
public Color[] bgColor;
public Color[] fgColor;
public char[] data;
public byte[] effects;
public TerminalLine(int width)
{
bgColor = new Color[width];
fgColor = new Color[width];
data = new char[width];
effects = new byte[width];
}
public void setData(int x, Color bg, Color fg, char c, byte e)
{
data[x] = c;
bgColor[x] = bg;
fgColor[x] = fg;
effects[x] = e;
}
}