I am trying to create a simple text editor, and I have run into a problem trying to take my JTextArea
and make it scroll-able via a JScrollPane
.
The conventional methods I know of have not worked, so I am wondering if anyone here can help. I am not sure where to start with this, so I am going to post my entire code. I have annotated it to help show what my methods do.
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import java.util.Hashtable;
@SuppressWarnings("serial")
public class GrooveEditor extends JFrame {
private Action openAction = new OpenAction();
private Action saveAction = new SaveAction();
private JTextComponent textComp;
@SuppressWarnings({ "rawtypes", "unused" })
private Hashtable actionHash = new Hashtable();
public static void main(String[] args) {
GrooveEditor editor = new GrooveEditor();
editor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
editor.setVisible(true);
}
// Create editor.
public GrooveEditor() {
super("Groove Text Editor");
textComp = createTextComponent();
makeActionsPretty();
Container content = getContentPane();
content.add(textComp, BorderLayout.CENTER);
setJMenuBar(createMenuBar());
setExtendedState(MAXIMIZED_BOTH);
}
// Create JTextComponent subclass.
private JTextComponent createTextComponent() {
JTextArea ta = new JTextArea();
ta.setLineWrap(true);
ta.setMargin(new Insets(10,10,10,10));
return ta;
}
protected void makeActionsPretty() {
Action a;
a = textComp.getActionMap().get(DefaultEditorKit.cutAction);
a.putValue(Action.SMALL_ICON, new ImageIcon("icons/cut.gif"));
a.putValue(Action.NAME, "Cut");
a = textComp.getActionMap().get(DefaultEditorKit.copyAction);
a.putValue(Action.SMALL_ICON, new ImageIcon("icons/copy.gif"));
a.putValue(Action.NAME, "Copy");
a = textComp.getActionMap().get(DefaultEditorKit.pasteAction);
a.putValue(Action.SMALL_ICON, new ImageIcon("icons/paste.gif"));
a.putValue(Action.NAME, "Paste");
a = textComp.getActionMap().get(DefaultEditorKit.selectAllAction);
a.putValue(Action.NAME, "Select All");
}
// Create a JMenuBar
protected JMenuBar createMenuBar() {
JMenuBar menubar = new JMenuBar();
menubar.add( Box.createHorizontalStrut(10));
JMenu file = new JMenu("File");
JMenu edit = new JMenu("Edit");
JMenu format = new JMenu("Format");
menubar.add(file);
menubar.add(edit);
menubar.add(format);
file.add(getOpenAction());
file.add(getSaveAction());
file.add(new ExitAction());
edit.add(textComp.getActionMap().get(DefaultEditorKit.cutAction));
edit.add(textComp.getActionMap().get(DefaultEditorKit.copyAction));
edit.add(textComp.getActionMap().get(DefaultEditorKit.pasteAction));
edit.add(textComp.getActionMap().get(DefaultEditorKit.selectAllAction));
return menubar;
}
// Subclass can override to use a different open action.
protected Action getOpenAction() { return openAction; }
// Subclass can override to use a different save action.
protected Action getSaveAction() { return saveAction; }
protected JTextComponent getTextComponent() { return textComp; }
// ********** ACTION INNER CLASSES ********** //
// A very simple exit action
public class ExitAction extends AbstractAction {
public ExitAction() { super("Exit"); }
@Override
public void actionPerformed(ActionEvent ev) { System.exit(0); }
}
// An action that opens an existing file
class OpenAction extends AbstractAction {
public OpenAction() {
super("Open", new ImageIcon("icons/open.gif"));
}
// Query user for a filename and attempt to open and read the file into the
// text component.
@Override
public void actionPerformed(ActionEvent ev) {
JFileChooser chooser = new JFileChooser();
if (chooser.showOpenDialog(GrooveEditor.this) !=
JFileChooser.APPROVE_OPTION)
return;
File file = chooser.getSelectedFile();
if (file == null)
return;
FileReader reader = null;
try {
reader = new FileReader(file);
textComp.read(reader, null);
}
catch (IOException ex) {
JOptionPane.showMessageDialog(GrooveEditor.this,
"File Not Found", "ERROR", JOptionPane.ERROR_MESSAGE);
}
finally {
if (reader != null) {
try {
reader.close();
} catch (IOException x) {}
}
}
}
}
// An action that saves the document to a file
class SaveAction extends AbstractAction {
public SaveAction() {
super("Save", new ImageIcon("icons/save.gif"));
}
// Query user for a filename and attempt to open and write the text
// component's content to the file.
@Override
public void actionPerformed(ActionEvent ev) {
JFileChooser chooser = new JFileChooser();
chooser.addChoosableFileFilter(new FileNameExtensionFilter("Text Document", "txt"));
chooser.addChoosableFileFilter(new FileNameExtensionFilter("HTML", "html"));
if (chooser.showSaveDialog(GrooveEditor.this) !=
JFileChooser.APPROVE_OPTION)
return;
@SuppressWarnings("unused")
String ext = "";
String extension = chooser.getFileFilter().getDescription();
if (extension == "txt") {
ext = ".txt";
}
File file = chooser.getSelectedFile();
if (file == null)
return;
FileWriter writer = null;
try {
writer = new FileWriter(file);
textComp.write(writer);
}
catch (IOException ex) {
JOptionPane.showMessageDialog(GrooveEditor.this,
"File Not Saved", "ERROR", JOptionPane.ERROR_MESSAGE);
}
finally {
if (writer != null) {
try {
writer.close();
} catch (IOException x) {}
}
}
}
}
}
You need to add your text component to JScrollPane
. For example instead of:
content.add(textComp, BorderLayout.CENTER);
use:
content.add(new JScrollPane(textComp), BorderLayout.CENTER);
For more details refer to How to Use Scroll Panes.