祝大家有美好的一天!
我正在开发支持样式的文本编辑器。在应用程序中将有几个文本编辑器。我认为允许将样式文本从一个 JTextPane 拖动到另一个是个好主意。看起来 JTextPane 支持拖动带有自身样式的文本。您可以启动下面的代码来检查它。但是当我将样式文本拖到另一个 JTextPane 时,插入的文本是 PLAIN。:( 我查看了源代码,发现了一个有趣的类——TextTransferHandler。调试后很明显,这个 TextTransferHandler 处理拖放。正如我在它的代码中看到的,它支持通过将文本转换为 RTF 或 HTML 来拖动样式文本。我试过了这个:
_tp.setEditorKit(new RTFEditorKit());
但没有成功。
我错过了什么吗?
编码:
package apps.editor;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.ResourceBundle;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;
import javax.swing.text.rtf.RTFEditorKit;
class EditorUtil2 {
Action[] _actions;
HashMap<String, Action> _actionHashMap = new HashMap<String, Action>();
ResourceBundle _resourceBundle = BundleFactory.getBundle();
JTextPane _initTextPane;
Keymap _keymap;
JPopupMenu _popupMenu;
ArrayList<JTextPane> _editors = new ArrayList<JTextPane>();
public EditorUtil2() {
_initTextPane = new JTextPane();
hashDefaultActions();
makeActionsPretty();
makeKeymap();
createPopupMenu();
}
private String getProperty(String key) {
return _resourceBundle.getString(key);
}
private void hashDefaultActions() {
_actions = _initTextPane.getActions();
String name = null;
for (int i=0; i<_actions.length; i++) {
name = (String)_actions[i].getValue( Action.NAME );
_actionHashMap.put( name, _actions[i] );
}
}
private Action getHashedAction(String name) {
return (Action)_actionHashMap.get( name );
}
private void makeActionsPretty() {
Action a;
a = getHashedAction( DefaultEditorKit.cutAction );
a.putValue( Action.SMALL_ICON, loadImage( getProperty("Toolbar.Icons.cut") ) );
a.putValue( Action.NAME, getProperty("Toolbar.cut") );
a = getHashedAction( DefaultEditorKit.copyAction );
a.putValue( Action.SMALL_ICON, loadImage( getProperty("Toolbar.Icons.copy") ) );
a.putValue( Action.NAME, getProperty("Toolbar.copy") );
a = getHashedAction( DefaultEditorKit.pasteAction );
a.putValue( Action.SMALL_ICON, loadImage( getProperty("Toolbar.Icons.paste") ) );
a.putValue( Action.NAME, getProperty("Toolbar.paste") );
a = getHashedAction("font-bold");
a.putValue( Action.SMALL_ICON, loadImage( getProperty("Toolbar.Icons.bold") ) );
a.putValue( Action.NAME, getProperty("Toolbar.bold") );
a = getHashedAction("font-italic");
a.putValue( Action.SMALL_ICON, loadImage( getProperty("Toolbar.Icons.italic") ) );
a.putValue( Action.NAME, getProperty("Toolbar.italic") );
a = getHashedAction("font-underline");
a.putValue( Action.SMALL_ICON, loadImage( getProperty("Toolbar.Icons.underline") ) );
a.putValue( Action.NAME, getProperty("Toolbar.underline") );
}
private void makeKeymap() {
_keymap = JTextComponent.addKeymap( "NewKeymap", _initTextPane.getKeymap() );
//KeyStroke next = KeyStroke.getKeyStroke( KeyEvent.VK_RIGHT, InputEvent.CTRL_MASK, false);
//KeyStroke prev = KeyStroke.getKeyStroke( KeyEvent.VK_LEFT, InputEvent.CTRL_MASK, false);
//KeyStroke selectNext = KeyStroke.getKeyStroke( KeyEvent.VK_RIGHT, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK, false);
//KeyStroke selectPrev = KeyStroke.getKeyStroke( KeyEvent.VK_LEFT, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK, false);
KeyStroke cut = KeyStroke.getKeyStroke( KeyEvent.VK_X, InputEvent.CTRL_MASK, false);
KeyStroke copy = KeyStroke.getKeyStroke( KeyEvent.VK_C, InputEvent.CTRL_MASK, false);
KeyStroke paste = KeyStroke.getKeyStroke( KeyEvent.VK_V, InputEvent.CTRL_MASK, false);
KeyStroke bold = KeyStroke.getKeyStroke( KeyEvent.VK_B, InputEvent.CTRL_MASK, false);
KeyStroke italic = KeyStroke.getKeyStroke( KeyEvent.VK_I, InputEvent.CTRL_MASK, false);
KeyStroke underline = KeyStroke.getKeyStroke( KeyEvent.VK_U, InputEvent.CTRL_MASK, false);
//_keymap.addActionForKeyStroke( next, getHashedAction( DefaultEditorKit.nextWordAction ) );
//_keymap.addActionForKeyStroke( prev, getHashedAction( DefaultEditorKit.previousWordAction ) );
//_keymap.addActionForKeyStroke( selectNext, getHashedAction( DefaultEditorKit.selectionNextWordAction ) );
//_keymap.addActionForKeyStroke( selectPrev, getHashedAction( DefaultEditorKit.selectionPreviousWordAction ) );
_keymap.addActionForKeyStroke( cut, getHashedAction( DefaultEditorKit.cutAction) );
_keymap.addActionForKeyStroke( copy, getHashedAction( DefaultEditorKit.copyAction ) );
_keymap.addActionForKeyStroke( paste, getHashedAction( DefaultEditorKit.pasteAction ) );
_keymap.addActionForKeyStroke( bold, getHashedAction( "font-bold" ) );
_keymap.addActionForKeyStroke( italic, getHashedAction( "font-italic" ) );
_keymap.addActionForKeyStroke( underline, getHashedAction( "font-underline" ) );
}
private ImageIcon loadImage(String path) {
URL imageURL = this.getClass().getResource( path );
return new ImageIcon( imageURL );
}
private void createPopupMenu() {
_popupMenu = new JPopupMenu();
ArrayList<Action> actions = new ArrayList<Action>();
actions.add( getHashedAction( DefaultEditorKit.cutAction ) );
actions.add( getHashedAction( DefaultEditorKit.copyAction ) );
actions.add( getHashedAction( DefaultEditorKit.pasteAction ) );
JMenuItem mi = null;
for (Action a : actions) {
mi = new JMenuItem();
mi.setAction(a);
mi.setAccelerator(_keymap.getKeyStrokesForAction( a )[0] );
_popupMenu.add(mi);
}
_popupMenu.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
System.out.println("will be visible");
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
System.out.println("will be invisible");
System.out.println("stop freeze");
JTextPane tp = (JTextPane)_popupMenu.getInvoker();
tp.getCaret().setBlinkRate(500);
tp.getCaret().setVisible(false);
//_popupOpened = false;
tp.repaint();
//tp.requestFocus();
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
System.out.println("menu canceled");
}
} );
_popupMenu.addComponentListener( new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent e) {
System.out.println("menu shown");
}
@Override
public void componentHidden(ComponentEvent e) {
}
});
}
boolean _popupOpened = false;
public JTextPane createTextEditor() {
final JTextPane tp = new JTextPane();
_editors.add( tp );
tp.setKeymap(_keymap);
tp.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
if (_popupMenu.isShowing() && _popupMenu.getInvoker() == tp) {
JTextPane tp = (JTextPane)_popupMenu.getInvoker();
tp.getCaret().setBlinkRate(0);
tp.getCaret().setVisible(true);
tp.repaint();
}
}
@Override
public void focusGained(FocusEvent e) {
System.out.println("focus gained");
for ( JTextPane t : _editors )
if ( t != tp )
t.setCaretPosition( t.getCaretPosition() );
}
});
tp.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(final MouseEvent e) {
System.out.println("mouse pressed");
tp.requestFocus();
if ( tp.getSelectionStart() == tp.getSelectionEnd() )
tp.setCaretPosition( tp.viewToModel( e.getPoint() ) );
if ( e.isPopupTrigger() ) {
_popupMenu.show( e.getComponent(), e.getX(), e.getY() );
}
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("mouse released");
// tp.requestFocus();
// if ( e.isPopupTrigger() ) {
// _popupMenu.show( e.getComponent(), e.getX(), e.getY() );
// }
}
});
return tp;
}
public ArrayList<Action> getActionsForToolBar() {
ArrayList<Action> actions = new ArrayList<Action>();
actions.add( getHashedAction( DefaultEditorKit.cutAction ) );
actions.add( getHashedAction( DefaultEditorKit.copyAction ) );
actions.add( getHashedAction( DefaultEditorKit.pasteAction ) );
actions.add( getHashedAction("font-bold") );
actions.add( getHashedAction("font-italic") );
actions.add( getHashedAction("font-underline") );
return actions;
}
public ArrayList<JMenuItem> getMenuItems() {
ArrayList<JMenuItem> items = new ArrayList<JMenuItem>();
ArrayList<Action> actions = new ArrayList<Action>();
actions.add( getHashedAction( DefaultEditorKit.cutAction ) );
actions.add( getHashedAction( DefaultEditorKit.copyAction ) );
actions.add( getHashedAction( DefaultEditorKit.pasteAction ) );
JMenuItem mi = null;
for (Action a : actions) {
mi = new JMenuItem();
mi.setAction(a);
mi.setAccelerator(_keymap.getKeyStrokesForAction( a )[0] );
items.add(mi);
}
return items;
}
}
public class TextEditorFrame2 extends LFrame {
EditorUtil _editorUtil = new EditorUtil();
JTextPane _tp;
JTextPane _tp2;
HashMap<String, Action> actionHashMap = new HashMap<String, Action>();
public TextEditorFrame2() {
setTitle("Editor");
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
_tp = _editorUtil.createTextEditor();
_tp2 = _editorUtil.createTextEditor();
add( createToolBar(), BorderLayout.NORTH );
add( _tp, BorderLayout.CENTER );
add( _tp2, BorderLayout.SOUTH );
setJMenuBar( createMenuBar() );
_tp.setDragEnabled(true);
_tp2.setDragEnabled(true);
//_tp.setContentType("text/rtf");
_tp.setEditorKit(new RTFEditorKit());
_tp2.setEditorKit(new RTFEditorKit());
//_tp2.setContentType("text/rtf");
System.out.println(_tp.getEditorKit());
pack();
setVisible(true);
setLocation(200, 300);
}
private JToolBar createToolBar() {
JToolBar tb = new JToolBar();
ArrayList<Action> actions = _editorUtil.getActionsForToolBar();
for (Action a : actions)
tb.add( a );
JButton button = new JButton("dump");
tb.add(button);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
DefaultStyledDocument doc = (DefaultStyledDocument)_tp.getStyledDocument();
doc.dump(System.out);
}
});
return tb;
}
private JMenuBar createMenuBar() {
JMenuBar mb = new JMenuBar();
JMenu edit = new JMenu("Edit");
mb.add(edit);
ArrayList<JMenuItem> items = _editorUtil.getMenuItems();
for (JMenuItem i : items)
edit.add( i );
return mb;
}
public static void main(String[] args) {
new TextEditorFrame();
}
}