JApplet/JPanel not receiving KeyListener events! - firefox

I cannot get my JPanel within my JApplet to receive keyboard events. I CANNOT FATHOM why!
Note that...
Clicking the panel (with mouse) before typing makes no difference. This is by far the most common advice I see given on the Net.
I have tried using the 'low-level' java.awt.KeyEventDispatcher interface. That makes no different either!
However, if I use Applet instead of JApplet, then the Applet DOES receive keyboard events. But even here, the moment I add a Panel to this Applet (the Panel is really where all my app/painting logic is), I once again stop receiving kb events (in my Panel)!
Now, I cannot simply use Applet (instead of JApplet) because, among other things, its onPaint gets a Graphics (instead of a Graphics2D object). So, #3 is NOT a solution for me.
Things work like a charm in AppletViewer that comes with JDK.
I desperately need someone's help here. Spent last 2-3 days trying all kinds of permutations I don't even recall now.
My platform details:
Firefox 3.5.3
Fedora 11 on x86 (with latest updates/patches)
Java Plugin: tried both of these, made no difference.
3.1 IcedTea Java Web Browser Plugin 1.6 (fedora-29.b16.fc11-i386)
3.2 jdk1.6.0_16/jre/plugin/i386/ns7/libjavaplugin_oji.so
Used the above jdk1.6.0_16 to compile my applet source.
Here's my code. Will greatly appreciate to hear from my fellow programmers... as I'm completely stuck!
Thanks,
/SD
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
class MyAppletKeyListener implements KeyListener, MouseListener {
public void keyPressed(KeyEvent e) {
System.out.println("panel:keyPressed" + e.getKeyChar());
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
System.out.println("panel:keyTyped" + e.getKeyChar());
}
public void mouseClicked(MouseEvent e) {
System.out.println("panel:mouseClicked");
}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
}
public class TestApplet extends JApplet implements MouseListener {
public void init() {
System.out.println("applet:init");
MyAppletKeyListener listener = new MyAppletKeyListener();
// Panel related
// Note: I'd like this red panel to handle
// all my keyboard and mouse events.
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(new JButton("test"));
panel.add(new JButton("test2"));
panel.setFocusable(true);
panel.requestFocus();
panel.setBackground(new Color(200, 0, 0));
panel.addKeyListener(listener);
panel.addMouseListener(listener);
// applet related
// Note: Added this only for debugging. I do NOT want
// to handle my mouse/kb events in the applet.
addMouseListener(this);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(panel);
}
public void mouseClicked(MouseEvent e) {
System.out.println("applet:mouseClicked");
}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
}
The HTML:
<html>
<head>
</head>
<body>
<applet id="myApplet" code="TestApplet.class"
width="425"
height="150" >
</applet>
</body>
</html>

I found this on the net, and it solves the issue for me:
As for the fact that KeyListener does
not work for JApplet as it does for
Applet you should use the
KeyEventDispatcher interface.
public class AppletMain extends JApplet implements
java.awt.KeyEventDispatcher
Furthermore you have to set the
KeyboardFocusManager to the Panel
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);
Afterwards override the
dispatchKeyEvent function of the
interface:
#Override
public boolean dispatchKeyEvent(KeyEvent e);
This allows you to catch the KeyEvents
as it is done with KeyListener.

I investigated the problem connected to my current project and explored some problems with focusability of JApplet class.
It is because why setFocusable(true);decided the problem.
You also may eventually need to add focus-capture call such as requestFocusInWindow(); to make it work propertly.

I had this problem with the sun-java-6 packages and the openjdk packages in both Ubuntu 9.04 and 10.10 with firefox version 3.6.11 and 3.6.14. I've discovered two workarounds: use Applet rather than JApplet, or implement a MouseListener which calls "requestFocus()" in the mousePressed(..) function.

Related

How to work with IActivityLifecycleCallbacks with MVVMCross?

