На swing писал только в колледже, но от нечего делать немного переписал ваш код.
Сильно заморачиваться не стал - вариантов архитектуры много..
Но я бы посоветовал не увлекаться обьявлением переменных как членов класса, если не планируется их использовать. Также по возможности не включайте много логики в конструктор (ИМХО)
Ну и названия классов не очень правильные как мне кажется.
Также различные размеры элементов и текстовые сообщения желательно обьявлять как константы.
И не помешало бы добавить проверку -действительно ли выбранный файл - текстовый.
package wordpad;
public class RunTextEditor {
public static void main(String args[]) {
new Environment().run();
}
}
package wordpad;
import javax.swing.*;
import java.awt.*;
// Название класса не правильное!
public class Service extends JLabel {
private static final long serialVersionUID = 1L;
public Service() {
super();
setPreferredSize(new Dimension(200, 30));
setHorizontalAlignment(SwingConstants.CENTER);
}
public Service(String message) {
this();
setMessage(message);
}
public void setMessage(String message) {
setText(message);
}
}
package wordpad;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
// Я бы переименовал в FileManager или что-то подобное
public class LoadFile {
private FileHandler handler;
// интерфейс обработчика можно вынести и в отдельный класс
public interface FileHandler {
void onLoad(Document document);
void onSave(Document document);
void onError(String message);
}
// конструктор приватный чтобы не проверять обработчик на null
private LoadFile() {
}
public LoadFile(FileHandler handler) {
this();
setHAndler(handler);
}
public FileHandler getHandler() {
return handler;
}
public void setHAndler(FileHandler handler) {
this.handler = handler;
}
public void processLoad(File file) {
if ( file == null || !file.exists()) {
handler.onError("No filename present");
return;
}
try {
FileReader fileReader = new FileReader(file);
String text = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath())));
Document document = new Document(file.getName(), 0, text);
fileReader.close();
handler.onLoad(document);
} catch (IOException exc) {
handler.onError("Error opening or reading file.");
}
}
}
package wordpad;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import wordpad.LoadFile.FileHandler;
public class FileMenu extends JMenuBar {
private static final long serialVersionUID = 1L;
private FileMenu() {
super();
}
public FileMenu(FileHandler handler) {
this();
JMenu menu = new JMenu("File");
JMenuItem loadItem = new JMenuItem("Load");
JMenuItem saveItem = new JMenuItem("Save");
JFileChooser fileChooser = new JFileChooser();
LoadFile fileManager = new LoadFile(handler);
menu.add(loadItem);
menu.add(saveItem);
add(menu);
loadItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
fileManager.processLoad(file);
} else {
fileManager.getHandler().onError("No file selected.");
}
}
});
//TODO добавьте сохранение сами :)
}
}
package wordpad;
import javax.swing.*;
import wordpad.LoadFile.FileHandler;
import java.awt.*;
// Не очень красивое название класса на мой взгляд
public class Environment {
private JTextArea textArea;
private JFrame mainFrame;
private Service statusMessage;
private FileHandler handler = new FileHandler() {
@Override
public void onSave(Document document) {
statusMessage.setText(document.getFileName() + " saved!");
}
@Override
public void onLoad(Document document) {
textArea.setText(document.getContent());
statusMessage.setText(document.getFileName() + " loaded");
}
@Override
public void onError(String message) {
statusMessage.setText(message);
}
};
public Environment() {
mainFrame = new JFrame("Text Editor");
mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
mainFrame.getContentPane().setLayout(new FlowLayout());
mainFrame.setSize(270, 420);
textArea = new JTextArea();
JScrollPane jScrollPane = new JScrollPane(textArea);
jScrollPane.setPreferredSize(new Dimension(250, 200));
jScrollPane.getViewport().add(textArea);
FileMenu fileMenu = new FileMenu(handler);
mainFrame.setJMenuBar(fileMenu);
Container container = mainFrame.getContentPane();
container.add(jScrollPane);
statusMessage = new Service();
container.add(statusMessage);
}
public void run() {
mainFrame.setVisible(true);
}
}
package wordpad;
/**
* @author Timur Nikiforov
*/
public class Document {
private String fileName;
private String content;
// Для чего нужна позиция каретки?
private int caretPosition;
public Document(String fileName, int caretPosition, String content) {
this.setFileName(fileName);
this.setCaretPosition(caretPosition);
this.setContent(content);
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getCaretPosition() {
return caretPosition;
}
public void setCaretPosition(int caretPosition) {
this.caretPosition = caretPosition;
}
}
ЗЫ: B как сказали выше - испульзуйте лучше JavaFX
По поводу книги:
вот неплохая и читается легко.