Focus not being set by method to grab focus - java

Learning to code, building a GUI to figure out how everything interacts. Trying to write a method to set focus on (component) at the points I need in the larger program - ie to call FocusGrabber(JTextField1) and have it set the input focus on JTextField1. In an attempt to do my best SSCCE, I've made a simple main that makes just enough GUI to give 2 textfields that should set focus on the second.
package ODIN;
import java.awt.Component;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
/*
*/
class FocusGrabber implements Runnable {
private JComponent component;
public FocusGrabber(JComponent component) {
this.component = component;
}
#Override
public void run() {
component.grabFocus();
}
public static void main(String[] args){
//draw and show the GUI
JFrame GUI = new JFrame();
GUI.setTitle("New Provider Interface");
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JTextField textID = new JTextField("providerID ", 20);
final JTextField textName = new JTextField("Provider Name ", 20);
GUI.add(textID);
GUI.add(textName);
GUI.pack();
GUI.setVisible(true);
FocusGrabber(textName);
}
}

Use requestFocusInWindow over grabFocus...
It would also be helpful if you called the run method at some point
Also, shouldn't it be more like
FocusGrabber fg = new FocusGrabber(textName);
fg.run();

Related

KeyListener/KeyBindings and order of adding components

In my program a JPanel component which is operated by listener using KeyBindings (changed that from KeyListeners already after reading about issues with focusing) is added to a JFrame. Task of this app is to simply move drawn figure around using arrow keys.
This works perfectly until i add another component before drawing board (JPanel with three buttons).
I tested both Keybindings and KeyListener and both methods have the same issue.
If I add components after drawing board keybindings starts to work again.
Here is my UI class where i add components.
EDIT: removed uncleaned code
I would like to understand Java a bit more so any answer is very appreciated.
Edit: I cleaned my code and created "minimal" example of the problem.
Thank you Andrew for heads up.
Program should print "movingup" in console after pressing arrow up.
The problem occurs here:
container.add(buttons); //after adding this Key Bindings stops working
container.add(board);
And the question is: Why order of adding components makes Key Bindings to stop working? If i add buttons after board Key Binding is working.
Class with the problem (used for creating frame and adding components)
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.WindowConstants;
public class UserInterface implements Runnable {
private static final String MOVE_UP = "moveUP";
private JFrame frame;
public UserInterface() {
}
#Override
public void run() {
frame = new JFrame("Board");
frame.setPreferredSize(new Dimension(500, 400));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout());
createComponents(frame.getContentPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void createComponents(Container container) {
DrawingBoard board = new DrawingBoard();
container.add(new JButton()); //after adding this figure stops moving - arrow keys doesn't work
container.add(board);
MovingUpwards up = new MovingUpwards(board);
board.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
board.getInputMap().put(KeyStroke.getKeyStroke("UP"), MOVE_UP);
board.getActionMap().put(MOVE_UP, up);
}
public JFrame getFrame() {
return frame;
}
}
Rest of the used classes for testing purposes:
import javax.swing.SwingUtilities;
public class Main {
public static void main (String[] args) {
UserInterface ui = new UserInterface();
SwingUtilities.invokeLater(ui);
}
}
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class DrawingBoard extends JPanel {
public DrawingBoard() {
super.setBackground(Color.WHITE);
}
#Override
protected void paintComponent (Graphics graphics) {
super.paintComponent(graphics);
}
}
import java.awt.Component;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
public class MovingUpwards extends AbstractAction {
private Component component;
public MovingUpwards(Component component) {
this.component = component;
}
#Override
public void actionPerformed(ActionEvent a) {
System.out.println("movingup");
}
}
The key bindings work fine for me. Check out the Motion Using Key Bindings example found in Motion Using the Keyboard.
I changed the code:
frame.add( content );
frame.add(left, BorderLayout.NORTH);
to:
frame.setLayout(new GridLayout());
frame.add(left);
frame.add( content );
to better simulate your logic.
If you need more help then read Andrew's comment above. Simplify your code to demonstrate the problem so we can "easily" test it by copying and compiling a single source file, the way you can test the code found in the link above.

holding key breaks java swing form

I am working on a basic Java Swing UI application, which seems to be working correctly, except for an issue I've noticed when using the form I created.
The problem is when I am typing in the text boxes, holding down a key seems to break the form--ie, after taking this action, the text boxes no longer seem to accept any input. I find it hard to believe this is a released issue with Java Swing components, but I also can't see how it would be related to my code. Has anyone seen a similar issue before? I am using OS x with Intellij IDEA if that is relevant.
My form is defined thusly:
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
#SuppressWarnings("serial")
public class LoginDialogMcve extends JFrame {
protected JTextField stringEntry, dateEntry;
public LoginDialogMcve() {
super("Create Textbox");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
this.stringEntry = new JTextField(5);
add(this.stringEntry);
this.dateEntry = new JTextField(5);
add(this.dateEntry);
}
public static void main(String... args) {
LoginDialogMcve me = new LoginDialogMcve();
me.pack();
me.setLocationByPlatform(true);
me.setVisible(true);
}
}
Edit: Thanks for the feedback, this is quite possibly not a Java problem. Could have something to do with OSx... Uploaded simpler example with mcve
My MCVE that works fine. Test it yourself to see.
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
// import net.miginfocom.swing.MigLayout;
#SuppressWarnings("serial")
public class LoginDialogMcve extends JFrame {
protected JTextField stringEntry, dateEntry;
protected JLabel stringEntryLabel, dateEntryLabel;
protected JButton print;
protected Action validateAction;
public LoginDialogMcve() {
super("Create Textbox");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
// setLayout(new MigLayout("ins 10, gap 5",
// "[][grow]",
// "[][][]"));
this.stringEntryLabel = new JLabel("Name:");
add(this.stringEntryLabel);
this.stringEntry = new JTextField(5);
add(this.stringEntry);
this.dateEntryLabel = new JLabel("Date:");
add(this.dateEntryLabel);
this.dateEntry = new JTextField(5);
add(this.dateEntry);
this.validateAction = new MyAction();
this.print = new JButton(this.validateAction);
add(this.print);
getRootPane().getActionMap().put("validate", this.validateAction);
}
public static void main(String... args) {
LoginDialogMcve me = new LoginDialogMcve();
me.pack();
me.setLocationByPlatform(true);
me.setVisible(true);
}
public class MyAction extends AbstractAction {
public MyAction() {
super("Validate");
}
#Override
public void actionPerformed(ActionEvent e) {
// lots of irrelevant code
}
}
}

I can't move my JLabel with Key Binding?

I am trying to make a game in Java where pressing spacebar moves the box in the window. I am using Key Binding to accomplish this task. The problem is that I can't figure out how to use an ActionListener on the box itself, which is a JLabel. Here is the code below:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Game {
private static JFrame frame = new JFrame();
private static JPanel gamePanel = new JPanel();
private static Action playerAction = new PlayerListener();
private static JLabel box = new JLabel();
private static int x = 250;
private static int y = 250;
public static void main(String[] args) {
frame.add(boxPanel());
frame.setTitle("Block Game");
frame.setSize(500,500);
frame.setLocationRelativeTo(null);
frame.setFocusable(true);
box.addActionListener(playerAction);
frame.setVisible(true);
}
static JPanel boxPanel() {
ImageIcon boxIcon = new ImageIcon("box.png");
box.setIcon(boxIcon);
box.setSize(30,30);
box.setLocation(x,y);
box.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "doPlayerAction");
box.getActionMap().put("doPlayerAction", playerAction);
gamePanel.setLayout(null);
gamePanel.add(box);
frame.add(gamePanel);
return gamePanel;
}
static class PlayerListener extends AbstractAction {
public void actionPerformed(ActionEvent e) {
System.out.println("SPACEBAR");
}
}
}
I tried changing the box to a JButton and working with that instead, but I have found that "SPACEBAR" only prints out when I click on the box itself. Any help is greatly appreciated. Thanks!
Your "core" problem revolves around box.getInputMap(), change it to something more like box.getInputMap(WHEN_IN_FOCUSED_WINDOW) which will mean that the API will respond to key events whenever the window has focus, regardless what other components might have focus.
I'd also suggestsomething more like box.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "doPlayerAction"), as the mechanism which KeyStroke uses to parse String to a KeyStroke is more complicated then it might seem, normally requiring additional information like pressed, released or typed, it's just easier to use the virtual keys
I would also bind the keys to the gamePanel as a general preference, as it should be the container making decisions about what to do, but that's just me.
Have a look at How to Use Key Bindings for more details

