How to Save, Save As Java? - java

Hello I'm having a little bit of a problem with my text editor like program. I would like to have my Save feature work only if Save As has been called, and if Save is called that it appends the text From a JTextArea to the file created by Save As. I am using ActionListeners from JMenuItems to call the Save and Save As Actions. Here's the code for Save As:
FileDialog fileDialogSave = new FileDialog(frame, "Save", FileDialog.SAVE);
fileDialogSave.setVisible(true);
String userProjectSavePath = fileDialogSave.getDirectory() + fileDialogSave.getFile();
File userProjectSave = new File(userProjectSavePath);
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(userProjectSave, true)))) {
userProjectSave.createNewFile();
String userProjectNameToSave = codeArea.getText();
out.println(userProjectNameToSave);
} catch (IOException e1) {
e1.printStackTrace();
}
Both the Save and Save As are nested inside static class ActionSaveAs implements ActionListener { public void actionPerformed(ActionEvent e) { ... } }
The problem is I can't access the String userProjectSavePath in the Save class so I can't append the new text to the same file as in the Save As.

Instead, let your notional saveDocument() method invoke saveDocumentAs() if currentFile is null. The following outline suggests the approach taken in Charles Bell's HTMLDocumentEditor, cited here.
public void saveDocument() {
if (currentFile != null) {
// Save in currentFile
} else {
saveDocumentAs();
}
}
public void saveDocumentAs() {
// Check before overwriting existing file
}

Related

How to save text file which has been modified through a Master Details Block in Eclipse?

