-1

I'm making a simple text editor in Java and for some reason my find and replace actions won't work, i made two separate frames, one for the find action, and the other to open up another frame with 2 jtextfields for find and replace. i have in my actionperformed

if(source == find){
        JFrame frame = new FindFrame();
        frame.setVisible(true);
    }

and in my findFrame i have the action that should be carried out when the user clicks on the JMenuItem called "Find".

class FindFrame extends JFrame implements ActionListener{
    JButton find = new JButton("Find");
    JTextField findtext = new JTextField("Find What", 20);
    FindFrame(){
        setSize(400, 100);
        setLocation(500, 300);
        setTitle("Find...");
        JPanel panel = new JPanel();
        panel.add(find);
        panel.add(findtext);
        Container cpane = getContentPane();
        cpane.add(panel, "Center");
        setVisible(true);
        find.addActionListener(this);
    }

    public void actionPerformed(ActionEvent evt) {
        Object source = evt.getSource();
        String command = evt.getActionCommand();
        String search = findtext.getText();
        int n = textarea.getText().indexOf(search);
        if(source == find){
            MenuFrame.textarea.select(n,n+search.length());
        }
    }
}

In my Replace frame where i want the user to find a word and replace it, anything you type into the find textfield and click the find button, it finds the first 3 characters on the text field, and the replace action just doesn't work at all, here is my replace frame

class replaceFrame extends JFrame implements ActionListener{
JButton find = new JButton("Find");
JButton replace = new JButton("Replace");
JTextField replacetext = new JTextField("Enter text to replace", 20);
JTextField findtext = new JTextField("Enter text to find", 20);
replaceFrame(){
    setSize(400, 100);
    setLocation(500, 300);
    setTitle("Replace");
    JPanel panel = new JPanel();
    panel.add(find);
    panel.add(findtext);
    panel.add(replace);
    panel.add(replacetext);
    Container cpane = getContentPane();
    cpane.add(panel, "Center");
    setVisible(true);
    find.addActionListener(this);
    replace.addActionListener(this);

}

public void actionPerformed(ActionEvent evt) {
    Object source = evt.getSource();
    String command = evt.getActionCommand();
    String search = find.getText();
    String replacing = replacetext.getText();
    int n = MenuFrame.textarea.getText().indexOf(search);
    if(command.equals("Find")){
        MenuFrame.textarea.select(n,n+search.length());
    }
    if(command.equals("Replace")){
        MenuFrame.textarea.replaceRange(replacing, n, n+search.length());
    }

}

}

the find and replace are two separate JMenuItems, when the user clicks on Find it opens up findframe and when they click on "replace" it opens up the replace frame which has a find textfield and a replace textfield.

here is the whole runnable code :

//Programmer Aly Badran – Project 10

import java.awt.*; 
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.DefaultEditorKit.CutAction;

class saveFrame extends JFrame implements ActionListener{
JPanel panel = new JPanel();
JPanel labelpanel = new JPanel();
JButton savebutton = new JButton("Save");
JButton dontsave = new JButton("Dont Save");
JLabel savelabel = new JLabel("Are you sure you want to close"?);                                                     
public saveFrame(){
setSize(400,100);
setLocation(500, 300);
setTitle("Saving...");
labelpanel.add(savelabel);
panel.add(savebutton);
panel.add(dontsave);
Container cpane = getContentPane();
cpane.add(panel, "South");
cpane.add(labelpanel, "Center");
setVisible(true);
savebutton.addActionListener(this);
dontsave.addActionListener(this);
}
public void actionPerformed(ActionEvent evt){
    Object source = evt.getSource();
    if(source == savebutton){
        System.exit(0);
    }
    else if(source == dontsave){
        System.exit(0);
    }

}

}
class replaceFrame extends JFrame implements ActionListener{
JButton find = new JButton("Find");
JButton replace = new JButton("Replace");
JTextField replacetext = new JTextField("Enter text to replace", 20);
JTextField findtext = new JTextField("Enter text to find", 20);
replaceFrame(){
    setSize(400, 100);
    setLocation(500, 300);
    setTitle("Replace");
    JPanel panel = new JPanel();
    panel.add(find);
    panel.add(findtext);
    panel.add(replace);
    panel.add(replacetext);
    Container cpane = getContentPane();
    cpane.add(panel, "Center");
    setVisible(true);
    find.addActionListener(this);
    replace.addActionListener(this);

}

public void actionPerformed(ActionEvent evt) {
    Object source = evt.getSource();
    String command = evt.getActionCommand();
    String search = find.getText();
    String replacing = replacetext.getText();
    int n = MenuFrame.textarea.getText().indexOf(search);
    if(command.equals("Find")){
        MenuFrame.textarea.select(n,n+search.length());
    }
    if(command.equals("Replace")){
        MenuFrame.textarea.replaceRange(replacing, n, n+search.length());
    }

}
}


