Hallo liebe Forengemeinde,
ich habe einen kleinen Texteditor mit Formatierung geschrieben.
Leider funktioniert die Formatierung nicht so wie es eigendlich gewünscht ist.
Wenn ich einen Text mit verschiedenen Formatierungen (Fett, Kursiv, Unterstrichen)
markiere und die Formatierung zum Beispiel auf Fett setze, so übernimmt der
Editor die Formatierung die das erste markierte Zeichen hat.
Beispiel:
Formatierter Text:
test test test test
Jetzt markiere ich den Text und setzte die Formatierung auf Fett, das Ergebniss
ist wie folgt:
test test test test
Kennt jemand das Problem und kann mir vieleicht helfen?
Die Hotkeys für die Formatierungen sind:
Strg + Shift + F --> Fett
Strg + Shift + K --> Kursiv
Strg + Shift + U --> Unterstrichen
Hier ist nochmal der ganze Code:
(Tut mir leid aber ich weis ja nicht wo der Fehler ist, daher poste ich mal alles)
ich habe einen kleinen Texteditor mit Formatierung geschrieben.
Leider funktioniert die Formatierung nicht so wie es eigendlich gewünscht ist.
Wenn ich einen Text mit verschiedenen Formatierungen (Fett, Kursiv, Unterstrichen)
markiere und die Formatierung zum Beispiel auf Fett setze, so übernimmt der
Editor die Formatierung die das erste markierte Zeichen hat.
Beispiel:
Formatierter Text:
test test test test
Jetzt markiere ich den Text und setzte die Formatierung auf Fett, das Ergebniss
ist wie folgt:
test test test test
Kennt jemand das Problem und kann mir vieleicht helfen?
Die Hotkeys für die Formatierungen sind:
Strg + Shift + F --> Fett
Strg + Shift + K --> Kursiv
Strg + Shift + U --> Unterstrichen
Hier ist nochmal der ganze Code:
(Tut mir leid aber ich weis ja nicht wo der Fehler ist, daher poste ich mal alles)
Code:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import javax.swing.undo.UndoManager;
import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable;
@SuppressWarnings("serial")
public class StyledEditorPane extends JTextPane
{
public JTextPane my;
public HTMLDocument doc;
public StyleSheet styleSheet;
public HTMLEditorKit kit;
public MutableAttributeSet attr;
public UndoManager ed_undomanager;
public Hashtable kit_actions;
public Hashtable ed_actions;
public Hashtable ed_hotkeys;
public StyledEditorPane()
{
my = this;
// Formatierungstyp:
setContentType("text/html");
// HTML-Dokument:
doc = (HTMLDocument) getDocument();
// Editor-Kit:
kit = (HTMLEditorKit) getEditorKit();
kit.install(this);
// MutableAttributSet:
attr = (MutableAttributeSet) getInputAttributes().copyAttributes();
// Aktionen:
kit_actions = new Hashtable();
addEditorKitActions();
ed_hotkeys = new Hashtable();
addEditorHotkeys();
// Editoraktionen:
ed_actions = new Hashtable();
addEditorKitCommands();
// Textaktionen:
addEditorTextActions();
// Undo-Manager:
ed_undomanager = new UndoManager();
doc.addUndoableEditListener(ed_undomanager);
updateEditor();
}
private void addEditorKitActions()
{
Action[] actions = kit.getActions();
Action a;
for (int i = 0; i < actions.length; i++)
{
a = actions[i];
kit_actions.put(actions[i].getValue(Action.NAME), a);
}
}
private void addEditorKitCommands()
{
ed_actions.put("action-undo", new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
if(ed_undomanager.canUndo())
ed_undomanager.undo();
}
});
ed_actions.put("action-redo", new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
if(ed_undomanager.canRedo())
ed_undomanager.redo();
}
});
ed_actions.put("action-bold", new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
int p = getCaretPosition();
int start = getSelectionStart();
int end = getSelectionEnd();
p = start > end ? end : start;
if (start == end)
p -= 1;
AttributeSet a = doc.getCharacterElement(p).getAttributes();
attr = (MutableAttributeSet) getInputAttributes().copyAttributes();
boolean bold = StyleConstants.isBold(a);
StyleConstants.setBold(attr, !bold);
setAttributeSet(attr);
grabFocus();
}
});
ed_actions.put("action-italic", new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
int p = getCaretPosition();
int start = getSelectionStart();
int end = getSelectionEnd();
p = start > end ? end : start;
if (start == end)
p -= 1;
AttributeSet a = doc.getCharacterElement(p).getAttributes();
attr = (MutableAttributeSet) getInputAttributes().copyAttributes();
boolean italic = StyleConstants.isItalic(a);
StyleConstants.setItalic(attr, !italic);
setAttributeSet(attr);
grabFocus();
}
});
ed_actions.put("action-underline", new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
int p = getCaretPosition();
int start = getSelectionStart();
int end = getSelectionEnd();
p = start > end ? end : start;
if (start == end)
p -= 1;
AttributeSet a = doc.getCharacterElement(p).getAttributes();
attr = (MutableAttributeSet) getInputAttributes().copyAttributes();
boolean underline = StyleConstants.isUnderline(a);
StyleConstants.setUnderline(attr, !underline);
setAttributeSet(attr);
grabFocus();
}
});
}
private void addEditorHotkeys()
{
ed_hotkeys.put("hotkey-delete",
KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_MASK));
ed_hotkeys.put("hotkey-deleteLastWord",
KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
ed_hotkeys.put("hotkey-redo",
KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_MASK));
ed_hotkeys.put("hotkey-undo",
KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_MASK));
ed_hotkeys.put("hotkey-bold",
KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
ed_hotkeys.put("hotkey-italic",
KeyStroke.getKeyStroke(KeyEvent.VK_K, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
ed_hotkeys.put("hotkey-underline",
KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
ed_hotkeys.put("hotkey-copy",
KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
ed_hotkeys.put("hotkey-paste",
KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK));
ed_hotkeys.put("hotkey-cut",
KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK));
ed_hotkeys.put("hotkey-enterLineBreak",
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0));
}
private void addEditorTextActions()
{
final JTextComponent.KeyBinding[] defaultBindings =
{
// Standard Textfunktionen:
new JTextComponent.KeyBinding(
(KeyStroke) ed_hotkeys.get("hotkey-copy"),
DefaultEditorKit.copyAction),
new JTextComponent.KeyBinding(
(KeyStroke) ed_hotkeys.get("hotkey-paste"),
DefaultEditorKit.pasteAction),
new JTextComponent.KeyBinding(
(KeyStroke) ed_hotkeys.get("hotkey-cut"),
DefaultEditorKit.cutAction),
// Spezielle Textfunktionen:
// **Löschen:
new JTextComponent.KeyBinding(
(KeyStroke) ed_hotkeys.get("hotkey-delete"),
DefaultEditorKit.deletePrevCharAction),
new JTextComponent.KeyBinding(
(KeyStroke) ed_hotkeys.get("hotkey-deleteLastWord"),
DefaultEditorKit.deletePrevWordAction),
// **Zeilenumbruch
new JTextComponent.KeyBinding(
(KeyStroke) ed_hotkeys.get("hotkey-enterLineBreak"),
DefaultEditorKit.insertBreakAction)
};
Keymap k = getKeymap();
loadKeymap(k, defaultBindings, getActions());
// Speziele Editorfunktionen:
k.addActionForKeyStroke(
(KeyStroke) ed_hotkeys.get("hotkey-undo"),
(AbstractAction) ed_actions.get("action-undo"));
k.addActionForKeyStroke(
(KeyStroke) ed_hotkeys.get("hotkey-redo"),
(AbstractAction) ed_actions.get("action-redo"));
k.addActionForKeyStroke(
(KeyStroke) ed_hotkeys.get("hotkey-bold"),
(AbstractAction) ed_actions.get("action-bold"));
k.addActionForKeyStroke(
(KeyStroke) ed_hotkeys.get("hotkey-italic"),
(AbstractAction) ed_actions.get("action-italic"));
k.addActionForKeyStroke(
(KeyStroke) ed_hotkeys.get("hotkey-underline"),
(AbstractAction) ed_actions.get("action-underline"));
}
private void setAttributeSet(AttributeSet attr)
{
int xStart = getSelectionStart();
int xFinish = getSelectionEnd();
if (xStart != xFinish)
{
doc.setCharacterAttributes(xStart, xFinish - xStart, attr, false);
}
else
{
doc.setCharacterAttributes(xStart, xStart + 1, attr, false);
MutableAttributeSet inputAttributes = kit.getInputAttributes();
inputAttributes.addAttributes(attr);
}
}
public void updateEditor()
{
kit = (HTMLEditorKit) getEditorKit();
doc = (HTMLDocument) getDocument();
styleSheet = kit.getStyleSheet();
styleSheet.addRule(
"body { font-family : Arial; font-size : 12pt }");
styleSheet.addRule(
"ul{ font-family : Arial; alignment : left }");
}
// Test: Starten des Editors:
public static void main(String[] args)
{
JFrame f = new JFrame("TextEditor - Test");
f.setSize(400, 300);
f.setLocation(
(java.awt.Toolkit.getDefaultToolkit().getScreenSize().width-f.getWidth())/2,
(java.awt.Toolkit.getDefaultToolkit().getScreenSize().height-f.getHeight())/2
);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Komponenten:
f.setLayout(new BorderLayout());
f.add(new JScrollPane(new StyledEditorPane()));
f.setVisible(true);
}
}