Failed to add keyboard listeners to DefaultView
ema-pe opened this issue · 4 comments
Graphstream version: 1.3 (using maven
)
Problem: I'm not sure if it is a bug, or it is simply a my problem or a misunderstood. The problem is the DefaultView
don't add correctly the keyboard listener to the frame, but only the default listener.
In the source code, there is a method provided to set the keyboard manager, but it is not added into the frame, instead only the default manager.
I know that there is more focus on the 2.x branch, but I think it is not difficult to fix this problem. I repeat the I'm not sure if this problem is really a bug, it may be a my failure using Swing and GraphStream.
How to reproduce: try to run the following code. If you type any keyboard's key no text is printed on the standard output.
package app;
import java.awt.event.KeyEvent;
import org.graphstream.graph.implementations.SingleGraph;
import org.graphstream.ui.view.View;
import org.graphstream.ui.view.util.ShortcutManager;
import org.graphstream.ui.graphicGraph.GraphicGraph;
public class App {
public static void main(String args[]) {
var graph = new SingleGraph("test", false, true);
graph.addEdge("AB", "A", "B");
graph.addEdge("CD", "C", "D");
graph.addEdge("BD", "B", "D");
var viewer = graph.display();
viewer.getDefaultView().setShortcutManager(new ShortcutManager() {
private View view;
@Override
public void init(GraphicGraph graph, View view) {
this.view = view;
view.addKeyListener(this);
}
@Override
public void release() {
view.removeKeyListener(this);
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("keyPressed!");
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("keyReleased!");
}
@Override
public void keyTyped(KeyEvent e) {
System.out.println("keyTyped!");
}
});
}
}
Workaround (until it will be fixed): I use reflection to get the frame and then I add the keyboard listener to it. It is not elegant, but if you run this code it works as intended.
package app;
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import org.graphstream.graph.implementations.SingleGraph;
import org.graphstream.ui.swingViewer.ViewPanel;
import org.graphstream.ui.swingViewer.DefaultView;
public class App {
public static void main(String args[]) {
var graph = new SingleGraph("test", false, true);
graph.addEdge("AB", "A", "B");
graph.addEdge("CD", "C", "D");
graph.addEdge("BD", "B", "D");
var viewer = graph.display();
try {
var frame = ((DefaultView) viewer.getDefaultView())
.getClass().getDeclaredField("frame");
frame.setAccessible(true);
((JFrame) frame.get(((DefaultView) viewer.getDefaultView())))
.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
System.out.println("keyPressed!");
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("keyReleased!");
}
@Override
public void keyTyped(KeyEvent e) {
System.out.println("keyTyped!");
}
});
} catch (NoSuchFieldException|IllegalAccessException e) {
e.printStackTrace();
System.exit(1);
}
}
}
Your first example works perfectly fine with me (I just added the missing Viewer import and corrected these "var").
import java.awt.event.KeyEvent;
import org.graphstream.graph.implementations.SingleGraph;
import org.graphstream.ui.view.View;
import org.graphstream.ui.view.Viewer;
import org.graphstream.ui.view.util.ShortcutManager;
import org.graphstream.ui.graphicGraph.GraphicGraph;
public class Issue {
public static void main(String args[]) {
SingleGraph graph = new SingleGraph("test", false, true);
graph.addEdge("AB", "A", "B");
graph.addEdge("CD", "C", "D");
graph.addEdge("BD", "B", "D");
Viewer viewer = graph.display();
viewer.getDefaultView().setShortcutManager(new ShortcutManager() {
private View view;
@Override
public void init(GraphicGraph graph, View view) {
this.view = view;
view.addKeyListener(this);
}
@Override
public void release() {
view.removeKeyListener(this);
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("keyPressed!");
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("keyReleased!");
}
@Override
public void keyTyped(KeyEvent e) {
System.out.println("keyTyped!");
}
});
}
}
@hichbra var
is just a Java keyword. Anyway the first example doesn't work for me (it runs but it won't print any output), I'm using 1.3 version, which version are you using?
Ok it's java 10+ my bad, but still it works, I don't have any issue with this code under graphstream 1.3.