I created a multi page editor with a text editor page and a Master Details Block page. In the Master Details block I have a list with entries which have been parsed from a text file.
These text files have the following structure:
myVar = 23423423;
SEARCH(myVar)
block
{
text = test;
}
When I click on one of the entries, for example myVar, a detail block with two forms will be displayed, one input field for the variable name and one for the corresponding value. If I change the entries through this form, the respective object will be modified. However, it will not mark the multi page editor as dirty and it will not ask me if I want to save my changes. greg-449 told me today, that I need to save the file manually, so I tried the following:
public class MyParser {
private MyModel model;
private long lastModified;
private IFile file;
public MyParser(FileEditorInput input) {
this.file = input.getFile();
this.lastModified = input.getFile().getModificationStamp();
parse();
}
private void parse() {
try {
InputStream in = file.getContents();
BufferedReader reader = new BufferedReader(
new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String line;
List<MyField> variables = new ArrayList<MyField>();
while ((line = reader.readLine()) != null) {
String[] splittedLine = line.split("=");
if (splittedLine.length >= 2)
variables
.add(new MyVariable(splittedLine[0], splittedLine[1]));
// Implement other entry types
}
System.out.println(out.toString()); // Prints the string content
// read from input stream
reader.close();
this.setModel(new MyModel().add(variables, false));
} catch (CoreException | IOException ex) {
}
}
public void saveChanges() {
FileWriter writer = null;
try {
writer = new FileWriter(file.getLocation().toFile());
try {
saveChanges(writer);
} finally {
writer.close();
}
if (file != null) {
try {
file.refreshLocal(IResource.DEPTH_INFINITE,
new NullProgressMonitor());
} catch (CoreException e) {
}
}
} catch (IOException ex) {
}
}
public void saveChanges(Writer writer) {
//TODO
this.getModel().setDirty(false);
}
public long getLastModified() {
return this.lastModified;
}
public MyModel getModel() {
return model;
}
public void setModel(MyModel model) {
this.model = model;
}
How can I save the modified objects to the original file? Do I need to overwrite the file completely or is it possible to change only the dirty values? Furthermore, the order of the entries in the text files is important. Do I need to remember the line numbers, because this may be a problem when adding new entries somewhere in the middle of the file.
Any help is greatly appreciated.
You have to replace the entire contents of the file. Use the IFile.setContents method to set the contents of an existing file. It is up to you to get the order of the contents correct.
For a FormEditor call editorDirtyStateChanged() to tell the editor that the 'dirty' state has changed. Each IFormPage should implement isDirty as appropriate (or override the FormEditor isDirty method).
If the dirty state is correct a '*' is added to the editor title. A 'do you want' to save dialog will also be displayed on exit if the editor is dirty.

Can I use FileInputStream without giving it a path right at the start

I am trying to upload a file to a database (a .mp4 file to be specific). But when I run my code the file path is not yet chosen because, in the program a window pops up where you can select a file you want to upload. Is there a way to achieve this?
The problem I am having with FileInputStream is that it asks for a file path at the start of my program but the path is still uncertain at that point.
Greetings Pygesux
This is where I try to INSERT into the db
public void draw() {
open.draw();
openText.draw();
if (video != null) {
upload.draw();
uploadText.draw();
}
}
public void mouseClick() {
if (open.mouseOverMe()) {
selectInput("Select a file to process:", "fileSelected");
} else if (upload.mouseOverMe()) {
uploadFile();
}
}
public void fileSelect(File selection) {
video = selection;
}
public void uploadFile() {
try {
con = database.getConnect();
java.sql.PreparedStatement statement = con.prepareStatement("INSERT INTO filmpje (filmpje) VALUES (?)");
FileInputStream input = new FileInputStream(video);
statement.setBlob(1, input);
statement.executeUpdate();
}
catch (SQLException e) {
e.printStackTrace();
}
}
Why you do not create FileInputStream after the path is chosen?
Make a method, that take path, and then creates the FileInputStream, and do other job. Call this method after you know your path, after user eneter it, and accept by pressing button/enter (it is your app logic).
I think you're trying to use selectInput() correct? The reference example is not super clear. The program continues to run while the user selects a file, so you get an error if you try to run code that requires the filename. Here's an example that tests if the file is set yet or not. You would need to update it for your particular needs:
String input;
void setup() {
size(500,200);
selectInput("Select a file...", "fileSelector");
}
void draw() {
background(255);
fill(0);
noStroke();
if (input == null) {
text("No file selected.", 20,height/2);
}
else {
text(input, 20,height/2);
}
}
void fileSelector(File selection) {
if (selection == null) {
// window closed or user hit cancel button
}
else {
input = selection.getAbsolutePath();
}
}

My custom "paste from clipboard" action

I want to find a way to do kind of a custom "paste from clipboard" action. Let's assume the content of clipboard is text for simplicity (not a file). Whenever you press Ctrl+V, it inserts that content (which is text) to a current open file which has a focus.
I have an app for catching a global hotkey. Note this is not a window application, it's a console one and it catches the hotkey globally. Let's say I have the hotkey of Ctrl+U. So what I want to do is when I press Ctrl+U I want to insert some predefined text to a current open file. Just like Ctrl+V does! The differences from a standard Ctrl+V is that I want to insert a predefined text and the hotkey is different.
How do I do this?
I'd prefer a cross-platform solution, however first of all I'm going to do that for Linux, specifically Ubuntu. The language is not important but Java or Scala would be better. Of course, I understand that the solutions is Java uses native OS' API for that.
I'm hoping that this hackish solution would work, but it is still untested, I am unsure how to catch the event for the hotkey.
The idea behind this code is the following five steps:
Get the old text in the clipboard and temporarily save it
Paste our predefined text into the clipboard
Trigger the global paste event
Release the global paste event
Reset the clipboard to the old text
This should give the appearance of a new clipboard (if not, hopefully it inspires you to come up with a better, less hackish solution).
Without further ado, here is my code. First I have a simple helper method to set the value of the clipboard (as we do this twice).
public static void setClipboard(String s) {
StringSelection contents = new StringSelection(s);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(contents, contents);
}
And then, I have a main method where I go through the five steps in order.
public static void main(String[] args) {
// Step 1 ) get old text
String oldText = "";
try {
oldText = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException ufe) {
ufe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
// Step 2 ) paste our text in clipboard
setClipboard("This lorem ipsum predefined string blows my mind.");
// Step 3 ) trigger paste event
Robot robot = null;
try {
robot = new Robot();
} catch (AWTException awte) {
awte.printStackTrace();
}
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
// Step 4 ) Release paste event
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_V);
// Step 5 ) Reset clipboard
setClipboard(oldText);
}
[Edit]:
Here is some code to test what kind of contents are in the Clipboard - image, text, etc. The unicode error was coming from the fact that the old contents of the clipboard were something that couldn't be represented by a plain String. To fix this error, you will have to check if the old contents were an image, the old contents were text, and save them accordingly.
public static int kindOfContents() {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable contents = clipboard.getContents(null);
if(contents.isDataFlavorSupported(DataFlavor.stringFlavor)) {
// String, save temporarily as string and write back as string
return 0;
} else if(contents.isDataFlavorSupported(DataFlavor.imageFlavor)) {
// Image, save temporarily as BufferedImage and write back as image
return 1;
} else if(contents.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
// List of files, save temporarily as java.util.List interface and write back as the file lists
return 2;
}
}
If the contents are text, then for saving and writing the content you would use the old method, repasted below for convenience.
// Step 1 ) get old text
String oldText = "";
try {
oldText = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException ufe) {
ufe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
// Step 5 ) Reset clipboard
setClipboard(oldText);
However, if the contents are an image, then for saving temporarily and rewriting you need to do the following. Note that the code for writing the image is not mine, but is taken from the accepted answer at Setting images to Clipboard - Java
// Step 1 ) get old image
BufferedImage img = null;
try {
img = (BufferedImage) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.imageFlavor);
} catch (UnsupportedFlavorException ufe) {
ufe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
Taken from Setting images to Clipboard - Java :
// Step 5 ) Reset clipboard
ImageTransferable transferable = new ImageTransferable( image );
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(transferable, null);
static class ImageTransferable implements Transferable
{
private Image image;
public ImageTransferable (Image image)
{
this.image = image;
}
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException
{
if (isDataFlavorSupported(flavor))
{
return image;
}
else
{
throw new UnsupportedFlavorException(flavor);
}
}
public boolean isDataFlavorSupported (DataFlavor flavor)
{
return flavor == DataFlavor.imageFlavor;
}
public DataFlavor[] getTransferDataFlavors ()
{
return new DataFlavor[] { DataFlavor.imageFlavor };
}
}

Objects from .txt file are not written to my Jlist

I'm having a little problem with my Java App. I have 2 frames, the mainframe is called MasterFrame. The MasterFrame contains a JList + 3 buttons.
Button 1 can add Block shapes to the JList, this will call the 2nd frame called BlockFrame. Block shapes are Objects stored in the ArrayList shapecollection.
The MasterFrame also contains a Save button which will store objects in a .txt file called "test.txt".
The MasterFrame also contains a Load button which will open the .txt file "test.txt", read the file for objects and set the objects back into the JList. That is what actually is going wrong. The save function works, i'm not quite sure about the load method. It seems that it's actually reading my .txt file for objects but it won't put it back in my Jlist.
The load method might be good, but than there might be a problem with reading the objects and setting them back into the JList. I'm glad if anyone off you guys could give me a hand :)
import java.io.*;
// My File IO Class
public class ShapeIOController {
private String filename;
public ShapeIOController(){
filename= "C:\\Users\\Lars\\Desktop\\test.txt";
}
// The Save method which will save all my created blocks in "test.txt" file
public void save(ShapeCollection shapecollection){
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename));
out.writeObject(shapecollection);
out.close();
}
catch( IOException e){
System.out.println("Error occured when trying to open file" + filename);
e.printStackTrace();
}
}
// The open file method which will open "test.txt" file,
// read it's objects and return a ArrayList of shapes "shapecollection"
public ShapeCollection open(ShapeCollection shapecollection){
try{
ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));
shapecollection= (ShapeCollection) in.readObject();
in.close();
}
catch (ClassNotFoundException e ) {
System.out.println("Unknown class by reading file" + filename);
}
catch ( IOException e ) {
System.out.println("Error occured when trying to open file " + filename);
e.printStackTrace();
}
shapecollection.giveCollection();
return shapecollection;
}
}
// The code for the save button which works
private void SaveShapeButtonActionPerformed(java.awt.event.ActionEvent evt) {
shapeiocontroller.save(shapecontroller.getShapeCollection());
}
// The code where it probably is going wrong
private void LoadShapeButtonActionPerformed(java.awt.event.ActionEvent evt) {
for(int i = 0; i < shapecontroller.getShapeCollection().giveCollection().size(); i++){
listModel.addElement(shapecontroller.getShapeCollection().giveShape(i).toString());
InfoShapeJList.setModel(listModel);
shapeiocontroller.open(shapecontroller.getShapeCollection());
}
}
// List of methods LoadShapeButtonActionPerformed is using:
// getShapeCollection()
public ShapeCollection getShapeCollection() {
return shapecollection;
}
// giveCollection()
public ArrayList<Shape> giveCollection(){
return shapecollection;
}
// giveShape()
public Shape giveShape(int index){
return shapecollection.get(index);
}
// toString()
public String toString(){
return "Block: " + length + " " + width + " " + height;
}

