Issue
So I'm working on building a text editor using java, javaFx, I have to open a file in the (Editor VBox) and put the lines in a double linked list, then edit, delete, overWrite a line etc.., I made a textArea called textAr in the Editor VBox, but I have a problem in reaching a text in specific line from the textAr, so I can edit, or insert a text in the double linked list and the position that new text should be inserted in,I have to use (I) to insert so I can't use getSelectedText().., here is a picture for what is required as user interface..
here is what I'm trying to do to insert a text when I is pressed on the keyboard, I put getText from the textAr (text Area in editor VBox ), but it takes the whole text in the area, not in a specific line or position..In addition to crash when I press (I) on keyboard and black screen appears in the java Application program
Solution
You could look at this code and see if it helps.
It is not designed to be a really usable, fully functional text editor, just to implement the main features outlined in your question.
Also, if the design wasn't as provided, I'd do things differently, e.g. instead of having an edit command to manually initiate editing a row, automatically start editing the selected row on change of selection.
The code provided does not use a custom linked list structure, it just uses array lists.
To initiate operations in the editor, it is necessary to use a system specific shortcut key in combination with the command to be executed. See the KeyCombination
documentation for more info if required.
If you wished to adapt the code to use a custom list implementation:
Have your custom linked list structure implement the
List
interface.- You don't need to implement all of the interface, only the pieces you need to get your application working, the rest of the operations can just throw
UnsupportedOperationException
.
- You don't need to implement all of the interface, only the pieces you need to get your application working, the rest of the operations can just throw
Pass an instance of your custom list to FXCollections to wrap it in an observable list the UI can use:
FXCollections.observableList(yourDoubleLinkedList)
- Do this instead of places I use an ArrayList via
FXCollections.observableArrayList()
.
- Do this instead of places I use an ArrayList via
I won't provide any further assistance on adaption of the implementation to use a custom list, if you have difficulties with that, those difficulties are yours to solve.
import javafx.application.*;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.*;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.*;
import javafx.stage.*;
import java.io.*;
import java.nio.file.*;
import java.util.Map;
public class LineEditor extends Application {
private Document document;
@Override
public void init() throws Exception {
Path path = Path.of(getParameters().getRaw().get(0));
document = new Document(
path.getFileName().toString(),
FXCollections.observableArrayList(
Files.readAllLines(path)
)
);
}
@Override
public void start(Stage stage) throws IOException {
Editor editor = new Editor(document);
Scene scene = new Scene(editor.getUI());
stage.setScene(scene);
scene.getAccelerators().putAll(
Map.of(
KeyCombination.valueOf("SHORTCUT+I"),
editor::insert,
KeyCombination.valueOf("SHORTCUT+O"),
editor::overwrite,
KeyCombination.valueOf("SHORTCUT+D"),
editor::delete,
KeyCombination.valueOf("SHORTCUT+E"),
editor::edit,
KeyCombination.valueOf("SHORTCUT+C"),
editor::changeTitle,
KeyCombination.valueOf("SHORTCUT+S"),
() -> editor.save(scene.getWindow()),
KeyCombination.valueOf("SHORTCUT+Q"),
editor::quit
)
);
stage.titleProperty().bind(
Bindings.concat("Editing: ", document.titleProperty())
);
stage.show();
}
public static void main(String[] args) throws IOException {
if (args.length == 0) {
Path dirPath = Files.createTempDirectory(TEMP_DIR_PREFIX);
Path filePath = dirPath.resolve(DEFAULT_TITLE);
Files.writeString(filePath, DEFAULT_TEXT);
args = new String[]{filePath.toString()};
} else {
if (!Files.isReadable(Path.of(args[0]))) {
System.out.println("File " + args[0] + " is not readable.");
System.exit(1);
}
}
launch(args);
}
private static final String TEMP_DIR_PREFIX = "line-editor";
private static final String TEXT_EXTENSION = "txt";
private static final String DEFAULT_TITLE = "sonnet-148." + TEXT_EXTENSION;
private static final String DEFAULT_TEXT = """
O me, what eyes hath Love put in my head,
Which have no correspondence with true sight!
Or, if they have, where is my judgment fled,
That censures falsely what they see aright?
If that be fair whereon my false eyes dote,
What means the world to say it is not so?
If it be not, then love doth well denote
Love's eye is not so true as all men's 'No.'
How can it? O, how can Love's eye be true,
That is so vex'd with watching and with tears?
No marvel then, though I mistake my view;
The sun itself sees not till heaven clears.
O cunning Love! with tears thou keep'st me blind,
Lest eyes well-seeing thy foul faults should find.
""";
}
class Document {
private final SimpleStringProperty title;
private final ObservableList<String> lines;
public Document(String title, ObservableList<String> lines) {
this.title = new SimpleStringProperty(title);
this.lines = lines;
}
public SimpleStringProperty titleProperty() {
return title;
}
public ObservableList<String> getLines() {
return lines;
}
}
class Editor {
private final Pane layout;
private final ListView<String> display;
private final TextArea input;
private final Document document;
private final static String INSTRUCTION_TEXT = """
Shortcut
+ Key Command
I Insert
O Overwrite
D Delete
E Edit
C Change Title
S Save
Q Quit
""";
private final static String UNTITLED_DOCUMENT_TITLE = "Untitled.txt";
public Editor(Document document) {
this.document =
(document != null)
? document
: new Document(
UNTITLED_DOCUMENT_TITLE,
FXCollections.observableArrayList()
);
assert document != null;
display = new ListView<>(document.getLines());
display.setPrefSize(350, 300);
input = new TextArea();
Label instructions = new Label(INSTRUCTION_TEXT);
instructions.setStyle("-fx-font-family: monospace;");
HBox displayWithInstructions = new HBox(10,
instructions,
display
);
SplitPane splitPane = new SplitPane(
displayWithInstructions,
input
);
splitPane.setOrientation(Orientation.VERTICAL);
splitPane.setDividerPositions(.8);
layout = new StackPane(splitPane);
layout.setPadding(new Insets(10));
}
public Pane getUI() {
return layout;
}
public void insert() {
int selectedIndex = display.getSelectionModel().getSelectedIndex();
document.getLines().add(selectedIndex + 1, input.getText());
}
public void overwrite() {
int selectedIndex = display.getSelectionModel().getSelectedIndex();
if (selectedIndex != -1) {
document.getLines().set(selectedIndex, input.getText());
}
}
public void delete() {
int selectedIndex = display.getSelectionModel().getSelectedIndex();
if (selectedIndex != -1) {
document.getLines().remove(selectedIndex);
}
}
public void edit() {
int selectedIndex = display.getSelectionModel().getSelectedIndex();
if (selectedIndex != -1) {
input.setText(document.getLines().get(selectedIndex));
}
}
public void changeTitle() {
TextInputDialog titleDialog = new TextInputDialog(document.titleProperty().get());
titleDialog.setTitle("Set Title");
titleDialog.showAndWait()
.ifPresent(result -> document.titleProperty().set(result));
}
public void save(Window owner) {
FileChooser fileChooser = new FileChooser();
fileChooser.getExtensionFilters().setAll(
new FileChooser.ExtensionFilter("Text Files", "txt")
);
fileChooser.setTitle("Save Document");
fileChooser.setInitialFileName(document.titleProperty().get());
File saveFile = fileChooser.showSaveDialog(owner);
if (saveFile != null && Files.isWritable(saveFile.toPath())) {
document.titleProperty().set(saveFile.getName());
try {
Files.writeString(
saveFile.toPath(),
String.join("\n", document.getLines())
);
} catch (IOException e) {
e.printStackTrace();
Alert alert = new Alert(
Alert.AlertType.ERROR,
"Unable to save " + document.titleProperty().get()
);
alert.initOwner(owner);
alert.showAndWait();
}
}
}
public void quit() {
Platform.exit();
}
}
Answered By - jewelsea
Answer Checked By - Katrina (JavaFixing Volunteer)