Привет, ребята, это моя первая свинговая программа, так что мне еще есть чему поучиться.Я делаю простой редактор слов, и у меня есть несколько проблем с выделением текста жирным шрифтом.Я хочу иметь возможность выделить что-то в редакторе с помощью курсора, и когда я закончу выделение, все, что было выделено, станет жирным.Или, если дважды щелкнуть слово, слово станет жирным.Мне удалось успешно реализовать то, что я только что объяснил, однако, у меня есть кнопка отмены.Когда я нажимаю «Отменить», в редакторе все будет выделено жирным шрифтом.Я использовал много возможностей редактора слов, чтобы код был коротким.Вы должны быть в состоянии скопировать и вставить в редактор, чтобы точно увидеть, что происходит, если вы тоже хотите.
import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
import java.io.*;
import java.util.Stack;
import java.awt.event.*;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
public class WordEditor extends JFrame implements KeyListener, ActionListener, Runnable {
private JFrame frame;
private StyledDocument styledDocument;
private JTextPane textPane;
protected static StyleContext editStyles = new StyleContext();
public WordEditor() throws BadLocationException {
this.styledDocument = new DefaultStyledDocument();
this.styledDocument.insertString(0, "", null);
addStylesToDocument(styledDocument);
}
public static void main(String args[]) throws IOException, BadLocationException {
SwingUtilities.invokeLater(new WordEditor());
}
@Override
public void run() {
JFrame frame = new JFrame("JTextPane Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
textPane = new JTextPane(styledDocument);
//textPane.setFont(new Font("Times New Roman", Font.ITALIC, 13));
textPane.addCaretListener(new SelectedText());
textPane.setPreferredSize(new Dimension(500, 500));
//textPane.setBackground(Color.LIGHT_GRAY);
textPane.addKeyListener(this);
JScrollPane scrollPane = new JScrollPane(textPane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JMenuBar menuBar = new JMenuBar();
JMenu doStuffMenu = new JMenu("Actions");
JMenuItem undoItem = new JMenuItem("Undo");
JMenuItem redoItem = new JMenuItem("Redo");
undoItem.addActionListener(this);
redoItem.addActionListener(this);
doStuffMenu.add(undoItem);
doStuffMenu.add(redoItem);
menuBar.add(doStuffMenu);
frame.setJMenuBar(menuBar);
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
private void addStylesToDocument(StyledDocument styledDocument) {
Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
Style s = styledDocument.addStyle("bold", def);
StyleConstants.setBold(s, true);
}
int point; // saves the last location of caret for undo/redo
private class SelectedText implements CaretListener {
public void caretUpdate(CaretEvent event) {
point = event.getDot();
int dot = event.getDot();
int mark = event.getMark();
System.out.println("dot: " + dot);
System.out.println("mark: " + mark);
if (dot != mark) {
if (dot < mark) {
int temp = dot;
dot = mark;
mark = temp;
}
System.out.println("MAKING BOLD!"); // does not print when undo is pressed
boldSelectedText(mark, dot);
} else { // if it doesn't bold make it times new Roman... doesnt work.
textPane.setFont(new Font("Times New Roman", Font.PLAIN, 13));
}
}
}
private void boldSelectedText(int mark, int dot) {
try {
int length = dot - mark;
String s = styledDocument.getText(mark, length);
styledDocument.remove(mark, length);
styledDocument.insertString(mark, s, styledDocument.getStyle("bold"));
} catch (BadLocationException e) {
e.printStackTrace();
}
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
Stack<String> listUndo = new Stack<String>();
Stack<String> listRedo = new Stack<String>();
char redoEndHold = ' ';
int numKeysTyped = 0;
String text = "";
public void keyTyped(KeyEvent e) {
text = textPane.getText();
redoEndHold = e.getKeyChar();
listUndo.push(text);
numKeysTyped++;
}
int undoCounter = 0;
int redoPopManager = 0;
boolean redoPushManager = false;
boolean undoHasBeenPressed = false;
public void undo() {
if (listUndo.size() > 0) {
if (undoCounter < 10) {
String hold = listUndo.pop();
if (undoCounter == 0) {
System.out.println("pushing extra character");
if(point - 1 == text.length()) {
if (redoPushManager == false) {
listRedo.push(hold + redoEndHold);
} else {
listRedo.push(hold);
}
} else {
String part1 = text.substring(0, point - 1);
String part2 = text.substring(point - 1);
listRedo.push(part1 + redoEndHold + part2);
}
}
listRedo.push(hold);
undoCounter++;
textPane.setText(hold);
undoHasBeenPressed = true;
} else {
JOptionPane.showMessageDialog(frame, "ERROR: max undo length of 10 reached");
}
} else {
JOptionPane.showMessageDialog(frame, "ERROR: Undo List is empty");
}
}
public void redo() {
if (listRedo.size() > 0) {
if (undoCounter >= 0) {
String hold = listRedo.pop();
if (redoPopManager == 0) {
hold = listRedo.pop();
System.out.println("worked");
}
textPane.setText(hold);
redoPopManager++;
undoCounter--;
if (undoCounter == 0) {
JOptionPane.showMessageDialog(frame, "just letting you know No more undos to redo! hit enter to continue");
redoPopManager = 0;
redoPushManager = true;
}
} else {
JOptionPane.showMessageDialog(frame, "ERROR: No more undos to redo!");
}
} else {
JOptionPane.showMessageDialog(frame, "ERROR: Redo list is empty!");
}
}
public void actionPerformed(ActionEvent e) {
String action = e.getActionCommand();
System.out.println(e.getActionCommand());
if (action.equals("Undo")) {
undo();
} else if (action.equals("Redo")) {
redo();
}
}
}
Я хочу, чтобы кнопка отмены просто отменяла самый последний набранный символ.Что и происходит, но все становится жирным, если я выделю один символ жирным шрифтом.Мой ожидаемый результат - например, я набираю «привет».Я выделяю el и o, чтобы он получился жирным.Я нажимаю «Отменить», и он избавляется от жирного шрифта.То, что у меня осталось, теперь не жирный, жирный, жирный, не жирный.Пожалуйста, дайте мне знать, если мне нужно быть более точным в том, что я спрашиваю.