class MenuFrame extends JFrame implements ActionListener, MouseListener{
static  JTextArea textarea = new JTextArea();
static JMenuBar menubar = new JMenuBar();
JMenu file = new JMenu("File");
JMenu edit = new JMenu("Edit");
JMenuItem copy = new JMenuItem(new DefaultEditorKit.CopyAction());
JMenuItem cut = new JMenuItem(new DefaultEditorKit.CutAction());
JMenuItem Paste = new JMenuItem(new DefaultEditorKit.PasteAction());
JMenuItem copyAction = new JMenuItem(new DefaultEditorKit.CopyAction());
JMenuItem cutAction = new JMenuItem(new DefaultEditorKit.CutAction());
JMenuItem pasteAction = new JMenuItem(new DefaultEditorKit.PasteAction());
JMenu search = new JMenu("Search");
JMenuItem open = new JMenuItem("Open");
JMenuItem close = new JMenuItem("Close");
JMenuItem quit = new JMenuItem("Quit");
JMenuItem find  = new JMenuItem("Find");
JMenuItem replace = new JMenuItem("Replace");
JMenu font = new JMenu("Font");
JCheckBoxMenuItem bold = new JCheckBoxMenuItem("Bold");
JCheckBoxMenuItem italic = new JCheckBoxMenuItem("Italic");
JPopupMenu popup;


public MenuFrame(){
    Container cpane = getContentPane();
    cpane.add(textarea);
    Toolkit tk = Toolkit.getDefaultToolkit();
    Dimension d = tk.getScreenSize();
    int screenheight = d.height;
    int screenwidth = d.width;
    setSize(screenwidth, screenheight);
    JPanel panel = new JPanel();
    ImageIcon closeicon = new ImageIcon("bin/close.png");
    ImageIcon openicon = new ImageIcon("bin/open.png");
    ImageIcon quiticon = new ImageIcon("bin/quit.jpeg");
    ImageIcon findicon = new ImageIcon("bin/find.png");
    ImageIcon replaceicon = new ImageIcon("bin/replace.png");
    ImageIcon boldicon = new ImageIcon("bin/bold.png");
    ImageIcon italicicon = new ImageIcon("bin/italic.png");
    ImageIcon copyicon = new ImageIcon("bin/copy.png");
    ImageIcon cuticon = new ImageIcon("bin/cut.png");
    ImageIcon pasteicon = new ImageIcon("bin/paste.png");
    Border matte = BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK);
    Border etched = BorderFactory.createEtchedBorder();
    popup = new JPopupMenu();

    copy.setText("Copy");
    cut.setText("Cut");
    Paste.setText("Paste");
    copy.setIcon(copyicon);
    cut.setIcon(cuticon);
    Paste.setIcon(pasteicon);

    copyAction.setText("Copy");
    cutAction.setText("Cut");
    pasteAction.setText("Paste");
    copyAction.setIcon(copyicon);
    cutAction.setIcon(cuticon);
    pasteAction.setIcon(pasteicon);

    popup.add(cut);
    popup.addSeparator();
    popup.add(copy);
    popup.addSeparator();
    popup.add(Paste);
    popup.addSeparator();
    popup.add(find);
    popup.addSeparator();
    popup.add(replace);

    edit.add(cutAction);
    edit.addSeparator();
    edit.add(copyAction);
    edit.addSeparator();
    edit.add(pasteAction);