JRadioButton selection doesn't show on GUI until visible in Windows LaF

I'm currently working on a project that requires the state of a JRadioButton to change when the record being viewed is updated.
We've had a few clients complain to us that when the record changes, if the JRadioButton is off-screen, it won't be updated until the screen is shown. This behavior seems to be a result of using the Windows Look and Feel, as it doesn't seem to happen when it is not set.
The code example below demonstrates this.
The default selected JRadioButton is 'Cat', so by selecting the 'Dog' JButton and then changing tab to 'Question', you can see the JRadioButton transition occur.
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
* Example of JRadioButton not updating until it's parent panel becomes visible.
*/
public class RadioButtonExample extends JPanel implements ActionListener {
public static final String CAT = "Cat";
public static final String DOG = "Dog";
private final JRadioButton radCat;
private final JRadioButton radDog;
private final ButtonGroup grpAnimal;
public RadioButtonExample() {
super(new BorderLayout());
JLabel lblQuestion = new JLabel("Are you a cat or dog person?");
radCat = new JRadioButton(CAT);
radCat.setActionCommand(CAT);
radCat.setSelected(true);
radDog = new JRadioButton(DOG);
radDog.setActionCommand(DOG);
grpAnimal = new ButtonGroup();
grpAnimal.add(radCat);
grpAnimal.add(radDog);
JPanel pnlQuestion = new JPanel(new GridLayout(0, 1));
pnlQuestion.add(lblQuestion);
pnlQuestion.add(radCat);
pnlQuestion.add(radDog);
JButton btnSetCat = new JButton(CAT);
btnSetCat.setActionCommand(CAT);
btnSetCat.addActionListener(this);
JButton btnSetDog = new JButton(DOG);
btnSetDog.setActionCommand(DOG);
btnSetDog.addActionListener(this);
JPanel pnlButtons = new JPanel(new GridLayout(0, 1));
pnlButtons.add(new JLabel("Update your choice of animal"));
pnlButtons.add(btnSetCat);
pnlButtons.add(btnSetDog);
JTabbedPane tabPane = new JTabbedPane();
tabPane.addTab("Buttons", pnlButtons);
tabPane.addTab("Question", pnlQuestion);
add(tabPane, BorderLayout.LINE_START);
setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
}
public void actionPerformed(ActionEvent evt) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
grpAnimal.clearSelection();
if (CAT.equals(evt.getActionCommand())) {
grpAnimal.setSelected(radCat.getModel(), true);
}
else if (DOG.equals(evt.getActionCommand())) {
grpAnimal.setSelected(radDog.getModel(), true);
}
}
});
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("RadioButtonExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new RadioButtonExample();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Comment out the line below to run using standard L&F
setLookAndFeel();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void setLookAndFeel() {
try {
// Set Windows L&F
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
}
catch (Exception e) {
// handle exception
}
}
}
Is there a way to prevent this behavior or even speed it up to make it less noticeable for our users?
You might be able to disable the animation by specifying the swing.disablevistaanimation Java system property:
java -Dswing.disablevistaanimation="true" your-cool-application.jar
In the com.sun.java.swing.plaf.windows.AnimationController class, there is a VISTA_ANIMATION_DISABLED field that is initialized to the swing.disablevistaanimation property. This field determines whether the paintSkin method calls the skin.paintSkinRaw method if animations are disabled or else starts to get into the animations.
It works on my Windows 8.1 laptop with Java 8 (jdk1.8.0_65), so its effect does not seem to be limited to Windows Vista only.

