java createText without Ctrl C, Ctrl V - java

I have tried to create a text box with
protected FormToolkit toolkit = new FormToolkit(parent.getDisplay());
Text idInput = toolkit.createText(parent, " ", SWT.BORDER);
Then, there is just Ctrl+A, but no Ctrl+C, Ctrl+V and Ctrl+X function, how can I get these HotKey function?

You can use the system clipboard. This will allow you to copy and paste from the Java application to native applications too!
Create a new ActionListener that uses the Clipboard.
public class ClipboardActionListener implements ActionListener
{
private final JTextField;
public ClipboardActionListener(JTextField text)
{
this.text= text;
}
#Override
public void actionPerformed(ActionEvent e)
{
Clipboard system = Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection selection = new StringSelection(text.getText());
system.setContents(selection, selection)
}
}
And register the key strokes when you create the text field.
KeyStroke copy = KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK, false);
textField.registerKeyboardAction(new ClipboardActionListener(textField), copy, JComponent.WHEN_FOCUSED);

Related

How do you listen for mouse paste done in a TextField using JavaFX?

Copy text into your clipboard, right click text field and press "paste", is there a way how to listen when paste was clicked? Or rather that input text in the field changed after something was pasted this way. Because these do not work in this particular case:
setOnKeyReleased()
setOnInputMethodTextChanged()
The "paste" functionality is implemented in the TextInputControl superclass of TextField in public void paste(). So, while it's not really an event-driven or MVC approach, you can react to a "paste" action (whether it's invoked by mouse or keyboard shortcut, typically ctrl-V) by overriding this method:
TextField tf = new TextField() {
#Override
public void paste() {
super.paste();
System.out.println("text pasted in");
}
}
you could just listen to text property changes.
example with a search text field:
tf_search.textProperty().addListener((observableValue, oldValue, newValue) -> {
onSearch();
});
The other approach would be to override the appropriate method using Clipboard.
TextField tf = new TextField() {
#Override
public void paste() {
Clipboard clipboard = Clipboard.getSystemClipboard();
if (clipboard.hasString()) {
replaceSelection(clipboard.getString());
}
}
};

how to implement ctrl+backspace and ctrl+delete for a text edior in swt

I have created an SWT text editor and also have implemented the cut, copy and paste features but now I need to implement CTRL + BACKSPACE, to delete the preceding word, and CTRL + DEL, to delete the proceeding word.
The code which copied text
private class Copy implements SelectionListener{
public void widgetSelected(SelectionEvent event) {
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
copySelectedMessages();
}
private void copySelectedMessages(){
//StringBuffer stringCopied =new StringBuffer();
String textData = editor.getSelectionText();
//TextTransfer textTransfer = TextTransfer.getInstance();
System.out.println("you hv selected"+textData);
//Clipboard clipboard = new Clipboard(Display.getDefault());
TextTransfer transfer = TextTransfer.getInstance();
clipboard.setContents(new Object[] { textData }, new TextTransfer[] { transfer });
}
});
}
}
The code for the editor
editor = new StyledText( this, SWT.MULTI | SWT.V_SCROLL );
editor.setLayoutData( new GridData(GridData.FILL_BOTH) );
editor.setFont( new Font(Display.getDefault(),"Cambria", 10, SWT.NORMAL) );
The listener
proceeding.addSelectionListener(new proceed());
private class proceed implements SelectionListener{
public void widgetSelected(SelectionEvent event) {
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
// Code to check for CTRL + backspace and CTRL + delete
}
});
}
So now how can CTRL+BACKSPACE and CTRL+ DELETEfunctionality can be implemented in SWT.
addSelectionListener() is the wrong method to use here; use addKeyListener() and then a KeyAdapter to process the events.
java2s has an example: http://www.java2s.com/Code/JavaAPI/org.eclipse.swt.custom/StyledTextaddKeyListenerKeyListenerkey.htm
or here for a more complete one: http://www.java2s.com/Tutorial/Java/0280__SWT/Asimpleeditor.htm
Your code to implement "copy to clipboard" is not necessary since StyledText already implements this. Just call the copy() method. The second example shows how to install a global listener for Ctrl+C via a menu item.
As for how to delete the next or previous word, call st.invokeAction() with ST.DELETE_WORD_NEXT or ST.DELETE_WORD_PREVIOUS (org.eclipse.swt.custom.ST).
By default, those actions are bound to Ctrl+BackSpace and Ctrl+Delete. But again, those keys only trigger the action when the widget has the focus. If you want to enable them no matter which widget in the window has the focus, then create a menu item.

Implementing a JMenu with actionPerformed using TextAction

