So I am building an login frame using Netbeans 8.1. The problem is that after the user has typed in their username, I want them to be able to press the tab key and then have the password textField selected, but instead of this, the 'Login' button is selected.
On startup the username field is selected.
Then when I press tab it looks like this
But instead I want it to look like this when I press tab
Any help is welcome, but I would prefer it if I can do this without getting into the code and can use the Netbeans GUI instead(the project is only about designing the GUI, and nothing about the actual code).
You need order your component indexes, it calls tab index.
NetBeans 8.0 I believe the first component (ie. textBox) you add to the design window should be the one the cursor defaults to when you run the program. You can set the order for tabbing from component to component when you run the program in the design window. Select the first component. In the Properties window, go to nextFocusableComponent and choose the next component you want to tab to in the dropdown list. Repeat for rest of components
I hope this helps you!
Look at this answer.
You can implement your own FocusTraversalPolicy which will manage the tab order. You can then assign it to your frame with the setFocusTraversalPolicy method.
You can find some more explanations in Oracle's doc.
No Tab key-pressed or key-released events are received by the key event listener. This is because the focus subsystem consumes focus traversal keys, such as Tab and Shift Tab.
See: http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html
To solve this, apply the following to the component that is firing the key events (e.g., the TextArea):
.setFocusTraversalKeysEnabled(false)
Using this method, you must then handle focus traversal explicitly. Alternatively, the KeyEventDispatcher class can be used to pre-listen to all key events.
you can do following way also
txtUserName.addKeyListener(new KeyAdapter()
{
public void keyReleased(KeyEvent arg)
{
if (arg.getKeyCode() == KeyEvent.VK_ENTER)
{
txtPassword.requestFocus();
}
}
});
txtPassword.addKeyListener(new KeyAdapter()
{
public void keyReleased(KeyEvent arg)
{
if (arg.getKeyCode() == KeyEvent.VK_ENTER)
{
btnLogin.doClick();
}
}
});
Related
I've written a basic calculator type program using WindowsBuilder in Eclise neon and Java 1.8. It's pretty much complete, with everything working how I want it to. Except keyboard entry.
As a finishing touch I'd like to detect keyTyped events and map them to button presses so users can use the keyboard for entry instead of clicking buttons with the mouse.
I've added 'implements KeyListener' to the program class...
public class CashRegister implements KeyListener {
private JTextField keyb;
I've tried to set a listener to a invisible JTextField called keyb....
private void initialize() {
keyb = new JTextField(20);
keyb.addKeyListener(this);
keyb.setFocusable(true);
keyb.requestFocusInWindow();
And I've added methods to handle the captured keypress...
public void keyTyped (KeyEvent e) {
String out = "";
out = out + e.getKeyChar();
pence1text.setText(out);
}
public void keyPressed (KeyEvent e) {
}
public void keyReleased (KeyEvent e) {
}
So, at this stage all I'm expecting, prove it is working, is the keycharacter I press to appear in the textfield called 'pence1text'. However, it doesn't work, when I press the a key nothing is displayed.
I think it could be a focus problem. Googling around and checking stackoverlow lead me to add the following lines...
keyb.setFocusable(true);
keyb.requestFocusInWindow();
as above, but still no luck.
Does anyone have any ideas what I am doing wrong, or what I can try next?
Thanks
Thanks to user Andrew Thompson for pointing me back to the docs and a re-read.
The problem is that the JTextField is not visable and thus can't be given focus. If I add the listener to a textfield that is visable then the program works correctly. However if the user uses the mouse to click a button it loses focus and breaks the implementation...so I need to rethink the code and keep looking at focuse settings.
As a finishing touch I'd like to detect keyTyped events and map them to button presses so users can use the keyboard for entry instead of clicking buttons with the mouse.
Don't use a KeyListener.
Instead you should be using Key Bindings. Read the section from the Swing tutorial on How to Use Key Bindings for basic information.
Also check out: how to put actionlistenerand actioncommand to multiple jbuttons for a working example that shows how you can apply the key bindings to a calculator.
Most windows users may remember that every windows 98 properties/settings window had a little question mark button next to other window buttons:
If you clicked on that button, all click events were overriden by different callback for that window. And that new callback would display element's individual help text.
I'd like to do the very same. My idea was to do it using class which holds all JComponent and Help associations:
public interface Help {
/** based on implementation, displays help to the used. May use
* JDialog, url redirection or maybe open document on the computer.**/
public void getHelp(JComponent comp, ActionEvent evt);
}
public class HelpLibrary {
public HashMap<JComponent, Help> helpLib;
public void getHelp(JComponent comp, ActionEvent evt) {
Help help = helpLib.get(comp);
if(help!=null) {
help.getHelp(comp, evt);
}
}
}
Writing these two classes was the easy part. The hard one is this:
How to override all click events in particular window and then remove override after help was called?
How to ensure help cursor will override all other cursors, and again, safely remove this setting?
I have no idea where to start with this. I really do not want to change the GUI structure or used classes just because of this, which is why I want to store the help and do the overrides from the outside.
public class HelpLibrary {
/**
* Overrides click events on the given window and displays help cursor.
* User then may click a JComponent, such as button, to initiate
* help callback for that element. If no help exists for that element,
* do nothing and stop the help mode.
* #param window the window to get help for
**/
public void waitForHelp(JFrame window) {
???
}
}
You can try following:
Register a global MouseListener using
Toolkit.getDefaultToolkit().addAWTEventListener(myListener, AWTEvent.MOUSE_EVENT_MASK)
Cast the incoming event to MouseEvent and check the event type using the getID() method
If the event is a click for a component, which has help, you need to show help, consume event and remove this listener from the global listener list.
You can also override mouseEnter/Exit event in this
listener for components which have help text, and set the cursor to
question/normal type (don't forget to consume this event).
This is only idea for you, I've not tested whether it works.
You could use a GlassPane.
Read the section from the Swing tutorial on How to Use Root Panes. The Glass Pane demo shows how to intercept mouse events and redispatch the event to the underlying components. YoOu would obviously change this code to find the component under the mouse click and then display the help context.
The glass pane can be toggeled on/off by making it visible or not.
I have tried multiple times to find out a solution on my own by consulting Google, but this question, as ridiculously easy as it seems, has no documented answer. It seems to me.
All I want to know is: How to call a method from a keystroke?
Example: Pressing ctrl + up -> call method zoomUp();
ps: would be nice if that keystroke could be bound to a JTextPane.
Update
Until now my solution was to:
Create an Item: JMenuItem up = new JMenuItem("up");
Create a shortcut:
up.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_UP,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
Catch the event by a listener:
up.addActionListener(new java.awt.event.ActionListener() { public
void actionPerformed(ActionEvent event) {
//Do stuff } });
(- never add the Item so it is a hidden shortcut)
But this is obviously ridiculous.
You cannot use JMenuItem to create "hidden" short cuts. The short cuts of JMenuItems become active once the JMenuItem gets indirectly added to a Window (usually via <-JMenu<-JMenuBar<-JFrame). Without that link, it cannot be known whether or not the accelerator is to be triggered or not, as the same accelerator might trigger different actions in different application windows.
You need to use a KeyListener on the component or frame in which you want to react.
On Windows if you click on the table tooltip (JToolTip), it will remove the tooltip AND select the row in the table. However on the Mac, it seems to just remove the tooltip and does NOT select the row in the table.
The code just uses a standard JTable and overrides getToolTipText method from JTable. No custom JToolTip is created or anything like that.
Code:
public class MyJTable extends JTable
{
#Override
public String getToolTipText(MouseEvent event)
{
return "Hello world";
}
}
**Update: On further investigation the issue seems to be due to something similar to this bug report. Basically the ToolTipManager.showTipWindow() is creating the tooltip as a HeavyWeight component on the Mac and a LightWeight component on Windows, which then causes the mouselistener not to be fired. The worse part is that regardless if you set the popupType to be lightweight, it will still create it as a heavyweight component in that method when the Java code calls popupFactory.getPopup(...)
No idea how to fix it.
Normally a different tooltip is given for each row or cell and not the entire table. So as you move the mouse the tooltip changes and is displayed in a different location so you never get an opportunity to actually click on the tooltip.
So, maybe as an alternative approach, you could also override the getToolTipLocation() method:
public Point getToolTipLocation(MouseEvent e)
{
return new Point(e.getX(), e.getY() + 10);
}
Now the user will never be able to click on it.
The reason clicking on the ToolTip does not generate a MouseEvent on the JTable is because the ToolTip is generated as a HEAVY_WEIGHT_POPUP rather than a LIGHT_WEIGHT_POPUP.
This can be due to a number of reasons, even something as simple as a L&F that does this.
The way it works in Java Swing is that the PopupFactory will create the ToolTip. In Java mixing HeavyWeight and LightWeight component can have some ramifications and as a result around Java 5-6 (not sure which) the Java language added the ability to define this property, however some L&F libraries don't use it or correctly adhere to it. And if you're using an older version it may just not be possible. For more details on the need for this toggle you can read the following bug report before the toggle was added to Swing.
In any case, if the component (in this case the ToolTip) is a HEAVY_WEIGHT_POPUP then the MouseEvent will not propagate to the JTable, and hence only the ToolTip will disappear and the row in the table will not be selected. The ToolTip needs to be a LIGHT_WEIGHT_POPUP for the MouseEvent to propagate to the JTable.
My situation is as follows: I've got a JList which triggers a search (using a ListSelectionListener) whenever a selection is made in the list. I'm trying to reset the selection on the list, using list.clearSelection(). The problem with this is that using clearSelection() triggers the listener, which calls the search: not good.
Is there a way of clearing the selection on the list without having the listener triggered? Could this be a hint that I'm not using the listener properly? In general though, can you change something in a Swing UI without triggering events associated with that element?
Thanks.
Read the section from the Swing tutorial on How to Write a List Selection Listener for a working demo.
Normally two events are generated, one for the deselection and one for the selection. You should only be doing your search when something is selected. You should also be able to check selected index which should be something other than -1 I believe.
Try following pattern when using clear() method to clear Jlist:
ListObjectName.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()){
if(ListObjectName.getSelectedIndex()>-1){
//Your Code
}
}
}
});