    find.setIcon(findicon);
    replace.setIcon(replaceicon);
    close.setIcon(closeicon);
    menubar = new JMenuBar();
    textarea = new JTextArea("He has achieved success.", d.width, d.height);
    JScrollPane scroll = new JScrollPane(textarea);
    cpane.add(scroll);
    open = new JMenuItem("Open", openicon);
    close = new JMenuItem("Close", closeicon);
    quit = new JMenuItem("Quit", quiticon);
    find = new JMenuItem("Find", findicon);
    replace = new JMenuItem("Replace", replaceicon);
    bold = new JCheckBoxMenuItem("Bold", boldicon);
    italic = new JCheckBoxMenuItem("Italic", italicicon);
    textarea.setLineWrap(true);
    file.add(open);
    file.addSeparator();
    file.add(close);
    file.addSeparator();
    file.add(quit);
    menubar.add(file);
    menubar.add(edit);
    menubar.add(search);
    menubar.add(font);
    search.add(find);
    search.addSeparator();
    search.add(replace);
    font.add(bold);
    font.addSeparator();
    font.add(italic);
    copy.setEnabled(false);
    cut.setEnabled(false);
    Paste.setEnabled(false);
    find.addActionListener(this);
    italic.addActionListener(this);
    bold.addActionListener(this);
    quit.addActionListener(this);
    close.addActionListener(this);
    find.addActionListener(this);
    replace.addActionListener(this);
    cut.addActionListener(this);
    copy.addActionListener(this);
    Paste.addActionListener(this);
    cut.addMouseListener(this);     
    textarea.addMouseListener(this);
    copy.addMouseListener(this);
    Paste.addMouseListener(this);
    textarea.setComponentPopupMenu(popup);
    file.setBackground(Color.BLACK);
    edit.setBackground(Color.BLACK);
    search.setBackground(Color.BLACK);
    font.setBackground(Color.BLACK);
    panel.add(menubar);
    menubar.setBorder(matte);
    menubar.setBackground(Color.BLACK);
    textarea.setBorder(etched);
}
public void actionPerformed(ActionEvent evt){
    Object source = evt.getSource();
    String command = evt.getActionCommand();
    String s = textarea.getSelectedText();
    Font f = new Font("Italic", Font.ITALIC, 13);
    Font f2 = new Font("Bold", Font.BOLD, 13);

    if(italic.isSelected()){            
        textarea.setFont(f);
    }
    if(bold.isSelected()){
        textarea.setFont(f2);
    }
    if(bold.isSelected() && italic.isSelected()){
        textarea.setFont(f);
        textarea.setFont(f2);
    }
    if(command.equals("Quit"))
            System.exit(0);
    if(command.equals("Close")){
        JFrame frame = new saveFrame();
        frame.setVisible(true);
    }
    if(source == find){
        JFrame frame = new FindFrame();
        frame.setVisible(true);
    }
    if(command.equals("Replace")){
        JFrame frame2 = new replaceFrame();
        frame2.setVisible(true);
    }
}

public void mouseClicked(MouseEvent e) {
    boolean s = textarea.getSelectedText() != null;
    if(s){
        copy.setEnabled(true);
        cut.setEnabled(true);
        Paste.setEnabled(true);

    }
}


public void mouseEntered(MouseEvent e) {

}


public void mouseExited(MouseEvent e) {

}


public void mousePressed(MouseEvent e) {

}


public void mouseReleased(MouseEvent e) {

}
class FindFrame extends JFrame implements ActionListener{
    JButton find = new JButton("Find");
    JTextField findtext = new JTextField("Find What", 20);
    FindFrame(){
        setSize(400, 100);
        setLocation(500, 300);
        setTitle("Find...");
        JPanel panel = new JPanel();
        panel.add(find);
        panel.add(findtext);
        Container cpane = getContentPane();
        cpane.add(panel, "Center");
        setVisible(true);
        find.addActionListener(this);
    }

    public void actionPerformed(ActionEvent evt) {
        Object source = evt.getSource();
        String command = evt.getActionCommand();
        String search = findtext.getText();
        int n = textarea.getText().indexOf(search);
        if(source == find){
            MenuFrame.textarea.select(n,n+search.length());
        }
    }
}
}


