Trouble managing keyboard focus - java

I'm currently working on an application that generates a kenken puzzle, wherein the user inputs number to solve it. However, I can't seem to get the focus system to work; my JFrame doesn't even receive focus to begin with. Here is the method which initializes the main frame:
public static void initMain() {
mainframe.setVisible(true);
mainframe.setSize(new Dimension(900, 900));
mainframe.requestFocus();
System.out.println(mainframe.isFocusOwner());
System.out.println(mainframe.isFocusable());
mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainframe.setExtendedState(JFrame.MAXIMIZED_BOTH);
mainframe.setContentPane(puzzle);
in = mainframe.getInsets();
mainframe.setJMenuBar(bar);
bar.add(menu);
menu.add(item);
item.addMouseListener(new MouseListener () {
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {popup();}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
});
}
(latter half not so important here, just showing it for completions's sake)
The first output is always false, and key events aren't generated. From what I gethered online, setting the window to visible and requesting focus should be enough, although the emphasis is on should. My operating system is Windows 8, incase that makes a difference.

Ok nvm, got the focus to work via requestFocusInWindow (which also didn't work previously). Seems like the problem was requesting focus too early and only once. Why the mainframe focus didn't work either I still don't quite get, but that doesn't matter now I guess. Thanks anyways for your answers.

Related

How to find the JComponent which has focus within a Swing application?

I am having problems to identify where the focus within my application goes to after activating/deactivating or opening/closing some dialogs.
Is there a way to safely get an event down handed down the component hierarchy to be informed when the focus changes and where to?
In a Smalltalk environment for instance, you could for testing reasons just re-implement #requestFocus on Window/SubPane (i.e. JComponent) level and have a debug statement where the focus went.
Can you do something like that in Java or is there a mechanism I am missing?
I'm not entirely sure what you're trying to do with this, but to answer your question you could add a FocusListener to each element. An avriable is then written using the FocusGained function.
int focus = 0;
textField1.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
focus = 1;
}
#Override
public void focusLost(FocusEvent e) {
}
});
textField2.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
focus = 2;
}
#Override
public void focusLost(FocusEvent e) {
}
});
So the appearant culprit was a debug tooltip. Removing these completely and adding Steffi's code for logging have made me sure enough that this is now solved. Thanks to all, I have learned again something new.

How does this Code show that the Mouse has clicked?

Seen this somewhere in StackOverflow. Just want to know how it works...
public void mouseClicked(MouseEvent e){
int x = e.getX();
int y = e.getY();
}
x and y are coordinates and can be shown to screen using JLabel, but the method name is mouseClicked. How does java know the mouse has been clicked?
(Hope this makes sense)...
The method mouseClicked is likely from java.awt.event.MouseListener interface (https://docs.oracle.com/javase/7/docs/api/java/awt/event/MouseListener.html)
A listener is a type of callback that follows the observer pattern, something happens, you get notified.
You can attach listener to items that support it. For example:
MouseListener listener = new MouseListener() { /* see example code below */ };
JLabel label = new JLabel("This is a clickable lable");
label.addMouseListener(listener);
See the following answer to get more info and reference to reading articles.
https://stackoverflow.com/a/17415300/132121
#transformer here is an empty implementation of the MouseListener you would create in Java code.
MouseListener listener = new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
// This is the method where you would get your callback
// whenever somebody clicked on the view that has this listener
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
};
This is an event handler. In order for it to work, it has to be "attached" to something in the front end (most likely a button, but it could be another UI element too).
Exactly how this works depends on which UI framework is being used, but since this is Java I assume it's most likely AWT. You can find more details in tutorials, e.g. here.
Incidentally, how significant the name is depends on which UI framework this is from. In Android, WPF, and ASP.NET, for example, the name of event handlers could theoretically be anything, it's mostly just a matter of convention (not actual requirement) what you call it. (Obviously, you have to be consistent with the name, though). As pointed out in the comments, though, in AWT this name is actually likely significant due to the class that contains it implementing an interface.

Is there a way to replace scanner, with the java applet mousedown boolean event? [duplicate]

What is the best way to listen for keyboard input in a Java Applet?
I have an applet which opens a JFrame and I am using a KeyListener to listen for keyboard input. This works fine in my development environment (eclipse), but when I run the applet through a browser (I have tried Firefox and IE) it does not respond to keyboard events.
However, if I run the applet and then minimize and maximize the frame, it works.
I have tried setting focus to the JFrame in many different ways and also programmatically minimizing and maximizing it, but to no effect.
I have also tried key bindings, but with the same problem.
I have trimmed my code down to the barest essentials of the problem and pasted it below.
Can someone see what I am doing wrong or suggest a better solution?
public class AppletTest extends Applet
{
private GuiTest guiTest;
public void init() {
guiTest = new GuiTest();
final AppletTest at = this;
guiTest.addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent ke) {
at.keyPressed(ke);
}
public void keyReleased(KeyEvent ke) {}
public void keyTyped(KeyEvent e) {}
});
}
private void keyPressed(KeyEvent ke)
{
System.out.println("keyPressed "+KeyEvent.getKeyText(ke.getKeyCode()));
getGuiTest().test(KeyEvent.getKeyText(ke.getKeyCode()));
}
}
public class GuiTest extends JFrame {
String teststring = "?";
public GuiTest()
{
setSize(100,100);
setEnabled(true);
setVisible(true);
setFocusable(true);
requestFocus();
requestFocusInWindow();
toFront();
}
public void test(String t)
{
teststring = t;
repaint();
}
public void paint(Graphics g)
{
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.black);
g.drawString(teststring, 50, 50);
}
}
I solved the problem. If I create the JFrame following a button press or mouse event on the applet, the key listener on the JFrame works. Apparently, creating the frame from Applet.init() means that key listeners do not function correctly when opened through a browser.
However, the question remains - why? If someone can explain this, I would greatly appreciate it.
I thought it might be because the frame should be created on the event dispatch thread, but using SwingUtilities.invokeLater or invokeAndWait did not work.
I think you are running into the plugin focus issue: in many modern browser a plugin only gains focus through either the user clicking on it or using Javascript. This typically affects Flash but it might be that it also affects applets. Try Adobe's recommendations at http://kb2.adobe.com/cps/155/tn_15586.html.
Let me know if that works for you.

