A
A
Ann As2016-01-26 19:18:32
Java
Ann As, 2016-01-26 19:18:32

How to design a text editor class structure?

Good afternoon.
Just started learning programming and wrote a small 600 line editor. I wanted to rewrite in OOP style and got a bunch ... which does not work.
In the IDE, I created an Environment class in which the main components are initialized (Frame, text area, the menu class and the service class are called (process status line ("file open", "file closed", etc.))). There is another class - Document (stores the name of the file, the number of characters, etc. (then I will send it to the Sevice class).
My problems: I cannot open a file from the menu class normally and create a documentby opening the file (there was a moment when another editor was created, but the text area still remained empty).
But even if I manage to create a document and pass content to it, I cannot pass the same text to Environment .
The service class is a label at the bottom of the editor that must constantly update its content (the document event source and the environment itself).
Questions
1. Does anyone have a design scheme for such an application or who can suggest the main stages of implementation?
2. Downloaded the books: Perfect Code and the Gang of Four book. Will they help at this stage?
This is the third day I've been working on this problem. Was at Google.
Update :
1. As I understand it, I need to learn UML
2. Further books on software
architecture ---- Only after that I should already be able to design an application - right?
Broken heap below:
START-UP CLASS

import javax.swing.*;

public class RunTextEditor {
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Environment();
            }
        });
    }
}

ENVIRONMENT CLASS
import javax.swing.*;
import java.awt.*;


public class Environment {
    public static JTextArea textArea;
    private JFrame frame;
    private MainMenu mainMenu;
    private Container container;
    private JScrollPane jScrollPane;
    private Service statusMessage;

    Environment()
    {
        frame = new JFrame("Text Editor");
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.getContentPane().setLayout(new FlowLayout());
            frame.setSize(270, 420);

        textArea = new JTextArea();
            jScrollPane = new JScrollPane(textArea);
            jScrollPane.setPreferredSize(new Dimension(250, 200));
            jScrollPane.getViewport().add(textArea);

        mainMenu = new MainMenu();

        frame.setJMenuBar(mainMenu.getMenuBar());
        container = frame.getContentPane();
            container.add(jScrollPane);
        statusMessage = new Service();
            container.add(statusMessage.getStatusMessage());
        frame.setVisible(true);
    }

    public static JTextArea getTextArea()
    {
        return textArea;
    }
}

CLASS DOCUMENT
public class Document {

    private String fileName;
    private String content;
    private int caretPosition;

    Document(String fn, int cp, String ct)
    {
        fileName = fn;
        caretPosition = cp;
        content = ct;
    }

    public void setCaretPosition(int x)
    {
        caretPosition = x;
    }
}

CLASS MENUBAR
import javax.swing.*;

public class MainMenu {
    private JMenuBar menuBar;
    private FileMenu fileMenu;

    MainMenu()
    {
        menuBar = new JMenuBar();
        fileMenu = new FileMenu();
            menuBar.add(fileMenu.getFileMenu());
    }

    public JMenuBar getMenuBar()
    {
        return menuBar;
    }
}

CLASS MENU-FILE
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class FileMenu {
    private JMenu menuFile;
    private JMenuItem loadFile;
    private JMenuItem saveFile;
    private JFileChooser fileChooser;
    private Service service;

    FileMenu()
    {
        menuFile = new JMenu("File");
        loadFile = new JMenuItem("Load");
            loadFile.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String fileName = "";
                    fileChooser = new JFileChooser();
                    service = new Service();
                    int result = fileChooser.showOpenDialog(null);

                    if (result == JFileChooser.APPROVE_OPTION){
                        fileName = fileChooser.getSelectedFile().getName();
                    } else {
                        service = new Service("No file selected.");
                    }
                    LoadFile loadFile = new LoadFile(fileName);
                    Environment.textArea.setText(loadFile.getContent());
                }
            });
        saveFile = new JMenuItem("Save");
            menuFile.add(loadFile);
            menuFile.add(saveFile);
    }

    public JMenu getFileMenu()
    {
        return menuFile;
    }
}

FILE UPLOAD CLASS
import javax.swing.*;
import java.io.FileReader;
import java.io.IOException;

public class LoadFile{

    private String fileName;
    private static JTextArea textArea;

    LoadFile(String name)
    {
        FileReader fw;
        fileName = name;
        Service statusMsg;
        Document document;
        textArea = new JTextArea();

        if(name.length() == 0)
        {
            statusMsg = new Service("No filename present");
            return;
        }

        try{
            fw = new FileReader(fileName);
            textArea.read(fw, null);
            document = new Document(fileName, 0, textArea.getText());
            fw.close();
        }catch (IOException exc){
            statusMsg = new Service("Error opening or reading file.");
            return;
        }
    }

    public static String getContent()
    {
        return textArea.getText();
    }
}

CLASS SERVICE
import javax.swing.*;
import java.awt.*;
public class Service {
    private JLabel statusMessage;


    Service()
    {
        statusMessage = new JLabel("Test");
        statusMessage.setPreferredSize(new Dimension(200, 30));
        statusMessage.setHorizontalAlignment(SwingConstants.CENTER);
    }

    Service(String message)
    {
        statusMessage = new JLabel(message);
        statusMessage.setPreferredSize(new Dimension(200, 30));
        statusMessage.setHorizontalAlignment(SwingConstants.CENTER);
    }

    public JLabel getStatusMessage()
    {
        return statusMessage;
    }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
Timur, 2016-01-27
@snave

I wrote swing only in college, but I rewrote your code a little because of nothing to do.
I didn’t bother much - there are many architecture options ..
But I would advise you not to get involved in declaring variables as class members if you do not plan to use them. Also, if possible, do not include a lot of logic in the constructor (IMHO)
Well, the class names are not very correct, as it seems to me.
It is also desirable to declare different sizes of elements and text messages as constants.
And it would not hurt to add a check - whether the selected file is really a text one.

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;
  }
}

ZY: B as said above - use better JavaFX
Regarding the book: it's not bad and it's easy to read.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question