public class Menus {
public static void main(String [] args){ 
    JFrame frame = new MenuFrame();
    frame.setJMenuBar(MenuFrame.menubar);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}

}
Aly Badran
  • 45
  • 5
  • Consider providing a [runnable example](https://stackoverflow.com/help/mcve) which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses – MadProgrammer May 15 '15 at 00:09
  • 1
    I "suspect" that `MenuFrame.textarea` means you are using `static` as means by which you can communicate between classes, this is a HORRIBLE, HORRIBLE idea and should be discouraged and discontinued immediately. Instead, you should use some kind of dialog to gather the information you need from the user and the action to be performing and allow the calling class to deal with it – MadProgrammer May 15 '15 at 00:11
  • *"for some reason my find and replace actions won't work"* - Really? How is not working? What are you expections? Can you provide a runnable example which demonstrates it "not working"? – MadProgrammer May 15 '15 at 00:12
  • would you be ok with me posting my entire program? it runs perfectly but you would have a clearer picture of what the issue is; – Aly Badran May 15 '15 at 00:54
  • I just want something that is concise, compiles and demonstrates your problem – MadProgrammer May 15 '15 at 01:00
  • just posted it, sorry for the long program – Aly Badran May 15 '15 at 01:00
  • Based on your code so far, you may want to take a look at [How to Make Dialogs](http://docs.oracle.com/javase/tutorial/uiswing/components/dialog.html) – MadProgrammer May 15 '15 at 01:02
  • and as for the find and replace methods? are they written correctly? – Aly Badran May 15 '15 at 01:04

2 Answers2

1

Your basic problem comes down to the fact that the "selection" highlight won't be painted while the JTextArea doesn't have focus, I know, awesome.

However, you could use a Highlighter instead, for example...

if (source == find) {
    try {
        DefaultHighlighter.DefaultHighlightPainter highlighter = new DefaultHighlighter.DefaultHighlightPainter(UIManager.getColor("TextArea.selectionBackground"));

        MenuFrame.textarea.getHighlighter().addHighlight(n, n + search.length(), highlighter);
    } catch (BadLocationException ex) {
        ex.printStackTrace();
    }
}

Which will paint a "highlight" over the specified area.

You may want to have a look at this for away to remove it

This and this may also be of interest

In your replace method, you are using the text of the find JButton instead of the findtext JTextField

//String search = find.getText();
String search = findtext.getText();
String replacing = replacetext.getText();
int n = MenuFrame.textarea.getText().indexOf(search);

Your codes also a mess (sorry, took me a while to navigate it).

For example, you're adding a ActionListener twice to the find menu item and probably some others, which caused to find windows to appear.

I'd avoid using Toolkit#getScreenSize(); in connection with JFrame#setSize, a better solution would be to use JFrame#setExtendedState and pass it JFrame#MAXIMIZED_BOTH, as this will also take into consideration the other UI assets that the OS may have fixed on the screen (like docks and task bars).

You really should be using dialogs instead of JFrames for your "short term input" mechanisms

Your also recreating a bunch of stuff you've already created, for example...

static JTextArea textarea = new JTextArea();
//...
textarea = new JTextArea("He has achieved success.", d.width, d.height);

What's worse, is you add the original instance of the textarea to the frame BEFORE you create the new one, which runs the risk of not knowing which component you are actually dealing with...which is just compounded by the fact that you're using a static reference to it so other classes can access it, which they shouldn't be allowed to do...

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • thank you, it works now ! but for some odd reason when it runs, two find frames are opening up, do you know why that is? – Aly Badran May 15 '15 at 01:27
  • @AlyBadran See extended commentry – MadProgrammer May 15 '15 at 01:28
  • wow, thanks alot for all that advice, i really appreciate your input on my program, the reason its such a mess and that i don't implement the methods such as the setextendedstate for the jframe is that i am currently taking an intro course in college and i pretty much just work with what i have learned and we haven't learned all the complex stuff you showed me, but i definitely enjoyed reading over your comments because it definitely helped me expand my knowledge in this topic! thanks alot !!! – Aly Badran May 15 '15 at 01:33
  • @AlyBadran Glad it could help, hope you have fun ;) – MadProgrammer May 15 '15 at 01:37
0

In replaceFrame, you are taking text to search from the find field (button), but you should take it from findtext (you are always searching for text "Find").

This is one of the reasons why code duplication is bad - you should extract the finding logic to one place and reuse it in both classes.

Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110
  • im sorry, im not really understanding what you're saying; in my replace frame i am extracting the text from the find textfield and trying to replace it with the replacing textfield but im not sure why its not working – Aly Badran May 15 '15 at 01:28