# 2
It's kinda massive, but OK. You'll have to click Edit > Find and Replace to get the error.import java.awt.datatransfer.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.undo.*;
import java.util.regex.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.io.*;
public class JesWord extends JFrame implements ActionListener, ItemListener{
protected UndoAction undo = new UndoAction();
protected RedoAction redo = new RedoAction();
protected File file;
protected static LinkedList<File> recent = new LinkedList<File>();
protected BufferedReader reader;
protected BufferedWriter writer;
protected boolean unsaved = false;
protected UndoManager um = new UndoManager();
protected GapContent content = new GapContent();
protected DefaultEditorKit editor = new DefaultEditorKit();
protected DefaultStyledDocument doc = new DefaultStyledDocument(content, new StyleContext());
protected JTextPane tp = new JTextPane(doc);
protected InputMap im = tp.getInputMap();
/**
*Creates a new instance of JesWord.
*/
public JesWord() {
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_DOWN_MASK), undo);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Y, KeyEvent.CTRL_DOWN_MASK), redo);
doc.addUndoableEditListener(new UndoHandler());
JMenuBar menuBar;
JMenu menu;
JMenuItem menuItem;
JMenu subMenu;
menuBar = new JMenuBar();
menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
menuItem = new JMenuItem("New", KeyEvent.VK_N);
menuItem.setAccelerator(KeyStroke.getKeyStroke(menuItem.getMnemonic(), InputEvent.CTRL_DOWN_MASK));
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Open", KeyEvent.VK_O);
menuItem.setAccelerator(KeyStroke.getKeyStroke(menuItem.getMnemonic(), InputEvent.CTRL_DOWN_MASK));
menuItem.addActionListener(this);
menu.add(menuItem);
subMenu = new JMenu("Open Recent");
subMenu.setMnemonic(KeyEvent.VK_R);
for(int i = 0; i < recent.size(); i++) {
menuItem = new JMenuItem(recent.get(i).getName(), KeyEvent.VK_0 + i);
menuItem.setAccelerator(KeyStroke.getKeyStroke(menuItem.getMnemonic(), InputEvent.CTRL_DOWN_MASK));
menuItem.addActionListener(this);
subMenu.add(menuItem);
}
menu.add(subMenu);
menuItem = new JMenuItem("Save", KeyEvent.VK_S);
menuItem.setAccelerator(KeyStroke.getKeyStroke(menuItem.getMnemonic(), InputEvent.CTRL_DOWN_MASK));
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Save As", KeyEvent.VK_A);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,
InputEvent.CTRL_DOWN_MASK + InputEvent.SHIFT_DOWN_MASK));
menuItem.addActionListener(this);
menu.add(menuItem);
menu.addSeparator();
menuItem = new JMenuItem("Exit", KeyEvent.VK_X);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, InputEvent.SHIFT_DOWN_MASK));
menuItem.addActionListener(this);
menu.add(menuItem);
menuBar.add(menu);
menu = new JMenu("Edit");
menu.setMnemonic(KeyEvent.VK_E);
menu.add(undo);
menu.getItem(0).setMnemonic(KeyEvent.VK_U);
menu.getItem(0).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK));
menu.add(redo);
menu.getItem(1).setMnemonic(KeyEvent.VK_R);
menu.getItem(1).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK));
menu.addSeparator();
menuItem = new JMenuItem("Cut", KeyEvent.VK_C);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_DOWN_MASK));
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Copy", KeyEvent.VK_O);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK));
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Paste", KeyEvent.VK_P);
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK));
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Paste Special", KeyEvent.VK_S);
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Delete", KeyEvent.VK_DELETE);
menuItem.addActionListener(this);
menu.add(menuItem);
menuItem = new JMenuItem("Select All", KeyEvent.VK_A);
menuItem.setAccelerator(KeyStroke.getKeyStroke(menuItem.getMnemonic(), InputEvent.CTRL_DOWN_MASK));
menuItem.addActionListener(this);
menu.add(menuItem);
menu.addSeparator();
menuItem = new JMenuItem("Find and Replace", KeyEvent.VK_E);
menuItem.setAccelerator(KeyStroke.getKeyStroke(menuItem.getMnemonic(), InputEvent.CTRL_DOWN_MASK));
menuItem.addActionListener(this);
menu.add(menuItem);
menuBar.add(menu);
setJMenuBar(menuBar);
add(tp);
setTitle();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
/**
*Creates a new {@code JesWord} to edit the specified file.
*/
public JesWord(File f) {
this();
init(f);
}
/**
*Initializes this {@code JesWord} based on the specified file.
*/
protected void init(File f) {
try{
reader = new BufferedReader(new FileReader(f));
editor.read(reader, doc, 0);
reader.close();
file = f;
setTitle();
}catch(FileNotFoundException e) {
JOptionPane.showMessageDialog(
this,
"I couldn't find the file specified" + (f.getName().equals("") ? "" : ", \"" + f.getName()) + "\".",
"File Not Found",
JOptionPane.ERROR_MESSAGE
);
}catch(IOException e) {
JOptionPane.showMessageDialog(
this,
"I encountered an error while opening the file" +
(file.getName().equals("") ? "" : ", \"" + file.getName() + "\"") +"; aborting.",
"Error While Opening",
JOptionPane.ERROR_MESSAGE
);
}catch(BadLocationException e) {
assert false : e;
}
}
/**
*Returns whether the current {@code File} is null.
*/
protected final boolean isNull() {
return file == null;
}
/**
*Writes the current data to the specified file.
*/
protected void writeTo(File f) {
try{
writer = new BufferedWriter(new FileWriter(f));
editor.write(writer, doc, 0, doc.getLength());
writer.flush();
writer.close();
}catch(IOException e) {
JOptionPane.showMessageDialog(
this,
"I encountered an error while saving the file" +
(file.getName().equals("") ? "" : ", \"" + file.getName() + ",\"") +
" and recommend that you try saving it again.",
"Error While Saving",
JOptionPane.ERROR_MESSAGE
);
}catch(BadLocationException ble) {
System.err.println(ble);
return;
}
unsaved = false;
if(!f.equals(file)) {
recent.remove(file);// file should occur in recent 0 or 1 times
recent.add(file);
if(recent.size() > 10) recent.remove();// 10 = maximum # recent files
file = f;
}
setTitle();
}
/**
*Prompts the user for an address in the usual manner, and delegates the actual writing to {@link writeTo(File)}.
*/
public void saveAs() {
FileDialog fd = new FileDialog(this, "Save As", FileDialog.SAVE);
fd.setVisible(true);
File f = null;
try{
f = new File(fd.getFile());
}catch(NullPointerException npe) {
return;
}
writeTo(f);
setTitle();
}
/**
*If the file currently referenced is non-null, calls {@link writeTo(File)}; otherwise, operation
*is delegated to {@link saveAs()}.
*/
public void save() {
if(isNull()) saveAs();
else writeTo(file);
}
/**
*Prompts the user for an address in the usual manner, and delegates the actual reading to {@link init(File)}.
*/
public void open() {
close();
FileDialog fd = new FileDialog(this, "Open", FileDialog.LOAD);
fd.setVisible(true);
File f = null;
try{
init(f = new File(fd.getFile()));
}catch(NullPointerException npe) {
//init canceled
}
setTitle();
}
/**
*Sets the title of this {@code JFrame} in a predetermined manner. If the {@code File} currently referenced is null,
*the title is "New Document ~ JesWord"; otherwise, the title is "<filename> ~ JesWord".
*/
public void setTitle() {
super.setTitle((isNull() ? "New Document" : file.getName()) + " ~ JesWord");
}
/**
*Redirects to {@link setTitle())}, ignoring the {@code String} argument.
*/
public void setTitle(String text) {
setTitle();
}
public void close() {
if(unsaved) {
int value = JOptionPane.showConfirmDialog(
this,
"Save changes to the file" + (file.getName().equals("") || isNull() ? "" : ", \"" + file.getName() + "\"") + "?",
"Save Changes?",
JOptionPane.WARNING_MESSAGE,
JOptionPane.YES_NO_CANCEL_OPTION
);
if(value == JOptionPane.YES_OPTION) save();
else if(value == JOptionPane.NO_OPTION);
else if(value == JOptionPane.CANCEL_OPTION) return;
else close();// Exiting is an invalid response.
}
setTitle();
if(content.length() > 0) try{
doc.remove(0, doc.getLength());
}catch(BadLocationException ble) {
assert false;// This is impossible.
}
}
public void actionPerformed(ActionEvent ae) {
String action = ae.getActionCommand();
if(action.equals("New")) {
close();
return;
}
if(action.equals("Open")) {
open();
return;
}
for(int i = 0; i < recent.size(); i++) if(action.equals(recent.get(i).getName())) {
close();
init(recent.get(i));
return;
}
if(action.equals("Save")) {
save();
return;
}
if(action.equals("Save As")) {
saveAs();
return;
}
if(action.equals("Exit")) {
close();
System.exit(0);
}
if(action.equals("Cut")){
tp.cut();
return;
}
if(action.equals("Copy")){
tp.copy();
return;
}
if(action.equals("Paste")){
tp.paste();
return;
}
if(action.equals("Delete")){
if(tp.getSelectionStart() >= tp.getSelectionEnd()) tp.setSelectionEnd(tp.getSelectionEnd() + 1);
tp.replaceSelection("");
return;
}
if(action.equals("Select All")){
tp.selectAll();
return;
}
if(action.equals("Find and Replace")){
FindDialog fd = new FindDialog(this);
return;
}
System.out.println("action uncaught: " + action);
}
protected class FindDialog extends JDialog implements ActionListener{
JCheckBox[] checkBoxes = {
new JCheckBox("Match Case"),
new JCheckBox("Only In Selection"),
new JCheckBox("Highlight All"),
new JCheckBox("Whole Words"),
new JCheckBox("Search Up"),
new JCheckBox("Wrap Around"),
new JCheckBox("Find Regex")
};
int[] mnemonics = {
'C',
'S',
'H',
'W',
'U',
'A',
'R'
};
FindDialog(final JesWord owner){
super(owner, "Find and Replace", false);
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
Box left = new Box(BoxLayout.Y_AXIS);
left.add(new JLabel("Find What: "));
left.add(new JLabel("Replace With: "));
Box center = new Box(BoxLayout.Y_AXIS);
center.add(new JTextArea());
center.add(new JTextArea());
assert mnemonics.length == checkBoxes.length;
JPanel cbp = new JPanel(new GridBagLayout());
for(int i = 0; i < checkBoxes.length; i++){
checkBoxes[i].setMnemonic(mnemonics[i]);
checkBoxes[i].addItemListener(owner);
cbp.add(checkBoxes[i]);
}
cbp.applyComponentOrientation(ComponentOrientation.getOrientation(Locale.getDefault()));
center.add(cbp);
left.add(Box.createVerticalStrut(cbp.getHeight()));
// makin' it look purty
Box right = new Box(BoxLayout.Y_AXIS);
JButton btnFind = new JButton("Find");
btnFind.addActionListener(this);
right.add(btnFind);
JButton btnReplace = new JButton("Replace");
btnReplace.addActionListener(this);
right.add(btnReplace);
JButton btnReplaceAll = new JButton("ReplaceAll");
btnReplaceAll.addActionListener(this);
right.add(btnReplaceAll);
JButton btnClose = new JButton("Close");
btnClose.addActionListener(this);
right.add(btnClose);
JButton btnHelp = new JButton("Help");
btnHelp.addActionListener(this);
right.add(btnHelp);
add(left);
add(center);
add(right);
setVisible(true);
}
public void actionPerformed(ActionEvent ae){
String action = ae.getActionCommand();
if(action.equals("Find")){
find(((JTextComponent)((Container)getComponent(1)).getComponent(1)).getText());
// That's pretty hard to read, but it amounts to 'center.getComponent(1).getText()'.
return;
}
if(action.equals("Replace")){
replace(((JTextComponent)((Container)getComponent(1)).getComponent(1)).getText(),
((JTextComponent)((Container)getComponent(1)).getComponent(2)).getText());
// ^ the only difference
return;
}
if(action.equals("ReplaceAll")){
replaceAll(((JTextComponent)((Container)getComponent(1)).getComponent(1)).getText(),
/* the only difference ^ */((JTextComponent)((Container)getComponent(1)).getComponent(2)).getText());
return;
}
if(action.equals("Close")){
dispose();
return;
}
if(action.equals("Help")){
// Open the Help files on 'Find and Replace'.
return;
}
}
}
protected class UndoHandler implements UndoableEditListener{
public void undoableEditHappened(UndoableEditEvent uee){
um.addEdit(uee.getEdit());
update();
}
}
protected class RedoAction extends AbstractAction{
public RedoAction() {
super("Redo");
setEnabled(false);
}
public void actionPerformed(ActionEvent ae) {
try {
um.redo();
} catch (CannotRedoException cre) {
System.err.println("Unable to redo: " + cre);
cre.printStackTrace();
}
update();
}
}
private void update() {
redo.setEnabled(um.canRedo());
redo.putValue(Action.NAME, (um.canUndo() ? um.getRedoPresentationName() : "Redo"));
undo.setEnabled(um.canUndo());
undo.putValue(Action.NAME, (um.canUndo() ? um.getUndoPresentationName() : "Undo"));
}
protected class UndoAction extends AbstractAction{
public UndoAction() {
super("Undo");
setEnabled(false);
}
public void actionPerformed(ActionEvent ae) {
try {
um.undo();
} catch (CannotUndoException cre) {
System.err.println("Unable to undo: " + cre);
cre.printStackTrace();
}
update();
}
}
protected void select(int start, int end){
tp.setCaretPosition(start);
tp.moveCaretPosition(end);
}
private String textFound = "";
private int from, to = 0;
private boolean reg = false;
protected boolean find(String textOrRegex){
if(textOrRegex.equals("")){
JOptionPane.showMessageDialog(this, "Please enter some text to find.");
return false;
}
boolean found;
String full = tp.getText();
if(reg){
Matcher m = Pattern.compile(textOrRegex).matcher(full.substring(to));
if(found = m.find()){
textFound = textOrRegex;
select(from = m.start() + to, to = m.end() + to);// Adjust 'from' and 'to' according to substring offset.
}
}else{
int index = full.indexOf(textOrRegex, to);
if(found = index != -1){
textFound = textOrRegex;
select(from = index, to = index + textOrRegex.length());// Adjust 'to' according to text offset.
}
}
return found;
}
protected boolean findNext(){
return find(textFound);
}
protected boolean replace(String old, String neu){
boolean found;
if(reg){
if(tp.getSelectionStart() < tp.getSelectionEnd() && tp.getSelectedText().matches(old)){
if(found = find(old)) tp.replaceSelection(neu);
}else found = find(old);
}else{
if(tp.getSelectionStart() < tp.getSelectionEnd() && tp.getSelectedText().equals(old)){
if(found = find(old)) tp.replaceSelection(neu);
}else found = find(old);
}
return found;
}
protected boolean replaceAll(String old, String neu){
boolean found = false;
while(replace(old, neu)) found = true;
return found;
}
public void itemStateChanged(ItemEvent ie) {
Object source = ie.getSource();
if(source instanceof JCheckBox && ((JCheckBox)source).getText().equals("Use input as regex?")){
reg = ((JCheckBox)source).isSelected();
}
}
public static void main(String[] args) {
JesWord w = new JesWord();
}
}
Message was edited by:
Jesdisciple