Capturing Keystrokes in Java without focus on a Panel

I was wondering if there was a way to trigger a KeyEvent with Java's KeyListener while the Java program is running in the background? I want to keep track of what keys are being pressed and save them for later use. Here is a sample of the code I am trying to trigger:
public static class Push implements KeyListener{
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyPressed(KeyEvent e) {
//Save KeyEvent info here
}
}
I do have a way of saving the information that I want, I just need to trigger this event. I am using an invisible window to cover my screen. I can click through this window , so it gives the appearance of not being there. Any help on this issue would be much appreciated.

How do I close a JDialog and have the Window Event Listeners be notified?

Is there a way to close a JDialog through code such that the Window event listeners will still be notified? I've tried just setting visible to false and disposing, but neither seem to do it.
Closing a window (with dispose()) and hiding it (with setVisible(false)) are different operations, and produce different events -- and closing it from the operating system is yet another different operation that produces yet a different event.
All three will produce windowDeactivated to tell you the window's lost focus, but dispose() will then produce windowClosed, while closing from the OS will first produce windowClosing. If you want to handle both of these the same way, you can set the window to be disposed when closed:
window.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
In general, setVisible(false) implies that you might want to use the window again, so it doesn't post any window events (apart from windowDeactivated). If you want to detect the hiding of a window, you need to use a ComponentListener;
window.addComponentListener(new ComponentAdapter() {
#Override
public void componentHidden(ComponentEvent e) {
System.out.println("componentHidden()");
}
})
Note though that this will pretty much only work for explicit setVisible() calls. If you need to detect hiding more generally, you can use a HierarchyListener, but it's probably more trouble than it's worth.
window.addHierarchyListener(new HierarchyListener() {
#Override
public void hierarchyChanged(HierarchyEvent e) {
System.out.println("valid: " + window.isValid());
System.out.println("showing: " + window.isShowing());
}
});
Note that when you dispose a window you'll get a couple of HierarchyEvents, first for hiding and then for invalidation, but when you hide it with setVisible() it's still valid, so you won't get the invalidation.
I don't seem to have your problem. When I use the code below windowDeactivated() is called for either setVisible( false ) or dispose() and windowClosed() is also called for dispose().
ClosingDialog.java:
public class ClosingDialog extends JDialog {
public ClosingDialog(Frame owner, String title, boolean modal) {
super(owner, title, modal);
JPanel contentPanel = (JPanel) this.getContentPane();
JButton setVisButton = new JButton("setVisible( false )");
setVisButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ClosingDialog.this.setVisible(false);
}
});
JButton disposeButton = new JButton("dispose()");
disposeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ClosingDialog.this.dispose();
}
});
contentPanel.setLayout(new FlowLayout());
contentPanel.add(setVisButton);
contentPanel.add(disposeButton);
this.addWindowListener(new WindowListener() {
public void windowActivated(WindowEvent e) {
System.out.println("windowActivated");
}
public void windowClosed(WindowEvent e) {
System.out.println("windowClosed");
}
public void windowClosing(WindowEvent e) {
System.out.println("windowClosing");
}
public void windowDeactivated(WindowEvent e) {
System.out.println("windowDeactivated");
}
public void windowDeiconified(WindowEvent e) {
System.out.println("windowDeiconified");
}
public void windowIconified(WindowEvent e) {
System.out.println("windowIconified");
}
public void windowOpened(WindowEvent e) {
System.out.println("windowOpened");
}
});
this.setSize(300, 300);
}
}
Dispatch a windowClosing event to the Window. Check out the ExitAction example from the Closing an Application entry.
Untested suggestion:
Have you tried getWindowListeners() and then iterating around to fire windowClosed() to each of the WindowListeners?
EDIT: the above suggestion is wrong. Keeping it for posterity.
I'm afraid calling dialog.dispose() works fine for me in my simple example.
I wanted to fire a windowClosing event from the code (just as if the user clicked the X), because I have an extra close button in the JDialog and want the same WindowListener (that I implemented using a WindowAdapter) to be run when the X is clicked and when the button is clicked. Running dispose() only fires windowClosed, not windowClosing, and I want a message to appear before the window is closed, for confirmation. I also didn't manage to fire windowClosing via JDialog's method processWindowEvent since it is protected.
Here is how I got it working though:
WindowAdapter adapter = (WindowAdapter)jdialog.getWindowListeners()[0];
adapter.windowClosing(new WindowEvent((Window)jdialog, WindowEvent.WINDOW_CLOSING));
Hope that helps someone.

Categories

Resources