• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Document Listener and/or Ley Listener

 
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I need to add something that when I use the Save option or hit the x to kill the frame that notices that the text has changed and prompts me to save. I beleive that document listener and/or key listenered might do the trick. I would just have a JOPtionpane poped asking wether or not to save or not. I just don;t know to actully use any of those. Any help would be greatly appreciated.
Thanks,
Ben
 
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you hit the "X" button you get a WindowEvent, which can represent closing, maximising, resizing, etc, etc, the window (JFrame).
If you click a JButton or JMenuItem you can get a MouseEvent, or an ActionEvent. The latter is more useful.

Suggest:
  • Visit this thread, where I wrote about Listeners this morning. Note the links to the Java Tutorial and API about EventListener.
  • Set up a save() method in the usual fashion, and you may wish to have some mechanism for choosing your file to save into.
  • Read about JOptionPane here. Note the link to "how to use dialogs" in the Java Tutorial.
  • Not sure about DocumentListener; you can have a KeyListener which sets a "needSave" variable to "true" whenever you write anything on screen.
  • You will end up with something like "if(needSave && JOptionPane.showConfirmDialog(myFrame, "Do you wish to save?", "Save", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) etc
  • Look up JOptionPane.YES_OPTION etc where the link to constant values is.
  • Don't use setDefaultCloseOperation() on the JFrame; the default of DISPOSE_ON_CLOSE will do nicely.
  • You can add a WindowListener to your JFrame which starts the save sequence when you close the JFrame.
  • You can have an "exit" JButton with an ActionListener which starts the save sequence.
  • You can have a "Save" JButton which starts the save sequence and doesn't start a shutdown sequence, and when "save" is finished, sets needSave to "false."

  • Sorry there seems to be so much to do. Try it a little bit at a time. Maybe start with a "save" button and get that bit working first.
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Actully I don't need a save button ...I just need to let the user know changes have been made. I just need a JOPtionPane to pop, display the message and if they click ok, exit, but if they click no...nothing happens. I will need the same thing for the exit option from the menu...


    viewer is the instance of fileviewer and display is the what the
    JTextArea is called.

    /tmp/26242/FileViewer.java:149: cannot resolve symbol
    symbol : method addDocumentListener ()
    location: class javax.swing.JTextArea
    viewer.display.addDocumentListener();
    ^
    1 error

    I have imported import javax.swing.text.*;. So I am bit confused on where to go from here.. any suggestions?
     
    Campbell Ritchie
    Marshal
    Posts: 79151
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    having seen how your app works, it appears you don't need all these Listeners. You can add a line likewhenever you push the "replace" menu item, and whenever you have saved the changes. Those bits can go inside the ActionListeners.

    Do you actuallywant users to edit the text directly on screen? If so, then look what sort of Listeners you can add to a JTextArea. I don't think you can add a DocumentListener. You will have to assume that any keystrokes represent a change which has to be saved, probably best done with a KeyListener.
    Then use a WindowListener to find out whether the JFrame is being closed, so you get exit and the "X" button both calling save if necessary.

    BTW: you are opening Files and not closing them again.
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I am trying to use a key listener to this but I get this error for it...



    I am still at a bit of a loss here...
     
    Ranch Hand
    Posts: 2412
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    It's telling you that you aren't implementing the keyTyped method from KeyListener.
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    How do I implent the KeyTyped for the KeyListener? The example I saw on Java docs was logging the changes. I just need to know if something changed whne either the exit button or close window button is pushed... see the code mention above in the thread..

    Thanks,
    Ben Jordan
    [ April 23, 2007: Message edited by: Ben Jordan ]
     
    Keith Lynn
    Ranch Hand
    Posts: 2412
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    You don't have to do anything in the method. You just have to have a valid implementation for it to compile.


    will work.
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    thanks,
    I will try that...
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I had to create blank methods for KeyEvent, KeyPressed and KeyReleased but it complied....
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator


    I am getting this error, why?

    /tmp/32760/FileViewer.java:159: cannot resolve symbol
    symbol : method addKeyListener ()
    location: class java.lang.String
    text.addKeyListener();
    ^
     
    Rancher
    Posts: 3742
    16
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Because 'text' is a String and String does not have a addKeyListener() method.
    [ April 24, 2007: Message edited by: Joanne Neal ]
     
    Campbell Ritchie
    Marshal
    Posts: 79151
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    You are trying to add the Listener to the wrong object. You can't add it to a String. You were proabbly trying to add it to the JTextField called display.
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I want it on the Display object put I keep getting errors...


    /tmp/14473/FileViewer.java:160: addKeyListener(java.awt.event.KeyListener) in java.awt.Component cannot be applied to ()
    viewer.display.addKeyListener();
    ^
    1 error

    This is where I am now with this... any suggestions...Maybe I should create a new JTextArea but not sure how to do that?
     
    Campbell Ritchie
    Marshal
    Posts: 79151
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    JTextArea supports addKeyListener, and I can't see a spelling error.

    You have the non-static access error. You need to find out the difference betweeen static and instance methods (it comes up on this forum frequently, here, most recently, or in the Java tutorial here: click on "instance and class members".

    To cut it short: "this" implies you are using an instance method, but you appear to be calling it from a static method. You will have to redesign your app to change that method to an instance method.
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator


    this is the method that I am using to attach the addlistener to the JtextArea...
    I have this
    viewer.display.addKeyListener();

    Is this not an instance method becuase frame is an instance of JFrame and viewer is an instance of FileViewer. Do I need to add something inside of the () of the addKeyListener. Once again, thanks for all your help.
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    It complied using this....

    viewer.display.addKeyListener(viewer);
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator


    I know this didn't complie becuase it needs a boolean value. How do I create one from the KeyListener?
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator


    This is what I came up with..I hope this works. It will compile but I can't test it yet. Any suggestions?
     
    Ranch Hand
    Posts: 4632
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    haven't read all the thread to see what's been tried, but this may be an alternative approach

     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    thanks for the code..

    I still trying to figure out how to have the prgoram know something has changed when I press the exit button and the x on the window...

    I know it has to do with the KeyListener and this what I have but it isn;t working...



    I don't know why it isn't working... any suggestions
     
    Michael Dunn
    Ranch Hand
    Posts: 4632
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    to start
    if (KeyEvent.KEY_TYPED > 0)
    will return the event id, in this case 400, so > 0 will always be true.

    but adding the keyListener after you've clicked exitmenu, or X, won't tell
    you if changes have been made prior (the keyListener is not retrospective).

    in the code I posted, the KeyboardFocusManager is listening for any key, on
    any component. Any KeyEvent will change the flag to true, then, when exiting,
    the flag is checked and appropriate action taken.

    also, in the code I posted, to work with an exitmenu, the code would need to
    be changed to move the windowListener code into a separate method, which is
    then called from either windowClosing() or the exitmenu's actionPerformed().

    perhaps part of your problem is not including this line (haven't read all the thread)
    f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

    can you post a very simple program (similar in length to what I posted),
    so we can see exactly how you've put it together
     
    Ben Jordan
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator


    Here is my code....I apploigize for the length.. I actully removed a whole lot of other code for each of the menu items. I think my exit button will work now...Iknow it might better to write a seperate save () method but I am alright with this. How owuld I get the window one working now?

    thanks,
    Ben
     
    Michael Dunn
    Ranch Hand
    Posts: 4632
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    see if you can follow this.
    I removed all the file stuff - not related to the problem.

    note: keylistener is not the best solution for this - what will happen if
    data is pasted into the textArea?

     
    Ranch Hand
    Posts: 42
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Here is my final program
    [code}
    //Bradley Jordan
    //Final Project



    import java.awt.*;
    import java.io.File;
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.io.StringWriter;
    import javax.swing.*;
    import java.awt.event.*;



    /** this is the class and all of the lovely variables needed for this to run*/

    public class FileViewer extends JPanel implements KeyListener
    {
    private File file;
    private JScrollPane scrollPane;
    private JTextArea display;
    boolean changes = false;

    /** method for creating the fileviewer*/
    public FileViewer ()
    {
    setLayout(new GridLayout(1,1));
    display = new JTextArea();
    display.setFont(new Font("Courier", Font.PLAIN, 12));
    display.setEditable(true);
    scrollPane = new JScrollPane(display);
    add(scrollPane);
    }


    /** method for setting the new file.*/
    public void setFile (File file) throws IOException
    {
    this.file = file;
    refreshContents();
    }
    /** method for updating the JText Area with the new file.*/
    private void refreshContents () throws IOException
    {
    BufferedReader in = new BufferedReader(new FileReader(file));
    StringWriter out = new StringWriter();
    PrintWriter pout = new PrintWriter(out);

    for (String str = in.readLine();
    str != null;
    str = in.readLine())
    {
    pout.println(str);
    }
    pout.flush();

    String contents = out.toString();
    display.setText(contents);
    pout.close();
    out.close();
    in.close();
    }

    /** this is creates the fileview in the in frame see the name. It wouldn't work without this, all the "work" gets done in here*/

    public static JFrame createFileViewerInFrame (String filename)
    throws IOException
    {
    final FileViewer viewer = new FileViewer();
    viewer.setFile(new File(filename));

    final JFrame frame = new JFrame(filename);
    frame.getContentPane().setLayout(new GridLayout(1,1));
    frame.add(viewer);

    // This handles the window's close button.
    frame.addWindowListener(new WindowAdapter ()
    {
    public void windowClosing (WindowEvent event)
    {
    if (viewer.changes == true)
    {
    int save = JOptionPane.showConfirmDialog(null,"The data has been changed, save?","Save?",JOptionPane.YES_NO_OPTION);
    if(save == JOptionPane.YES_OPTION)
    {
    try
    {
    String text = viewer.display.getText();
    BufferedWriter out = new BufferedWriter(new FileWriter(viewer.file));
    viewer.changes = false;
    out.write(text);
    out.flush();
    }
    catch(IOException ioe)
    {
    JOptionPane.showConfirmDialog(null, "Please try again. An error has occured","Output Error", JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
    }
    }
    }
    exit(frame);
    }
    });




    setMenuBar(frame, viewer);

    frame.setVisible(true);
    frame.setSize(600, 800);

    return frame;
    }
    /** this creates the menubar and than the submenus after that. All of the listners are added in here as well*/
    private static void setMenuBar (final JFrame frame, final FileViewer viewer)
    {
    JMenuBar menuBar = new JMenuBar();

    viewer.display.addKeyListener(new KeyAdapter(){public void keyTyped(KeyEvent
    event)
    {viewer.changes = true;;}});


    JMenu fileMenu = new JMenu("File");
    menuBar.add(fileMenu);
    fileMenu.setMnemonic('f');
    JMenu editMenu = new JMenu("Edit");
    menuBar.add(editMenu);
    editMenu.setMnemonic('e');
    JMenu helpMenu = new JMenu("Help");
    menuBar.add(helpMenu);
    helpMenu.setMnemonic('h');

    JMenuItem openMenuItem = new JMenuItem("Open");
    fileMenu.add(openMenuItem);
    openMenuItem.setMnemonic('o');

    JMenuItem saveMenuItem = new JMenuItem("Save");
    fileMenu.add(saveMenuItem);
    saveMenuItem.setMnemonic('s');

    JMenuItem exitMenuItem = new JMenuItem("Exit");
    fileMenu.add(exitMenuItem);
    exitMenuItem.setMnemonic('e');



    JMenuItem searchMenuItem = new JMenuItem("Search");
    editMenu.add(searchMenuItem);
    searchMenuItem.setMnemonic('s');

    JMenuItem replaceMenuItem = new JMenuItem("Replace");
    editMenu.add(replaceMenuItem);
    replaceMenuItem.setMnemonic('r');

    JMenuItem contentsMenuItem = new JMenuItem("Contents");
    helpMenu.add(contentsMenuItem);
    contentsMenuItem.setMnemonic('c');

    JMenuItem aboutMenuItem = new JMenuItem("About");
    helpMenu.add(aboutMenuItem);
    aboutMenuItem.setMnemonic('a');

    exitMenuItem.addActionListener(new ActionListener ()
    {
    public void actionPerformed (ActionEvent event)
    {
    if (viewer.changes == true)
    {
    int save = JOptionPane.showConfirmDialog(null,"The data has been changed, save?","Save?",JOptionPane.YES_NO_OPTION);
    if(save == JOptionPane.YES_OPTION)
    {
    try
    {
    String text = viewer.display.getText();
    BufferedWriter out = new BufferedWriter(new FileWriter(viewer.file));
    viewer.changes = false;
    out.write(text);
    out.flush();
    }
    catch(IOException ioe)
    {
    JOptionPane.showConfirmDialog(null, "Please try again. An error has occured","Output Error", JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
    }
    }
    }
    exit(frame);
    }
    });




    contentsMenuItem.addActionListener(new ActionListener ()
    {
    public void actionPerformed (ActionEvent event)
    {
    JOptionPane.showConfirmDialog(null, "This is a simple text editior"+ "\n" + "Works just like Notepad minus a few options","Instructions", JOptionPane.OK_CANCEL_OPTION,
    JOptionPane.INFORMATION_MESSAGE);
    }
    });

    aboutMenuItem.addActionListener(new ActionListener ()
    {
    public void actionPerformed (ActionEvent event)
    {
    JOptionPane.showConfirmDialog(null, "Written by Bradley Jordan" + "\n" + "Final Project" + "\n" + "April 26,2007","About", JOptionPane.OK_CANCEL_OPTION,
    JOptionPane.INFORMATION_MESSAGE);
    }
    });

    searchMenuItem.addActionListener(new ActionListener ()
    {
    public void actionPerformed (ActionEvent event)
    {


    String text = viewer.display.getText();
    String a = JOptionPane.showInputDialog(null, "Please enter a character to search for","Search", JOptionPane.QUESTION_MESSAGE);
    int index = text.indexOf(a, viewer.display.getCaret().getDot());
    if (index > -1)
    {
    viewer.display.getCaret().setDot(index);
    }
    }
    });
    replaceMenuItem.addActionListener(new ActionListener ()
    {
    public void actionPerformed (ActionEvent event)
    {


    String text = viewer.display.getText();
    String a = JOptionPane.showInputDialog(null, "Please enter a character to search for","Search", JOptionPane.QUESTION_MESSAGE);
    String b = JOptionPane.showInputDialog(null, "Please enter a character to replace for","Replace", JOptionPane.QUESTION_MESSAGE);
    int index = text.indexOf(a, viewer.display.getCaret().getDot());
    if (index > -1)
    {
    int length = b.length();
    viewer.display.replaceRange(b,index,index + length );
    }
    }
    });
    openMenuItem.addActionListener(new ActionListener ()


    {
    public void actionPerformed (ActionEvent event)


    {
    try
    {
    String newFile = JOptionPane.showInputDialog(null, "Please enter a file to open"+ "\n" + "Be sure include the entire location and file name i.e.:" + "\n" + "(C:\\temp\\file_name)","Open", JOptionPane.QUESTION_MESSAGE);
    viewer.setFile(new File(newFile));
    viewer.changes = false;
    }
    catch(IOException ioe)
    {
    JOptionPane.showConfirmDialog(null, "You inputed a file name that does not exist or is in a differnet location","Input Error", JOptionPane.OK_CANCEL_OPTION,
    JOptionPane.INFORMATION_MESSAGE);
    }

    }

    });

    saveMenuItem.addActionListener(new ActionListener ()


    {
    public void actionPerformed (ActionEvent event)


    {
    try
    {

    String text = viewer.display.getText();
    BufferedWriter out = new BufferedWriter(new FileWriter(viewer.file));
    viewer.changes = false;
    out.write(text);
    out.flush();
    }
    catch(IOException ioe)
    {
    JOptionPane.showConfirmDialog(null, "Please try again. An error has occured","Output Error", JOptionPane.OK_CANCEL_OPTION,
    JOptionPane.INFORMATION_MESSAGE);
    }

    }

    });









    frame.setJMenuBar(menuBar);

    }

    public void keyTyped(KeyEvent e)
    {

    }
    public void keyReleased(KeyEvent e)
    {

    }
    public void keyPressed(KeyEvent e)
    {

    }






    /*
    What follows here is a rather convoluted mess of multithreading
    code that is not actually necessary. This is being done to avoid
    calling System.exit() to exit the virtual machine. The only
    other way to exit the virtual machine is for all non-daemon
    threads to stop. So we have to make sure there is at least one
    non-daemon thread (the main thread) AND we have to make sure
    there are no other non-daemon threads.
    */
    private static boolean exit = false;
    private static Object lockObject = new Object();

    public static void main (String [] args) throws Exception
    {
    final String filename = args[0];
    Thread t = new Thread ()
    {
    public void run ()
    {
    synchronized (lockObject)
    {
    try
    {
    /*
    This will start the AWT event queue which
    we want to be started as a daemon thread.
    The only way this can be assured is if
    the parent thread (this thread) is also
    a daemon thread.
    */
    createFileViewerInFrame(filename).setVisible(true);
    }
    catch (IOException ioe)
    {
    ioe.printStackTrace();
    FileViewer.exit(null);

    }
    }
    }
    };
    t.setDaemon(true); // Make it a daemon.
    synchronized (lockObject)
    {
    t.start();
    while (!exit)
    {
    try
    {
    /*
    Wait here until notified. Since this thread is
    NOT a daemon thread, this keeps the virtual machine
    alive.
    */
    lockObject.wait();
    }
    catch (InterruptedException checkAgain) {}
    }
    }
    }

    public static void exit (JFrame frame)
    {
    synchronized (lockObject)
    {
    if (frame != null)
    {
    frame.setVisible(false);
    /*
    We need to dispose of the frame so that the AWT event
    queue will not keep the virtual machine around waiting
    for GUI events.
    */
    frame.dispose();
    }
    exit = true;
    /*
    Tell the main thread it is time to stop waiting.
    */
    lockObject.notify();
    }
    }
    }

    [/code]

    thanks for all your help...
    reply
      Bookmark Topic Watch Topic
    • New Topic