I am new to MVVMCross. I need to get details about whether my android application is running in background or not. To achieve this i have try to implement with IActivityLifecycleCallbacks with MVXApplication.But i get following error "implements Android.Runtime.IJavaObject but does not inherit Java.Lang.Object or Java.Lang.Throwable. This is not supported.". So could anyone suggest me to how to achieve my requirement with MVVM cross.
You can implement that interface in your main application of your Android project and on the OnTrimMemory comparing the level with TrimMemory.UiHidden you can know if the app is in background or not.
public class MainApplication : Application, Application.IActivityLifecycleCallbacks
{
...
public static bool IsApplicationInForeground { get; private set; }
public override void OnCreate()
{
base.OnCreate();
this.RegisterActivityLifecycleCallbacks(this);
}
public override void OnTerminate()
{
base.OnTerminate();
this.UnregisterActivityLifecycleCallbacks(this);
}
public virtual void OnActivityResumed(Activity activity)
{
IsApplicationInForeground = true;
}
public override void OnTrimMemory(TrimMemory level)
{
IsApplicationInForeground &= level != TrimMemory.UiHidden;
base.OnTrimMemory(level);
}
...
}
IDK if it covers all of the cases but I use it in my projects and it works like a charm in the scenarios I've tested
HIH

SWT Dialog does not display correctly

