How to delete a file through JFileChooser? - java

How could i delete a file in JFileChooser? I know that the AWT since being written in native could has an option to delete a file from it using the simple Delete button.
But what if i would like to delete the file in JFileChooser? When i am trying to delete, it i got an exception that the File is being accessed by another program and hence could not be deleted.
Two questions that i would like to ask in this situation are..
Questions
Is there any hack to delete a file through JFileChooser?
Why i am not getting File is being accessed by another program when i am deleting in FileDialog. Is it because it is written in native code?
Any help is appreciated. Thanks in advance.

Yeah! I got it! I even updated the JFileChooser after the file was deleted.
Updated
Added functionality to delete multiple files and modified jf.getUI().rescanCurrentDirectory(jf) to jf.rescanCurrentDirectory() and removed superfluous PropertyChangeListener as per sir Rob Camick's suggestion.
/*
* #see http://stackoverflow.com/a/17622050/2534090
* #author Gowtham Gutha
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;
class DeleteThroughJFileChooser extends JFrame
{
JButton jb;
JFileChooser jf;
File[] selectedFiles;
public DeleteThroughJFileChooser()
{
// Create and show GUI
createAndShowGUI();
}
private void createAndShowGUI()
{
// Set frame properties
setTitle("Delete through JFileChooser");
setLayout(new FlowLayout());
setSize(400,400);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
// Create JFileChooser
jf=new JFileChooser();
// Allow multiple selection
jf.setMultiSelectionEnabled(true);
// Create JButton
jb=new JButton("Open JFileChooser");
// Add ActionListener to it
jb.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae)
{
// Show the file chooser
showFileChooser();
}
});
// Register the delete action
registerDelAction();
// Add JButton jb to JFrame
add(jb);
}
private void showFileChooser()
{
// Show the open dialog
int op=jf.showOpenDialog(this);
}
private void registerDelAction()
{
// Create AbstractAction
// It is an implementation of javax.swing.Action
AbstractAction a=new AbstractAction(){
// Write the handler
public void actionPerformed(ActionEvent ae)
{
JFileChooser jf=(JFileChooser)ae.getSource();
try
{
// Get the selected files
selectedFiles=jf.getSelectedFiles();
// If some file is selected
if(selectedFiles!=null)
{
// If user confirms to delete
if(askConfirm()==JOptionPane.YES_OPTION)
{
// Call Files.delete(), if any problem occurs
// the exception can be printed, it can be
// analysed
for(File f:selectedFiles)
java.nio.file.Files.delete(f.toPath());
// Rescan the directory after deletion
jf.rescanCurrentDirectory();
}
}
}catch(Exception e){
System.out.println(e);
}
}
};
// Get action map and map, "delAction" with a
jf.getActionMap().put("delAction",a);
// Get input map when jf is in focused window and put a keystroke DELETE
// associate the key stroke (DELETE) (here) with "delAction"
jf.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("DELETE"),"delAction");
}
public int askConfirm()
{
// Ask the user whether he/she wants to confirm deleting
// Return the option chosen by the user either YES/NO
return JOptionPane.showConfirmDialog(this,"Are you sure want to delete this file?","Confirm",JOptionPane.YES_NO_OPTION);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
new DeleteThroughJFileChooser();
}
});
}
}

Why would you delete a file from the chooser?
Use the jfilechooser to get the name of the file and location store as a variable. Close the file jfilechooser. Then delete the file.
import java.io.File;
public class DeleteFileExample
{
public static void main(String[] args)
{
try{
File file = new File("c:\\logfile20100131.log");
if(file.delete()){
System.out.println(file.getName() + " is deleted!");
}else{
System.out.println("Delete operation is failed.");
}
}catch(Exception e){
e.printStackTrace();
}
}
}
Also, I found this code that might prove to be usefull if you want the functionality to be in the jfilechooser itself. From Here. To run this you will also need This. Swing file
import darrylbu.util.SwingUtils;
import java.awt.Container;
import java.awt.Point;
import java.awt.event.*;
import javax.swing.*;
public class FileChooserDeleteMenu {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new FileChooserDeleteMenu().makeUI();
}
});
}
public void makeUI() {
final JFileChooser chooser = new JFileChooser();
final JList list = SwingUtils.getDescendantOfType(JList.class, chooser, "Enabled", true);
JPopupMenu popup = list.getComponentPopupMenu();
JMenuItem item = new JMenuItem("Delete");
item.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (chooser.getSelectedFile() != null) {
JOptionPane.showConfirmDialog(chooser,
"Delete " + chooser.getSelectedFile().getAbsolutePath() + "?",
"Confirm delete",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
}
}
});
popup.add(item);
final MouseListener listener = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
if (e.getSource() == list) {
list.setSelectedIndex(list.locationToIndex(p));
} else {
JTable table = (JTable) e.getSource();
if (table.columnAtPoint(p) == 0) {
int row = table.rowAtPoint(p);
table.getSelectionModel().setSelectionInterval(row, row);
}
}
}
};
list.addMouseListener(listener);
final Container filePane = SwingUtilities.getAncestorOfClass(sun.swing.FilePane.class, list);
filePane.addContainerListener(new ContainerAdapter() {
#Override
public void componentAdded(ContainerEvent e) {
JTable table = SwingUtils.getDescendantOfType(JTable.class, chooser, "Enabled", true);
if (table != null) {
for (MouseListener l : table.getMouseListeners()) {
if (l == listener) {
return;
}
}
table.addMouseListener(listener);
}
}
});
chooser.showOpenDialog(null);
System.exit(0);
}
}

This is how to add a delete key listener to your JFileChooser:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.nio.file.Files;
public class JFileChooserUtilities
{
public static void registerDeleteAction(JFileChooser fileChooser)
{
AbstractAction abstractAction = new AbstractAction()
{
public void actionPerformed(ActionEvent actionEvent)
{
JFileChooser jFileChooser = (JFileChooser) actionEvent.getSource();
try
{
File selectedFile = jFileChooser.getSelectedFile();
if (selectedFile != null)
{
int selectedAnswer = JOptionPane.showConfirmDialog(null, "Are you sure want to permanently delete this file?", "Confirm", JOptionPane.YES_NO_OPTION);
if (selectedAnswer == JOptionPane.YES_OPTION)
{
Files.delete(selectedFile.toPath());
jFileChooser.rescanCurrentDirectory();
}
}
} catch (Exception exception)
{
exception.printStackTrace();
}
}
};
fileChooser.getActionMap().put("delAction", abstractAction);
fileChooser.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("DELETE"), "delAction");
}
}
Code adapted from JavaTechnical's answer.

Related

ArrayList of ActionListeners cleared when notifyListeners() called

I am trying to write a class that both listens for actions from buttons and notifies another class when one of the buttons is pressed. I have an ArrayList<ActionListener> and methods addActionListener(ActionListener al), removeActionListener(ActionListener al), and notifyActionListeners(ActionEvent ae). I print to a separate window whenever I add a listener, and print the size of actionListeners as well. It works great and prints that I have 1 actionListener, but then when I try to notify the listeners it says that there are 0 objects in actionListeners. I added a println() to the removeActionListener(al) method to see if it is called, and it never is.
Here's the class:
package state;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import driver.GameDriver;
import ui.Button;
public class MainMenu extends Menu {
private static final long serialVersionUID = -7130241947836998525L;
private ArrayList<ActionListener> actionListeners;
private Button play;
private Button scores;
private Button settings;
private Button help;
private Button exit;
public MainMenu() {
super("Main Menu");
actionListeners = new ArrayList<ActionListener>();
}
#Override
protected void addComponents() {
//Irrelevant to Stackexchange
}
#Override
public void actionPerformed(ActionEvent arg0) {
Object src = arg0.getSource();
if (src == play) {
} else if (src == scores) {
} else if (src == settings) {
} else if (src == help) {
} else if (src == exit) {
ActionEvent ae = new ActionEvent(this, ActionEvent.ACTION_FIRST, "exit");
notifyActionListeners(ae);
}
}
public void addActionListener(ActionListener al) {
GameDriver.println("Added Listener:");
actionListeners.add(al);
GameDriver.println(actionListeners.size());
}
public void removeActionListener(ActionListener al) {
GameDriver.println("Removed al for some reason");
actionListeners.remove(al);
}
private void notifyActionListeners(ActionEvent ae) {
GameDriver.println("Sending exit to " + actionListeners.size() + " listeners.");
for(int i = 0; i < actionListeners.size(); i++) {
GameDriver.println("Exit sent");
actionListeners.get(i).actionPerformed(ae);
}
}
}
Here are the methods that actually reference the instance of MainMenu:
1. Initialization
protected GameDriver() {
mainMenu = new MainMenu();
mainMenu.addActionListener(this);
debugger = new Debugger();
println("Size Loader Test...");
SizeLoader.loadSizes();
println(SizeLoader.getCurrentSize());
println("Complete.");
println("Window Test...");
window = new Window("Asteroids");
windowManager = new WindowManager();
// window.addWindowFocusListener(windowManager);
// window.addWindowListener(windowManager);
// window.addWindowStateListener(windowManager);
window.buildWindow(SizeLoader.getCurrentWidth(), SizeLoader.getCurrentHeight());
window.add(new MainMenu());
println("Complete");
println("Menu Test...");
}
And here's the actionPerformed(ae):
#Override
public void actionPerformed(ActionEvent e) {
println("Event happened");
if (e.getSource() == mainMenu) {
if (e.getActionCommand() == "exit") {
println("Exiting FR this time...");
}
}
}
As per my comment: 3) You're creating more than one MainMenu object, one you add a listener to and the other you add to window. This looks to be a serious bug.
Instead create only one instance, set its state as needed (add listeners) and add it to the gui.
So change
window.add(new MainMenu());
To
window.add(mainMenu);
And again as per my prior comment, don't use == for String equality check but rather the .equals method.

reading the value of jtable selected row

I am working with java RMI and swing and I have read the values from database but i am unable to read the value of selected row in this code. What i want to JTable to show all databases and it is showing all the available databases in server but i am unable to read the selected row value in this
package schoolclient;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import schoolserver.SchoolInterface;
public class DatabaseList {
JFrame jFrame = null;
JPanel jPanel = null;
JList jList = null;
JTable jTable = null;
String data = null;
schoolserver.SchoolInterface schoolInt = null;
public DatabaseList(SchoolInterface sii) {
schoolInt = sii;
jFrame = new JFrame();
jTable = new JTable(){
public boolean isCellEditable(int row, int column) {
return false;
}
};
jTable.setModel(createTable());
jTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jTable.addMouseListener(new MouseAdapter() {
public void MouseClicked(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {
new createListSelection();
}
}
});
JScrollPane scrollPane = new JScrollPane(jTable);
jFrame.add(scrollPane);
jFrame.setSize(200, 200);
jFrame.setVisible(true);
}
private DefaultTableModel createTable() {
DefaultTableModel dtm = new DefaultTableModel();
dtm.addColumn("Databases", createArray());
return dtm;
}
private class createListSelection implements ListSelectionListener {
#Override
public void valueChanged(ListSelectionEvent e) {
if(!e.getValueIsAdjusting()) {
ListSelectionModel lsm = jTable.getSelectionModel();
data = (String) jTable.getValueAt(jTable.getSelectedRow(), 0);
System.out.println(data);
}
}
}
Object[] createArray() {
ArrayList<Object> al = null;
Object[] x = null;
try {
al = schoolInt.availableDatabases();
x = new Object[al.size()];
int i = 0;
for(Object o : schoolInt.availableDatabases())
x[i++] = o;
}
catch(Exception e) {
JOptionPane.showMessageDialog(null, "no connection to database or "
+ "remote server availabe", "Server Information", JOptionPane.OK_OPTION);
}
return x;
}
}
You look to be over-complicating things. Don't re-add listeners within a listener, but rather simply add one listener, a MouseListener to the JTable, and add it once. Within it check for double clicks (presses) and respond. Something like:
jTable.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
data = (String) jTable.getValueAt(jTable.getSelectedRow(), 0);
System.out.println(data);
}
}
});
Other problems, your method within your MouseAdapter will never be called, ever:
jTable.addMouseListener(new MouseAdapter() {
public void MouseClicked(MouseEvent e) {
// ....
}
});
Your capitalization is wrong, and since MouseAdapter/MouseListener does not have a MouseClicked method (it is mouseClicked) this method is never called. Always place an #Override annotation above any method that you think might be an override, and let the compiler warn you if it is not so. Had you done this, you'd get a prompt warning from the compiler.
Regarding your comment
You never add a selection listener to the JTable. Again the method within the MouseAdapter is never called since it is not capitalized correctly
Even if it did get called, what use is there repeatedly adding a ListSelectionListener?
If your goal is to only respond to double-clicks, a ListSelectionListener is not what you want. Only a MouseListener would work in this situation.
Do read the appropriate tutorials as they explain all of this and well. Please check out the links to be found within the Swing Info tag.

Choosing file path not seen on JTextField in Ubuntu on Eclipse

I have this code (this is all code). I want to write file path(choosing file) on JTextField. I run the program and i press button and file chooser open, i choose file but file path not write on JTextField.
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import org.dyno.visual.swing.layouts.Bilateral;
import org.dyno.visual.swing.layouts.Constraints;
import org.dyno.visual.swing.layouts.GroupLayout;
import org.dyno.visual.swing.layouts.Leading;
//VS4E -- DO NOT REMOVE THIS LINE!
public class xailabsPanel extends JFrame {
private static final long serialVersionUID = 1L;
private JButton jButton0;
public static String path;
private JTextField jTextField0;
private static final String PREFERRED_LOOK_AND_FEEL = "javax.swing.plaf.metal.MetalLookAndFeel";
public xailabsPanel() {
initComponents();
}
private void initComponents() {
setLayout(new GroupLayout());
add(getJText(), new Constraints(new Bilateral(12, 12, 4), new Leading(100, 10, 10)));
add(getJButton0(), new Constraints(new Bilateral(117, 117, 94), new Leading(57, 12, 12)));
setSize(328, 252);
}
private JButton getJButton0() {
if (jButton0 == null) {
jButton0 = new JButton();
jButton0.setText("jButton0");
jButton0.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent event) {
jButton0MouseMouseClicked(event);
}
});
}
return jButton0;
}
private JTextField getJText() {
if (jTextField0 == null) {
jTextField0 = new JTextField();
}
return jTextField0;
}
private static void installLnF() {
try {
String lnfClassname = PREFERRED_LOOK_AND_FEEL;
if (lnfClassname == null)
lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();
UIManager.setLookAndFeel(lnfClassname);
} catch (Exception e) {
System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL
+ " on this platform:" + e.getMessage());
}
}
/**
* Main entry of the class.
* Note: This class is only created so that you can easily preview the result at runtime.
* It is not expected to be managed by the designer.
* You can modify it as you like.
*/
private void jButton0MouseMouseClicked(MouseEvent event) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.showOpenDialog(null);
fileChooser.setCurrentDirectory(new File(System.getProperty("home/kerim")));
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
// user selects a file
File selectedFile = fileChooser.getSelectedFile();
path = selectedFile.getAbsolutePath().toString();
jTextField0.setText(path);
}
}
public static void main(String[] args) {
installLnF();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
xailabsPanel frame = new xailabsPanel();
frame.setDefaultCloseOperation(xailabsPanel.EXIT_ON_CLOSE);
frame.setTitle("xailabsPanel");
frame.getContentPane().setPreferredSize(frame.getSize());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
You are creating a new JTextField inside the method (and you are modfying its contents), but it's not added anywhere.
Drop jTextField0 = new JTextField() and it should work (assuming you already created the text field beforehand).
The code works fine, when I do the following
Change layout manager default BorderLayout (why? Because I don't have GroupLayout, it's not a standard Layout Manager - so I don't know if it's a direct cause)
Add the componenst to corresponding BorderLayout positions.
Changed setSize() to pack(). This is the preferred way.
create the text field the the constructor (new JTextField(int columns)). For some weird reason I feel like this is the culprit (as without this, the text field has no preferred size, and maybe you just weren't seeing it. Not 100% sure, hell probably not even 50% sure, as I couldn't test the GroupLayout
Got rid of frame.getContentPane().setPreferredSize(frame.getSize());, another suspected culprit (not really necessary to delete, but not preferred to keep).
Got rid of this unnecessary line, as it's redundant fileChooser.showOpenDialog(null); and causing the file chooser to open twice.
Here's the result
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
//VS4E -- DO NOT REMOVE THIS LINE!
public class xailabsPanel extends JFrame {
private static final long serialVersionUID = 1L;
private JButton jButton0;
public static String path;
private JTextField jTextField0;
private static final String PREFERRED_LOOK_AND_FEEL = "javax.swing.plaf.metal.MetalLookAndFeel";
public xailabsPanel() {
initComponents();
}
private void initComponents() {
//setLayout(new GroupLayout());
add(getJText(), BorderLayout.WEST);
add(getJButton0(), BorderLayout.EAST);
//setSize(328, 252);
pack();
}
private JButton getJButton0() {
if (jButton0 == null) {
jButton0 = new JButton();
jButton0.setText("jButton0");
jButton0.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent event) {
jButton0MouseMouseClicked(event);
}
});
}
return jButton0;
}
private JTextField getJText() {
if (jTextField0 == null) {
jTextField0 = new JTextField(20);
}
return jTextField0;
}
private static void installLnF() {
try {
String lnfClassname = PREFERRED_LOOK_AND_FEEL;
if (lnfClassname == null)
lnfClassname = UIManager.getCrossPlatformLookAndFeelClassName();
UIManager.setLookAndFeel(lnfClassname);
} catch (Exception e) {
System.err.println("Cannot install " + PREFERRED_LOOK_AND_FEEL
+ " on this platform:" + e.getMessage());
}
}
/**
* Main entry of the class. Note: This class is only created so that you can
* easily preview the result at runtime. It is not expected to be managed by
* the designer. You can modify it as you like.
*/
private void jButton0MouseMouseClicked(MouseEvent event) {
JFileChooser fileChooser = new JFileChooser();
//fileChooser.showOpenDialog(null);
//fileChooser.setCurrentDirectory(new File(System
//.getProperty("home/kerim")));
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
// user selects a file
File selectedFile = fileChooser.getSelectedFile();
path = selectedFile.getAbsolutePath().toString();
System.out.println(path);
jTextField0.setText(path);
}
}
public static void main(String[] args) {
installLnF();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
xailabsPanel frame = new xailabsPanel();
frame.setDefaultCloseOperation(xailabsPanel.EXIT_ON_CLOSE);
frame.setTitle("xailabsPanel");
//frame.getContentPane().setPreferredSize(frame.getSize());
((JPanel) frame.getContentPane()).setBorder(BorderFactory
.createEmptyBorder(20, 20, 20, 20));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
You never added JTextField to your JFrame (or whatever window you want the text field to be).
Right after your JTextFIeld0 = new JTextField(); add: myWindow.add(jTextField0)
also, you are displaying two open dialogs. i dont think it is your desired behavior, remove the file fileChooser.showOpenDialog(null);
Here is a quick example of what you are trying to accomplish:
public static void main(String[] args)
{
// you should not need this, use the frame you already have, where the button is.
JFrame window = new JFrame();
// This is what you are doing in your code, however, you should add a text field
// whereever you create and populate your jframe, and add the button etc, and simply
// set the jtextfield value here
JTextField tf = new JTextField();
// again in your case you should have this somewhere else, i assume if you are
// displaying a button, you must have a JFrame somewhere
window.setSize(100, 100);
window.add(tf);
window.setLocationRelativeTo(null);
/***** you DO NEED this code **************/
// create file chooser and open the dialog.
JFileChooser fc = new JFileChooser();
fc.showOpenDialog(null);
// get selected file object
File f = fc.getSelectedFile();
// disply file path in the text field
tf.setText(f.getAbsolutePath());
/****** end of the code you need *********/
// display a JFrame with the text field (dont need this obviously you
// already are displaying the frame)
window.setVisible(true);
}

How to save a text file without having to enter file name every time?

Hi all I am creating a simple text editor as a project and I have hit a snag when it comes to saving the content typed as a file. I can save the file using the Save As principle with a dialog box prompting the user to enter a filename.
The problem I am having is implementing the Save so that it saves to the file that is opened without having to go to the dialog box each time, like it would if someone did Ctrl+S. Anyone have any ideas how I would implement this feature?
Here's some of my code:
JMenuItem saveFile = new JMenuItem(new AbstractAction("Save") {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser save = new JFileChooser();
File filename = save.getSelectedFile();
if(opened == false && saved == false) {
save.showSaveDialog(null);
int confirmationResult;
if(filename.exists()) {
confirmationResult = JOptionPane.showConfirmDialog(getParent(), "Replace existing file?");
if(confirmationResult == JOptionPane.YES_OPTION) {
saveFile(filename);
}
} else {
saveFile(filename);
}
} else {
saveFile(filename);
}
}
});
saveFile.setPreferredSize(new Dimension(100, 20));
saveFile.setEnabled(true);
save method:
private void saveFile(File filename) {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
writer.write(textArea.getText());
writer.close();
saved = true;
editorWindow.setTitle("JavaText - " + filename.getName());
} catch (IOException err) {
err.printStackTrace();
}
}
If you store the opened File object somewhere in your application you can then just pass that into your saveFile method on a key press using a KeyListener or KeyAdapter. Without seeing more of the application it's hard to tell where would be best to put it, but if you just store it in a variable somewhere you can refer back to it.
Store the file name somewhere
if(nameOfFile != null) then don't show the dialog box and go to save method
else show dialog box and call the save method
That's what I would do
The following program shows the implementation of 'Save' & 'Save as' functionality for text editors. Running it will shows a JFrame with a JTextArea , save JButton & save as JButton.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class MyFrame extends JFrame {
private boolean alreadySaved = false;
private BufferedWriter bw;
private JFileChooser fileChooser;
private JTextArea jta;
private File file;
private JButton save;
private JPanel mainPanel;
private JButton saveAs;
public MyFrame() {
initComponents();
save.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if (!alreadySaved) {
int response = fileChooser.showSaveDialog(getParent());
file = fileChooser.getSelectedFile();
if (response == JFileChooser.APPROVE_OPTION) {
writeFile();
alreadySaved = true;
}
} else
writeFile();
}
});
saveAs.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
int response = fileChooser.showSaveDialog(getParent());
file = fileChooser.getSelectedFile();
if (response == JFileChooser.APPROVE_OPTION) {
writeFile();
alreadySaved = true;
}
}
});
} // END of Constructor
public void writeFile() {
try {
bw = new BufferedWriter(new FileWriter(file));
bw.write(jta.getText());
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void initComponents() {
fileChooser = new JFileChooser();
saveAs = new JButton("Save as");
jta = new JTextArea(10, 40);
mainPanel = new JPanel();
mainPanel.setBackground(Color.red);
save = new JButton("Save");
mainPanel.add(save);
mainPanel.add(saveAs);
this.setLayout(new BorderLayout());
this.add(jta);
this.add(mainPanel, BorderLayout.SOUTH);
this.pack();
this.setLocationRelativeTo(null);
}
public static void main(String[] args) {
new MyFrame().setVisible(true);
}
}

Java Swing second window calls event listener twice after being disposed

So I have a swing application where a button opens up a window. It is pretty simple, to open it I use:
private static logPicker logWindow;
static boolean logViewerOpen = false;
if (!logViewerOpen) {
logWindow = new logPicker();
logWindow.frmOpenLog.setVisible(true);
logViewerOpen = true;
}
else {
logWindow.frmOpenLog.requestFocus();
}
I also have a window listener to know when the viewer is closed:
frmOpenLog.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent arg0) {
indexPage.logViewerOpen = false;
frmOpenLog.dispose();
}
});
I do this because I want to keep track on whether or not the window is already open, because if it is then I have to update information. The window I open has a list of logs that a user can double click on to view the information about that log. The problem right now is, when a user double clicks on the list it gets called however many times I have opened and closed that window. example: I open the log picker window, and then close it. I open it again and double click on the log I want to view, and it will open 2 of those. I have the double click simple do a .doClick() on the Open Log button. The weird thing is, when I use the button to open the log, it does not do this. It will only open the log once. Here is the code for the double click event and the Open Log button.
#Override
public void mouseClicked(MouseEvent arg0) {
if (arg0.getClickCount() == 2) {
btnOpenLog.doClick();
}
}
btnOpenLog.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
logViewer window = new logViewer(log.getSelectedValue());
window.frmLogViewer.setVisible(true);
}
});
#LiverpoolFTW: Please provide a SSCCE demonstrating the problem. Absent sufficient code, I speculate you're (re-)adding the MouseListener/MouseAdapter each time your window is opened. The following example works as desired as-is, incrementing the clickCount once per button press or label double-click. But if you uncomment the indicated section, you'll see that the doClick() is executed twice when you double-click the label. If you have, for example, some component to which you're adding a listener each time the window opens, each of those listeners will be executed.
package example.stackoverflow;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class ClickCheck extends JFrame
{
private static final long serialVersionUID = -6446528001976145548L;
private static final JButton btnOpenLog = new JButton("Open Log");
public ClickCheck()
{
JLabel label = new JLabel("Double-Click Me");
label.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent arg0) {
if (arg0.getClickCount() == 2) {
btnOpenLog.doClick();
}
}
});
// Uncomment to demonstrate the effect of multiple listeners
// label.addMouseListener(new MouseAdapter()
// {
// #Override
// public void mouseClicked(MouseEvent arg0) {
// if (arg0.getClickCount() == 2) {
// btnOpenLog.doClick();
// }
// }
// });
btnOpenLog.addActionListener(new ActionListener() {
private int clickCount = 0;
public void actionPerformed(ActionEvent e) {
System.out.println(++clickCount + ": Button clicked");
}
});
setSize(200, 200);
setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
add(btnOpenLog);
add(label);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
ClickCheck c = new ClickCheck();
c.setVisible(true);
}
});
}
}

Categories