I have a Java Swing interface with multiple JTextArea's and I am implementing an "Edit" menu with various different functions like "Find", "Copy", "Paste", etc. When I click on the JMenuItem I need to know which JTextArea had the focus which is achievable through a TextAction (I haven't gone down the route of a FocusListener and keeping track of what last had the focus):
JMenuItem miFind = new JMenuItem(new EditHandler("Find"));
class EditHandler extends TextAction {
private String s = null;
public EditHandler(String vs) {
super(vs);
s = vs;
}
#Override
public void actionPerformed(ActionEvent e) {
JTextComponent c = getFocusedComponent();
if (s.equals("Find")) {
showFindDialog(c);
}
}
}
This works well and good but I want to be able to disable the "Find" JMenuItem under certain contexts (i.e. if the specific JTextArea is disabled or is empty. I can implement an ActionListener on a JMenu but I can't use getFocusedComponent() to identify what JTextArea has the focus.
According to the Java docs the JMenu constructor takes an Action (like a JMenuItem) and I have tried the following:
mEdit = new JMenu(new EditHandler("Edit"));
However, although the constructor fires, the actionPerformed() event isn't firing within my EditHandler for the JMenu. If I can get it to fire then I was planning to either enable or disable my "Find" JMenuItem.
The best way for you is using of actions map of the text component to place the corresponding action. In this case you can disable it for some text components.
#Override
public void actionPerformed(ActionEvent e) {
JTextComponent c = getFocusedComponent();
if (s.equals("Find")) {
Action a = c.getActionMap().get("Find");
if (a.isEnabled()) {
// generate new event to modify the source (menu item -> text component)
ActionEvent ae = new ActionEvent(c, e.getID(), e.getCommand());
a.actionPerformed(ae);
}
}
}
For each your text component you must provide an action and register it using the action map of the component.
public class UniversalFindAction extends AbstractAction {
public void actionPerformed(ActionEvent ae) {
JTextComponent c = (JTextComponent) ae.getSource();
showFindDialog(c);
}
}
// registering of action
JTextComponent comp = new JTextArea();
comp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK), "Find");
comp.getActionMap().put("Find", new UniversalFindAction());
Thanks to #sergiy-medvynskyy I have implemented a Global Focus Listener to keep track of the last JTextArea to be focused:
KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() {
#Override
public void propertyChange(final PropertyChangeEvent e) {
if (e.getNewValue() instanceof JTextArea) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
tFocused = (JTextArea)e.getNewValue();
}
});
}
}
});
I then check the tFocused object using a MenuListener on my JMenu to verify what JTextArea currently has the focus. I can then call setEnabled() on my respective JMenuItem's depending on the context.

SWT Drag to Explorer (Windows) or Finder (OS X)

I've got an SWT application with a bunch of graphical elements. I'd like for the user to be able to drag an element to their Desktop / Windows Explorer / OS X Finder. When they drop the element, I need the path that they dropped it to, so that I can create a file in that location which represents the element.
I don't think I can use a FileTransfer, because there is no source file. There is a source object which can create a file, but only once it knows where to put it.
Inlined below is a simple example of what I'm trying to achieve, there is a text box with a label to drag from. If the user drags to some folder or file, I'd like to get the path that they dragged to. If they dragged to a file, I'd like to replace the contents of that file with whatever is in the text box. If they dragged to a folder, I'd like to create a file called "TestFile" with the contents of whatever is in the text box.
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class DesktopDragExample {
public static void main(String[] args) {
// put together the SWT main loop
final Display display = Display.getDefault();
display.syncExec(new Runnable() {
#Override
public void run() {
Shell shell = new Shell(display, SWT.SHELL_TRIM);
initializeGui(shell);
//open the shell
shell.open();
//run the event loop
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
});
}
// create the gui
private static void initializeGui(Composite parent) {
GridLayout layout = new GridLayout(2, false);
parent.setLayout(layout);
// make the instructions label
Label infoLbl = new Label(parent, SWT.WRAP);
GridData gd = new GridData();
gd.grabExcessHorizontalSpace = true;
gd.horizontalAlignment = SWT.FILL;
gd.horizontalSpan = 2;
infoLbl.setLayoutData(gd);
infoLbl.setText(
"You should be able to drag to the desktop, Windows Explorer, or OS X Finder.\n" +
"If you drag to a file, it will replace the contents of that file with the contents of the text box.\n" +
"If you drag to a folder, it will create a file named 'TestFile' whose contents are whatever is in the text box.");
// make the text element
final Text text = new Text(parent, SWT.SINGLE | SWT.BORDER);
gd = new GridData();
gd.grabExcessHorizontalSpace = true;
gd.horizontalAlignment = SWT.FILL;
text.setLayoutData(gd);
// make the label element
Label label = new Label(parent, SWT.NONE);
label.setText("Drag me");
// listener for drags
DragSourceListener dragListener = new DragSourceListener() {
#Override
public void dragStart(DragSourceEvent e) {
e.detail = DND.DROP_COPY;
}
#Override
public void dragFinished(DragSourceEvent e) {
System.out.println("--dragFinished--");
System.out.println("e.data=" + e.data);
}
#Override
public void dragSetData(DragSourceEvent e) {
System.out.println("--dragSetData--");
System.out.println("e.data=" + e.data);
}
};
// the DragSource
DragSource dragSource = new DragSource(label, DND.DROP_COPY);
dragSource.setTransfer(new Transfer[]{FileTransfer.getInstance()});
dragSource.addDragListener(dragListener);
}
private static void draggedTo(String path, String textBoxContents) {
System.out.println("Dragged the contents '" + textBoxContents + "' to '" + path + "'");
}
}
Here are some other people with the same problem, but looks like no solution so far:
Drag from SWT to Desktop, ..want destination path as String
The only way to do it is by creating a temporary file and then using the FileTransfer. I suspect that's what you'd have to do in native code anyways. I'll see if I have enough time to sketch the sample...
You don't get the file location from and write the file yourself. Dragging to the Desktop implies a FileTransfer (you can check what type of transfer is supported in dragSetData).
This means that SWT expecting a String[] of file paths in DragSourceEvent.data. If you set this in the dragSetData method, then SWT copies those files to your drop target - e.g. the Desktop.
#Override
public void dragSetData(DragSourceEvent e) {
System.out.println("--dragSetData--");
System.out.println("Is supported: " + FileTransfer.getInstance().isSupportedType(e.dataType));
FileTransfer f = FileTransfer.getInstance();
String[] filePaths = {"C:\\CamelOut\\4.xml" } ;
e.data = filePaths;
}
};

