На 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 
По поводу книги: 
вот неплохая и читается легко.