Java Swing button colors [duplicate]

This question already has answers here:
How to set background color of a button in Java GUI?
(7 answers)
Closed 8 years ago.
I am using NET Beans IDE for developing my application in LINUX. I have used synthetica package to generate new look and feel. All is well till now.
Now my next stage is to add colors to buttons when some database status changes.
For example:
In a restaurant i have 2 tables and when 8 people came in to dine and i will create 2 table in my software since the people are unattended i want the buttons to those 2 tables to be green. When the order is processed for any of those tables the button color of the processed table should be changed to orange. When it is under processing it should be flashing color. How to do this in java ? I will take care of database update i just want to know how to change the colors of the buttons and adding flashing technique.
Here is a question and several answers related to flashing a component.
Addendum: You can learn more in the article How to Use Buttons. In particular, you can use setForeground() to change the color of a button's text, but the corresponding setBackground() doesn't read well on some platforms. Using a Border is one alternative; a colored panel, shown below, is another.
package overflow;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class ButtonTest extends JPanel implements ActionListener {
private static final int N = 4;
private static final Random rnd = new Random();
private final Timer timer = new Timer(1000, this);
private final List<ButtonPanel> panels = new ArrayList<ButtonPanel>();
public ButtonTest() {
this.setLayout(new GridLayout(N, N, N, N));
for (int i = 0; i < N * N; i++) {
ButtonPanel bp = new ButtonPanel(i);
panels.add(bp);
this.add(bp);
}
}
#Override
public void actionPerformed(ActionEvent e) {
for (JPanel p : panels) {
p.setBackground(new Color(rnd.nextInt()));
}
}
private static class ButtonPanel extends JPanel {
public ButtonPanel(int i) {
this.setBackground(new Color(rnd.nextInt()));
this.add(new JButton("Button " + String.valueOf(i)));
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame("ButtonTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ButtonTest bt = new ButtonTest();
f.add(bt);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
bt.timer.start();
}
});
}
}

Categories

Resources