When opening a new dialog, while its loading, you click couple of times on parent shell, apparently the new dialog does not display correctly.
Please see the example below:
Examples
https://i.stack.imgur.com/ZovxE.png (eclipse IDE example)
https://i.stack.imgur.com/5zVar.png
https://i.stack.imgur.com/u86b9.png
https://i.stack.imgur.com/FGaAr.png
Initially I encountered the problem in december 2014, and back then also reported by vaious in house devlopers which were using different development systems and then same problem has been reported by our several customers.
This behavior can be reproduced using following environment:
Windows Version: 7 Pro 64 Bit - 6.1.7601
Java Version: RE 1.8.0_121_b13
SWT Versions
3.8.2
4.6.2
4.7M6
I20170319-2000
I could only reproduce the problem on Windows 7 with the windows basic theme/design/style (not with classic or aero).
On windows 10 its not reproducible.
reproduce
code to reproduce
package test;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class Main {
public static void main(String[] args) {
Display display = new Display();
final Shell shell = createShell(display);
createButton(shell);
shell.open();
eventLoop(display, shell);
display.dispose();
}
private static Shell createShell(Display display) {
final Shell shell = new Shell(display);
shell.setLayout(new RowLayout());
shell.setSize(500, 200);
return shell;
}
private static void createButton(final Shell shell) {
final Button openDialog = new Button(shell, SWT.PUSH);
openDialog.setText("Click here to open Dialog ...");
openDialog.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
TestDialog inputDialog = new TestDialog(shell);
inputDialog.open();
}
});
}
private static void eventLoop(Display display, final Shell shell) {
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}
class TestDialog extends Dialog {
public TestDialog(Shell parent) {
super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.MIN | SWT.MAX | SWT.RESIZE);
setText("Dialog");
}
public void open() {
Shell shell = new Shell(getParent(), getStyle());
shell.setText(getText());
createContents(shell);
shell.pack();
initializeBounds(shell);
shell.open();
eventLoop(shell);
}
private void createContents(final Shell shell) {
shell.setLayout(new GridLayout(2, true));
Label label = new Label(shell, SWT.NONE);
label.setText("Some Label text ...");
final Text text = new Text(shell, SWT.BORDER);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
text.setLayoutData(data);
createCloseButton(shell);
/* time for the user to create the misbehavior */
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void createCloseButton(final Shell shell) {
Button closeButton = new Button(shell, SWT.PUSH);
closeButton.setText("Close");
GridData data = new GridData(GridData.FILL_HORIZONTAL);
closeButton.setLayoutData(data);
closeButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
shell.close();
}
});
shell.setDefaultButton(closeButton);
}
private void initializeBounds(Shell shell) {
Rectangle bounds = shell.getBounds();
Rectangle parentBounds = getParent().getBounds();
bounds.x = parentBounds.x;
bounds.y = parentBounds.y;
shell.setBounds(bounds);
}
private void eventLoop(Shell shell) {
Display display = getParent().getDisplay();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}
steps to reproduce
Start the application
it should look like: https://i.stack.imgur.com/dMJ9e.png
Click on the button.
Keep continuously clicking on right bottom corner of the parent shell (avoid hitting the new opening dialog), till mouse cursor changes to wait icon and parent shell changes its color.
it should look as following: https://i.stack.imgur.com/c1Ikp.png
Wait until the new dialog appears.
it looks likes as following: https://i.stack.imgur.com/kTDgQ.png (incorrectly displayed)
instead: https://i.stack.imgur.com/cHVjn.png (correctly displayed)
steps to reproduce done in video
https://youtu.be/7ukhloCPf0k
When you mouse hover some of the UI elements (the originally not correctly drawn), you can notice some of them to be get painted (e.g. table rows).
https://i.stack.imgur.com/kkMKn.png (before opening the dialog)
https://i.stack.imgur.com/ZXIKc.png (after opening the dialog)
https://i.stack.imgur.com/25M7S.jpg (after mouse over)
Even calling Shell.update() or Shell.redraw() after the Dialog opened does not fix it.
In Windows Performance Options -> Visual Effects -> disable "Use visual styles on windows and buttons" is the only option I found which provides a workaround,
which seems to be the same as changing the design/theme/style to classic.
https://www.sevenforums.com/tutorials/1908-visual-effects-settings-change.html (How to Change Windows Visual Effects)
In the end, I have following questions:
Is it a SWT or Windows problem?
Is there any related topic in bug entries for Windows or in Eclipse Bugzilla?
Is there someone else who experienced the same problem? please share the experience.
Is there any settings in SWT or Windows which could affect its look n feel and fix the problem?
In the end, I have following questions: Is it a SWT or Windows problem?
Neither. As others have mentioned, you certainly should not tie up the UI thread with any long-running task. That work belongs in a background thread.
In regards to using a background thread, there are several ways you could go about this depending on how you want your Dialog to behave.
One option would be to kick off the background thread and then open the dialog when the task is done. I personally don't care for this because while the task is running, a user may think that nothing is happening.
Another option would be to open the dialog but display a "Loading" message, or something to that effect to give meaningful feedback and let a user know that the application isn't frozen (like how it looks/responds in your example).
The strategy would be to:
Create the dialog
Start the long task on a background thread and register a callback
Open the dialog with a "Loading" message
When the task is complete, the dialog will be updated from the callback
If you search around a bit on using Executors, you should find some far better examples and detail on how to use them.
Here's a brief example to illustrate what that might look like:
(Note: There are definitely a few issues with this code, but for the sake of brevity and illustrating the point I opted for a slightly naive solution. Also there are Java 8-esque ways that would be a bit shorter, but again, this illustrates the idea behind using a background thread; the same concepts apply)
Given a Callable (or Runnable if you don't need a return value),
public class LongTask implements Callable<String> {
#Override
public String call() throws Exception {
Thread.sleep(15000);
return "Hello, World!";
}
}
You can use the Executors class to create a thread pool, and then an ExecutorService to submit the Callable for execution. Then, using Futures.addCallback(), you can register a callback which will execute one of two methods depending on whether the task was successful or failed.
final ExecutorService threadPool = Executors.newFixedThreadPool(1);
final ListeningExecutorService executorService = MoreExecutors.listeningDecorator(threadPool);
final ListenableFuture<String> future = executorService.submit(new LongTask());
Futures.addCallback(future, new FutureCallback(){...});
In this case I used the Google Guava implementation ListeningExecutorService which makes things a bit cleaner and simpler, in my opinion. But again, you may not even need this if you opt for a more "Java 8" approach.
As for the callback, when the task is successful, we update the Dialog with the results. If it fails, we can update it with something to indicate failure:
public static class DialogCallback implements FutureCallback<String> {
private final MyDialog dialog;
public DialogCallback(final MyDialog dialog) {
this.dialog = dialog;
}
#Override
public void onSuccess(final String result) {
dialog.getShell().getDisplay().asyncExec(new Runnable() {
#SuppressWarnings("synthetic-access")
#Override
public void run() {
dialog.setStatus(result);
}
});
}
#Override
public void onFailure(final Throwable t) {
dialog.getShell().getDisplay().asyncExec(new Runnable() {
#SuppressWarnings("synthetic-access")
#Override
public void run() {
dialog.setStatus("Failure");
}
});
}
}
In this case I opted for the Callable to return a String, thus the FutureCallback should be parameterized with String. You may want to use some other class that you created, which will work just as well.
Notice that we use the Display.asyncExec() method to ensure that the code which updates the UI runs on the UI thread, because the callback may execute on the background thread.
Like I said, there are still a few issues here, including what happens when you click the cancel button before the task completes, etc. But hopefully this helps illustrate an approach for handling long-running background tasks without blocking the UI thread.
Full example code:
public class DialogTaskExample {
private final Display display;
private final Shell shell;
private final ListeningExecutorService executorService;
public DialogTaskExample() {
display = new Display();
shell = new Shell(display);
shell.setLayout(new GridLayout());
executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(1));
final Button button = new Button(shell, SWT.PUSH);
button.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
button.setText("Start");
button.addSelectionListener(new SelectionAdapter() {
#SuppressWarnings("synthetic-access")
#Override
public void widgetSelected(final SelectionEvent e) {
final MyDialog dialog = new MyDialog(shell);
dialog.setBlockOnOpen(false);
dialog.open();
dialog.setStatus("Doing stuff...");
final ListenableFuture<String> future = executorService.submit(new LongTask());
Futures.addCallback(future, new DialogCallback(dialog));
}
});
}
public void run() {
shell.setSize(200, 200);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
executorService.shutdown();
display.dispose();
}
public static void main(final String... args) {
new DialogTaskExample().run();
}
public static class DialogCallback implements FutureCallback<String> {
private final MyDialog dialog;
public DialogCallback(final MyDialog dialog) {
this.dialog = dialog;
}
#Override
public void onSuccess(final String result) {
dialog.getShell().getDisplay().asyncExec(new Runnable() {
#SuppressWarnings("synthetic-access")
#Override
public void run() {
dialog.setStatus(result);
}
});
}
#Override
public void onFailure(final Throwable t) {
dialog.getShell().getDisplay().asyncExec(new Runnable() {
#SuppressWarnings("synthetic-access")
#Override
public void run() {
dialog.setStatus("Failure");
}
});
}
}
public static class LongTask implements Callable<String> {
/**
* {#inheritDoc}
*/
#Override
public String call() throws Exception {
Thread.sleep(15000);
return "Hello, World!";
}
}
public static class MyDialog extends Dialog {
private Composite baseComposite;
private Label label;
/**
* #param parentShell
*/
protected MyDialog(final Shell parentShell) {
super(parentShell);
}
/**
* {#inheritDoc}
*/
#Override
protected Control createDialogArea(final Composite parent) {
baseComposite = (Composite) super.createDialogArea(parent);
label = new Label(baseComposite, SWT.NONE);
return baseComposite;
}
public void setStatus(final String text) {
label.setText(text);
baseComposite.layout();
}
}
}
The code seems to be straight forward, only that you are making the main Thread sleep for 15secs hence the delay. If not required remove the sleep or reduce the time for sleep to 5secs or so.

