I have a multiple-choice JavaSwing app that has checkboxes and next/previous buttons. I had it modified so focus is now on the Next button when it launches, allowing user to press Enter/Return to go to next screen.
The problem now is when user selects a checkbox, the Next button loses its keyboard focus and grey outline. Coder has added a hack so the button is regains focus and grey outline each time a checkbox is selected, but then the button blinks on each mouse-click! Some screens have 4 correct checkboxes, so button blinks 4 times.
I think this is unacceptable behaviour but he says,"Expected behavior is when you select any control its obvious it gains focus on that Element. You are saying to override Java Inbuilt Functionality which is not possible."
This just feels wrong. Is he right? Is there any source I can point him to that will allow him to keep focus on checkboxes on mouse-click, while keeping keyboard focus on buttons?
Many thanks in advance.
You should not mess around with the keyboard focus - that only infuriates the users that try to navigate your UI with key strokes only.
What you are looking for is the "default button" that is available on JFrames and JDialogs rootpane:
public JFrame makeFrame() {
JFrame f = new JFrame(...);
JButton next = new JButton("next");
f.getRootPane().setDefaultButton(next);
return f;
}
public JDialog makeFrame() {
JDialog d = new JDialog(...);
JButton next = new JButton("next");
d.getRootPane().setDefaultButton(next);
return d;
}
Your programmer probably should just set setFocusable(false) on the checkboxes.
Related
I'm getting some trouble with a toolbar I made. In this I have 4 JButtons and below a JTable, which is set on focus when my windows shows in order to see the JButtons unfilled.
This is how I set each JButton:
btn = new JButton("New");
btn.setFocusPainted(false);
btn.setBackground(SystemColor.window);
btn.setVerticalTextPosition(SwingConstants.BOTTOM);
btn.setHorizontalTextPosition(SwingConstants.CENTER);
btn.addActionListener(new ActionListener() {
...
});
btn.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
toolBar_General.add(btn);
btn.setIcon(new ImageIcon(MainWindow.class.getResource("/icons/file11.png")));
Example of my toolbar at start: http://www.tiikoni.com/tis/view/?id=0ef950b
But after clicking on a JButton, it remains filled after itsactionListener does his work.
Example of my toolbar after clicking a JButton: http://www.tiikoni.com/tis/view/?id=9e88ea4
My question is: how can I mantain my buttons contentAreaFilled property true (so the user can tab between components in my window and see which control he has selected) and unfocus my button after the user click?
The result I would like to have is that of the first photo.
I think the call you are looking for is:
btn.setRequestFocusEnabled(false);
this will stop your buttons from taking over the focus when the mouse clicks them, achieving the goal of not having the keyboard focus painted for mouse users. However it still lets keyboard-centric users "tab over" to them.
If one of your buttons gets the initial focus, however, then the keyboard focus will still render there. In that case, you probably want to select some other sensible component to place the initial keyboard focus onto by calling:
otherComponent.requestFocusInWindow();
Are you talking about the input Focus? (the dotted rectangle a component shows when it has the focus)
You can explicitly disable a component getting the focus by calling setFocusable(false) on the component (e.g. every button). It does not prevent you from clicking on the buttons, but it does prevent you from cycling the focus with the tab-key to it.
I am extending the JButton class and using an ImageIcon as my button background. I have also added a mouseListener so I can change the image of the button when the mouse hovers over the button or presses the button. This all works fine but the problem is that when the button is clicked a JOptionPane is displayed asking the user "Are you sure" while the option pane is displayed the buttons MouseClicked, mouseExited or mouseReleased methods are not executed so it looks like the button is stuck pressed until the use deals with the option dialog. Removing the dialog is not an option. Is there a way to get the mouse events executed before or during the dialog displaying?
I have also added a mouseListener so I can change the image of the button when the mouse hovers over the button or presses the button.
Read the AbstractButton API. There are methods that allow you to specify the Icon for these situations. For examples setPressedIcon().
it looks like the button is stuck pressed until the use deals with the option dialog.
Not sure if the ButtonModel state has been changed before the option pane is displayed or not. Anyway you can try using:
button.paintImmediately(...);
before the option pane is displayed. If the ButtonModel state has been updated the button should be repainted in its normal state. Note, this method should rarely be used since it can affect painting performance.
So I have a UI that I made with Swing using Java. It is very complex and I want to save the user some time by making the UI simpler.
Imagine you have a page with many CheckBox. Once you select whatever CheckBox you desire, the next button makes a JFrame appear with the same tabs as you selected inside a Tabbed Pane.
Here is a small sample of my code which should give an idea of what I want the button to do:
btnNewButton_7.addActionListener(new ActionListener(){
#SuppressWarnings("static-access")
public void actionPerformed(ActionEvent e){
Admin.set.frame.setVisible(false);
Admin.adv.setVisible(true);
Admin.adv.jp2.setVisible(chckbxNewCheckBox_42.isSelected());
Admin.adv.jp3.setVisible(chckbxNewCheckBox_43.isSelected());
Admin.adv.jp4.setVisible(chckbxNewCheckBox_44.isSelected());
}
});
So the next Button should set the JFrame (set.frame) invisible. Then, it should open adv (a new frame). So far, everything is working. Now, my tabe are JPanel inside adv. I would love to make them disappear whenever the CheckBox 42,43 and 44 are selected or unselected, should I add an onChangeListener?
I independently invented the same solution as described in How to create a JButton with a menu? for creating a popup menu in a Swing applet. However, the coordinate specified in popup.show() is where the upper-left of the popup menu will be. I want the lower-left of the menu to coincide with the upper left corner of my button. This is the same as the layout older Windows versions use for the Start menu relative to the Start button.
What I have is this:
JPopupMenu popup_menu;
JButton button;
public void actionPerformed(ActionEvent e)
{
int menu_height = this.popup_menu.getHeight();
this.popup_menu.show(this.button, 0, -menu_height);
}
The problem is that the first time the button is clicked, it seems menu_height isn't properly initialized and the menu appears in the bottom right. However on subsequent clicks it's okay. The best ideas I can come up with are
showing the JPopupMenu when the applet starts up, then hiding it after a 1ms delay.
writing my own Swing menu component
Anyone have ideas that are more elegant than the first but less work than the second?
I have one button which set time on Timer. So now I push. Button change time on Timer and this is still selected. In this frame I have keyListener so when I push space Timer with start but now when I push space it push again this button because it is still selected. How I can improve this button when I push it, it will not be selected ?
I'm not sure of having fully understood your question.
If you want to disable click on a JButton:
JButton b = new JButton();
b.setEnabled(false);
If you want to unselect it:
b.setSelected(false);
You could also find useful prevent a button to gain focus:
b.setFocusable(false);
You can change the focus by calling the correct method in KeyboardFocusManager
KeyboardFocusManager kfm = KeyboardFocusManger.getCurrentKeyboardFocusManager();
kfm.focusNextComponent();
This causes focus to move to the next component, whatever it is. This has the advantage of being independent of what the component is, so that if the UI changes, this still moves to the "next" component rather than a specific component you specify to receive focus.
If your problem is that you do not want the user to press the button while other things are happening, you should consider disabling the button (as explained in a previous answer) so that it cannot be activated in any way. You need to enable it again, of course, as soon as it is legal to use it again.
rc