How can I fetch a path from a preference page and use it in a process started by a button?

I have made a preference page whose program code is --
public class SAML
extends FieldEditorPreferencePage
implements IWorkbenchPreferencePage {
public SAML() {
super(GRID);
setPreferenceStore(RmpPlugin.getDefault().getPreferenceStore());
setDescription("Browse Appropriate files");
}
public FileFieldEditor f;
public FileFieldEditor f1;
public void createFieldEditors() {
f = new FileFieldEditor(PreferenceConstants.P_PATH,
"&Prism.bat File:", getFieldEditorParent());
addField(f);
f1 = new FileFieldEditor(PreferenceConstants.P_PATH1,
"&NuSMV Application File:", getFieldEditorParent());
addField(f1);
}
public void init(IWorkbench workbench) {
}
}
In this preference page, there are two FileFieldEditor which is use to select "prism.bat" and "NuSMV.exe" file.
I have accessed path in my another button programming whose code is ---
try {
IPreferenceStore store = plugin.getPreferenceStore();
ProcessBuilder pb=new ProcessBuilder(store.getString(PreferenceConstants.P_PATH));
pb.directory(new File(store.getString(PreferenceConstants.P_PATH)));
Process p=pb.start();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String in;
while((in = input.readLine()) != null) {
out.println(in);
}
int exitVal=p.waitFor();
if(exitVal==0)
{
out.println("Printing on console");
}
else
out.println("Process failed");
}
catch (Exception e)
{
out.println(e.toString());
e.printStackTrace();
}
Whenever I am clicking the button after selecting Prism.bat file from preference page, it says that file not found.
What am I missing?
Debug your code and see what this computes to
store.getString(PreferenceConstants.P_PATH));
pb.directory(new File(store.getString(PreferenceConstants.P_PATH))
excute it from the command line and see what is missing. My guess is that there is a space character in your path which is breaking it. Quotify the path may fix it. But see the string and decide accordingly.

Categories