silent execution bug with processing standalone program

I have been trying to use processing (3.0.2) as a lib to display video. You can see the beginning of my main class below. I am using Maven to build a fat .jar that I run on the command line. The program runs, does not freeze, and can be closed, but no video... (screenshot below) The problem is that happens totally silently: no warning, no crash.
I am totally sure that the video file is found by the program, since removing it triggers a RuntimeException.
Edit: Ok, so the file is found, but not the frames. The program is stuck trying to find a nonzero frame.
Edit 2: It seems it is in fact a GStreamer problem. Apparently, Processing does not support the GStreamer 1.x lineage. Installing GStreamer 0.1x as explained here and here, unfortunately did not work for me.
Edit 3: Trying with a basic example (code below), I see that the Movie.read() method is never triggered, although the draw() method is. Since there still are no errors or warnings, I guess it's a library problem. Interestingly, this very same code works perfectly when executed as a .pde from the Processing IDE, so there must be a library there that I am lacking. Any ideas??
My dependencies:
core.jar
video.jar
jna.jar
gstreamer-java.jar
System: Ubuntu 14.04 LTS, Java HotSpot(TM) 64-Bit Server VM (java version "1.8.0_77"), Processing 3.0.2 with video library installed through the processing IDE.
import processing.core.PApplet;
import processing.video.*;
public class TestMovie extends PApplet{
Movie myMovie;
public static void main(String[] args){
PApplet.main(TestMovie.class.getName());
}
public void settings(){
size(720, 480, FX2D);
}
public void setup() {
//background(0);
try{
myMovie = new Movie(this, "red_45deg_284sec_500ml.mpg");
}catch(Exception e){
System.out.println(e.getMessage());
}
myMovie.loop();
}
public void draw() {
image(myMovie.get(), 0, 0);
System.out.println("I'm drawing!");
}
// Called every time a new frame is available to read
void movieEvent(Movie m) {
try{
m.read();
}catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println("new frame!");
}
}
So, I finally got the movie playing, and it does not seem to be a library problem after all... For some mysterious reason, movieEvent() does not execute, most likely because no event is triggered. Using Movie.available() solved it as follows:
public class TestMovie extends PApplet{
Movie myMovie;
public static void main(String[] args){
PApplet.main(TestMovie.class.getName());
}
public void settings(){
size(720, 480, FX2D);
}
public void setup() {
//background(0);
try{
myMovie = new Movie(this, "red_45deg_284sec_500ml.mpg");
}catch(Exception e){
System.out.println(e.getMessage());
}
myMovie.loop();
}
public void draw() {
if (myMovie.available()) {
myMovie.read();
}
image(myMovie, 0, 0);
}
}

