B4J Question Simulate keypress+combos

ThRuST

Well-Known Member
Licensed User
Longtime User
Hi all, I found this native Java code how to simulate keypress which I want to convert to B4J, because I need a automatic keypress of CTRL+V keypress and I need a solution without the jAWTRobot library.

Any solution needs to support SDK v9.0.4


You can find the native Java code here
 

ThRuST

Well-Known Member
Licensed User
Longtime User
I tested to change to keyPressed and keyReleased. This is what happened

upload_2019-1-7_16-2-44.png
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Got it working with java 8 now


Oh alright I'll tell you how lol
B4X:
#Region Project Attributes
 #MainFormWidth: 600
 #MainFormHeight: 600
#End Region
Sub Process_Globals
 Private fx As JFX
 Private MainForm As Form
 Private TextArea1 As TextArea
 Private btnClearTextArea As Button
 Private btnAutoKeyPress As Button
 Private btnQuit As Button
 Dim keycodes As JavaObject
End Sub
Sub AppStart (Form1 As Form, Args() As String)
 MainForm = Form1
 MainForm.RootPane.LoadLayout("1") 'Load the layout file.
 MainForm.Show
 keycodes.InitializeStatic("javafx.scene.input.KeyCode")
End Sub
'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
 Return True
End Sub
Sub btnClearTextArea_Click
 
 TextArea1.Text = ""
 TextArea1.RequestFocus
 
End Sub
Sub btnAutoKeyPress_Click
 
 AutoKeyPressCTRLV
 
End Sub
Sub btnQuit_Click
 
 ExitApplication
 
End Sub
Sub AutoKeyPressCTRLV
 Dim robot1 As JavaObject
 Dim jo1 As JavaObject
 
 jo1 = jo1.InitializeStatic("com.sun.glass.ui.Application")
 'robot1 = jo1.RunMethodJO("GetApplication",Null).RunMethodJO("createRobot",Null)
 robot1 = asJO(Me).RunMethod("newRobot",Array(asJO(MainForm.rootpane).RunMethodJO("getScene",Null)))
 TextArea1.RequestFocus
 
 robot1.RunMethod("keyPress", Array(keycodes.GetField("CONTROL")))
 robot1.RunMethod("keyPress", Array(keycodes.GetField("V")))
 robot1.RunMethod("keyRelease", Array(keycodes.GetField("V")))
 robot1.RunMethod("keyRelease", Array(keycodes.GetField("CONTROL")))
End Sub
Sub asJO(o As JavaObject) As JavaObject
 Return o
End Sub
#if java
import com.sun.javafx.robot.*;
import javafx.scene.Scene;
public static Object newRobot(Scene s){
 FXRobot robot = FXRobotFactory.createRobot(s);
 return robot;
}
#End If

Going for a lay down now, my brain hurts.
 
Last edited:
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
Mine too :eek:

I pasted the code in the original test app and here's what she wrote

upload_2019-1-7_16-43-10.png
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
well they did say anything starting com.sun… would be off limits to java devs, so it looks like that has happened.

I have another idea to get it working but will take a while to write/debug.
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
ah well, you might look at it again another time. Just drop a post when you're on to something :)
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
try this - it uses all fx related stuff, no bad packages
It only does CTRL-V at present but should be easy to adapt.

B4X:
#Region Project Attributes
 #MainFormWidth: 600
 #MainFormHeight: 600
#End Region
Sub Process_Globals
 Private fx As JFX
 Private MainForm As Form
 Private ctrlV As JavaObject
 Dim ta As TextArea
 Dim b As Button
End Sub
Sub AppStart (Form1 As Form, Args() As String)
 MainForm = Form1
 'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
 MainForm.Show
 ta.Initialize("")
 b.Initialize("paste")
 b.Text = "Paste"
 MainForm.RootPane.AddNode(ta,10,10,300,300)
 MainForm.RootPane.AddNode(b,10,350,100,20)
 ctrlV = asJO(Me).RunMethod("keyPressedEvent",Null)
 Log(ctrlV)
 ta.RequestFocus
 
End Sub
Sub asJO(o As JavaObject) As JavaObject
 Return o
End Sub
Sub paste_Click
 ctrlV.RunMethod("fireEvent",Array(ta,ctrlV))
End Sub
'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
 Return True
End Sub
#if java
import javafx.scene.input.*;
import javafx.event.Event;
public static KeyEvent keyPressedEvent(){
return new KeyEvent(KeyEvent.KEY_PRESSED,null,"V",KeyCode.V,false,true,false,false);
}
#End If
 