Swing: how do I close a dialog when the ESC key is pressed?

GUI development with Swing.
I have a custom dialog for choosing a file to be opened in my application; its class extends javax.swing.JDialog and contains, among other components, a JFileChooser, which can be toggled to be shown or hidden.
The JFileChooser component already handles the ESC key by itself: when the file chooser is shown (embedded in my dialog) and I press ESC, the file chooser hides itself.
Now I would like my dialog to do the same: when I press ESC, I want the dialog to close. Mind you, when the embedded file chooser is shown, the ESC key should only hide it.
Any ideas ?
You can use the following snippet. This is better because the rootPane will get events from any component in the dialog. You can replace setVisible(false) with dispose() if you want.
public static void addEscapeListener(final JDialog dialog) {
ActionListener escListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.setVisible(false);
}
};
dialog.getRootPane().registerKeyboardAction(escListener,
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
JComponent.WHEN_IN_FOCUSED_WINDOW);
}
Use InputMap and ActionMap for dealing with key actions in Swing. To close the dialog cleanly, send a window closing event to it.
From my now defunct weblog:
private static final KeyStroke escapeStroke =
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
public static final String dispatchWindowClosingActionMapKey =
"com.spodding.tackline.dispatch:WINDOW_CLOSING";
public static void installEscapeCloseOperation(final JDialog dialog) {
Action dispatchClosing = new AbstractAction() {
public void actionPerformed(ActionEvent event) {
dialog.dispatchEvent(new WindowEvent(
dialog, WindowEvent.WINDOW_CLOSING
));
}
};
JRootPane root = dialog.getRootPane();
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
escapeStroke, dispatchWindowClosingActionMapKey
);
root.getActionMap().put( dispatchWindowClosingActionMapKey, dispatchClosing
);
}
If your looking for a technique using new features of Java 8 , try a lambda expression:
dialog.getRootPane().registerKeyboardAction(e -> {
window.dispose();
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
or
KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
int w = JComponent.WHEN_IN_FOCUSED_WINDOW;
dialog.getRootPane().registerKeyboardAction(e -> window.dispose(), k, w);
I had problems implementing both of the top answers. Here's a rather compact version using AbstractAction to auto-implement most of Action's methods, which works within text-based fields (per #pratikabu's request):
final AbstractAction escapeAction = new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent ae) {
dispose();
}
};
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "ESCAPE_KEY");
getRootPane().getActionMap().put("ESCAPE_KEY", escapeAction);
References
the above answers
http://www.coderanch.com/t/335357/GUI/java/KeyPressed-JDialog
Here's mine, I add CtrlW as closing shorcut aswell
Action closeAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
dispose();
}
};
KeyStroke esc = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(esc, "closex");
getRootPane().getActionMap().put("closex", closeAction);
KeyStroke ctrlW = KeyStroke.getKeyStroke("control W");
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ctrlW, "close");
getRootPane().getActionMap().put("close", closeAction);

Categories

Resources