Using Events From A Class

I am trying to get a function to be called everytime an event occurs. In the KinectRegion class there is an event called HandPointerGrip: http://msdn.microsoft.com/en-us/library/microsoft.kinect.toolkit.controls.kinectregion.handpointergrip.aspx.
I see that it has declared the event and it seems to me that the event has already been set to be invoked(HandPointerEventArgs)? How do I attach a function to this event?
public Menu()
{
KinectRegion.HandPointerGripEvent+=Hand_Gripped; // why doesn't this work? :(
}
private void Hand_Gripped(object sender, HandPointerEvnetArgs e)
{
MessageBox.Show("I work!"); // I wish this would work
}
Been working hard on this problem and here is something I think will work. Afraid to test it. Learning a lot about routed events, delegates, and events.
namespace ...
{
public delegate void HandPointerEventHandler(object sender, HandPointerEventArgs e);
public partial class thePage : Page
{
public event HandPointerEventHandler HandGripped
{
add {this.AddHandler(KinectRegion.HandPointerGripEvent,value);}
remove {this.RemoveHandler(KinectRegion.HandPointerGripEvent,vlaue);}
}
public thePage()
{
InitializeComponent();
this.HandGripped += new HandPointerEventHandler(OnHandGripped);
}
protected virtual void OnHandGripped(object sender, HandPointerEventArgs e)
{
MessageBox.Show("hello"); //hopefully
}
}
}
The first block of code should work fine. My guess is that the HandPointerGripEvent is hooked up ok, it just never fires.
How are you setting up your KinectRegion?
Are you updating the interration library each frame?
Perhaps this helps?
Kinect SDK 1.7: Mapping Joint/Cursor Coordinates to screen Resolution
KinectRegion.AddHandPointerGripHandler(this.Button1, this.Button1_Click);
Here Button1 is:
< k:KinectTileButton x:Name="Button1" Height="150" Width="150" Content="Click"/ >
The namespaces:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:k="http://schemas.microsoft.com/kinect/2013"
Button1_Click is the method itself, for example:
private void Button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("YOU GOT ME !!!");
}
If you want to add a grip handler for another interface object, you just do:
KinectRegion.AddHandPointerGripHandler(< object name >, < method name >);
And s.o.

Monitor clipboard in Mac OS

I need to monitor clipboard events in my mac os app. I found a sample for a clipboard viewer and another question in stackoverflow asking for the same thing, but none of them has a solution on how to monitor the clipboard events.
That is, immediately after the user hits command + c, I get an event notifying. I know that the functionality exists, as there is an app that uses this functionality
Ideas?
I have written a clipboard listener [it will print every new text based information that entered the clipboard] in native Java see the following code:
import java.awt.Toolkit;
import java.awt.datatransfer.*;
import java.io.IOException;
public class ClipboardListener extends Thread implements ClipboardOwner {
Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
public void run(){
Transferable selection = systemClipboard.getContents(this);
gainOwnership(selection);
while (true) {}
}
public void gainOwnership(Transferable t){
try {this.sleep(100);}
catch (InterruptedException e) {}
systemClipboard.setContents(t, this);
}
public void lostOwnership(Clipboard clipboard, Transferable contents) {
try {System.out.println((String) clipboard.getData(DataFlavor.stringFlavor));}
catch (UnsupportedFlavorException e) {}
catch (IOException e) {}
gainOwnership(contents);
}
}
public class myApp {
public static void main(String[] args){
ClipboardListener listener = new ClipboardListener();
listener.start();}
}
It works, but the application will need focus to get the event from the clipboard. [I'm not Mac OS X developer so I don't how to fix this, actually I have posted a question about it...]
Have you looked at this. You could watch for command + c (and x) and manually get the clipboard.

Resources