Last edited:
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
Dud you deserve to get the Nobel price for making this work on both SDK 8 and 11. Not bad, not bad :)

upload_2019-1-7_17-40-18.png
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
This should be easy to modify to your needs.
 

Attachments

  • example1.zip
    2.2 KB · Views: 223
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
Wow, now this looks interesting :) Please add in also an option for Mac COMMAND+V so I can try it in the emulator.
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
btw how can I change post #29 to work with CONTROL+V key on Mac? I'm trying to figure it out but it doesn't make sense!! where's the CONTROL key call in the code!! I want to change it to COMMAND key.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
this line
return new KeyEvent(KeyEvent.KEY_PRESSED,null,"V",KeyCode.V,false,true,false,false);

breaks down as
KeyEvent(EventType<KeyEvent> eventType, String character, String text, KeyCode code, boolean shiftDown, boolean controlDown, boolean altDown, boolean metaDown)



this version hopefully will work on mac too, but I cant test it.
 

Attachments

  • example2.zip
    2.4 KB · Views: 225
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
Nice I will try it a bit later. Gotta wash my clothes since I haven't programmed a robot to do it for me (woman) :D
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
Just tried a modified version of your post #29 to make CTRL+V and COMMAND+V working on PC and Mac and I just tested it on Mac and it works perfectly in Mac OSX Sierra :) I should turn it into a library and credit us both. I learned some more about how to call native Java code from B4J, well done @Daestrum The Great :rolleyes:
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Final version (the last one had a minor bug - did anyone find it?)
This is version much simpler - no map for keys as they are defined in the calls now.

Basically you have
Control - types control characters.
Command - types Apple command characters.
Normal - types a single char.
WriteString - writes a string.
Alt - types alt + string combination. (this not tested on Unicode strings)
 

Attachments

  • example4.zip
    2.2 KB · Views: 233
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
I have not yet tested your example 4 yet, but I pass this question in between. The issue with my need for a pasting mechanism is that I will use it from a floating menu, which gets the data from an SQLite database. That's why I cannot specify TextArea as a target, since the pasting should be done at the cursor position on the screen.
I have modified your code and it works well on both PC and Mac, but only to paste into a control in this case TextArea. As seen is this example I tried to put "Null" instead of TextArea, but that crashes the program. What do you suggest as a workaround for this?

B4X:
#Region Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 600
#End Region

Sub Process_Globals
    
    Private fx As JFX
    Private MainForm As Form
    Private TextArea1 As TextArea
    Private Button1 As Button
    Private CTRL_V As JavaObject
    Private COMMAND_V As JavaObject
    
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("1") 'Load the layout file.
    MainForm.Show
    
    
End Sub

'Return true to allow the default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub Button1_Click
    
    TextArea1.RequestFocus
    
    CTRL_V = asJOKeyPressPaste(Me).RunMethod("keyPressedEventCTRL_V",Null)
    COMMAND_V = asJOKeyPressPaste(Me).RunMethod("keyPressedEventCOMMAND_V",Null)
    'Log(CTRL_V)
    
    AutoPaste_CTRL_V
    
End Sub

Sub asJOKeyPressPaste(o As JavaObject) As JavaObject
    Return o
End Sub
' PAY ATTENTION TO THIS LINE NULL WON'T WORK!!!
Sub AutoPaste_CTRL_V
    CTRL_V.RunMethod("fireEvent",Array(Null,CTRL_V))
End Sub

Sub AutoPaste_COMMAND_V
    COMMAND_V.RunMethod("fireEvent",Array(TextArea1,COMMAND_V))
End Sub

#if java
import javafx.scene.input.*;
import javafx.event.Event;

// CTRL_V (windows CTRL+V)
public static KeyEvent keyPressedEventCTRL_V()
{
    return new KeyEvent(KeyEvent.KEY_PRESSED,null,"V",KeyCode.V,false,true,false,false);
}

// COMMAND_V (Mac CMD+V)
public static KeyEvent keyPressedEventCOMMAND_V()
{
    return new KeyEvent(KeyEvent.KEY_PRESSED,null,"V",KeyCode.V,false,false,false,true);
}

// breaks down as
// KeyEvent(EventType<KeyEvent> eventType, String character, String text, KeyCode code, boolean shiftDown, boolean controlDown, boolean altDown, boolean metaDown)

#End If
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
What is the data being pasted into?
If it is not part of the application, then this method won't work. It cannot paste to other applications.
 
Upvote 0
Top