Set keyboard focus - java

I'm currently following a java tutorial on how to create a guessing game GUI App. At one point in the instructions however, it says to Set the keyboard focus to the field; I don't know what this means or how to do it. Any clarification would be greatly appreciated.
here's the exact instruction: Focus the user's attention on thePlayer field:
Set the keyboard focus to the field.
here's my code so far:
public class GOM extends JFrame implements ActionListener, KeyListener
{
Container content = this.getContentPane();
//top
JTextField theGuess = new JTextField(10);
JLabel bankroll = new JLabel("");
//bottom
JButton newplayer = new JButton("New Player");
JButton newnumber = new JButton("New Number");
JTextField thePlayer = new JTextField(20);
//center
JTextArea theoutput = new JTextArea("");
//invisible
String playerName;
int theNumber;
int numTries;
int numGames;
double amtRemaining;
Random randomizer()
{
Random rnd = new Random();
return rnd;
}
JScrollPane scrollArea = new JScrollPane(theoutput);
public GOM()
{
this.setVisible(true);
this.setSize(500,400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Guess O'Matic");
//top panel
JPanel p1 = new JPanel();
p1.add(theGuess);
p1.add(bankroll);
p1.add(new JLabel("Make Your Guess"));
content.add(p1, BorderLayout.NORTH);
//bottom panel
JPanel p2 = new JPanel();
p2.add(newplayer);
p2.add(newnumber);
p2.add(thePlayer);
content.add(p2, BorderLayout.SOUTH);
// finishing touches
content.add(new JLabel(" "), BorderLayout.WEST);
content.add(new JLabel(" "), BorderLayout.EAST);
content.add(scrollArea, BorderLayout.CENTER);
newplayer.addActionListener(this);
newnumber.addActionListener(this);
thePlayer.addKeyListener(this);
theGuess.addKeyListener(this);
newPlayer();
}
public void newPlayer()
{
theoutput.setText(playerName);
theoutput.setEnabled(false);
theGuess.setEnabled(false);
newnumber.setEnabled(false);
newplayer.setEnabled(false);
theGuess.setBackground(Color.WHITE);
thePlayer.setEnabled(true);
thePlayer.setText(playerName);
thePlayer.setBackground(Color.YELLOW);
}
#Override
public void actionPerformed(ActionEvent e)
{
}
#Override
public void keyTyped(KeyEvent e)
{
}
#Override
public void keyPressed(KeyEvent e)
{
}
#Override
public void keyReleased(KeyEvent e)
{
}
}

If you have a GUI with several JTextFields and possibly other text components, the keyboard focus can only be on one of those fields at a time. In other words, if you type, only one of the fields can display the caret and then will usually display the typed in text. When a Swing GUI is displayed then the GUI must decide which text component should have focus, and it uses its focus traversal policy to decide this. The default policy usually will put the focus into the first text field created. You can change this by calling requestFocusInWindow() on the text component that you want to hold the focus.

Related

How do I delete an image inside a JLabel by right clicking my mouse

I'm working on an Animal Project and I want to improve the project with the MouseListener functions, but I cannot find out how to do this specific bit and I've looked everywhere. Here is my code so you get a good idea at what I'm doing.
Main Class
public class Animals {
public static void main(String[] args) {
JFrame application = new JFrame("Animal Project");
GUI graphicalInterface = new GUI();
application.add(graphicalInterface);
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.setLocation(200, 200);
application.pack();
application.setVisible(true);
application.setResizable(false);
}
Sub Class
public class GUI extends JPanel implements ActionListener {
private JButton animalOption = new JButton();
private JButton save = new JButton();
private JButton load = new JButton();
private JButton clear = new JButton();
private JPanel buttonPanel;
private JPanel imagePanel;
private ImageIcon bear;
private ImageIcon tiger;
private ImageIcon lion;
private JLabel imageBlock1;
private JLabel imageBlock2;
private JLabel imageBlock3;
private int choice;
private int count = 1;
private JLabel currImageBlock = null;
GUI() {
Border blackline = BorderFactory.createLineBorder(Color.black);
//create button panel
buttonPanel = new JPanel();
buttonPanel.setPreferredSize(new Dimension(100, 230));
buttonPanel.setOpaque(true);
buttonPanel.setBackground(Color.white);
buttonPanel.setBorder(blackline);
imagePanel = new JPanel(new GridLayout(3, 3));
imagePanel.setPreferredSize(new Dimension(500, 500));
imagePanel.setOpaque(true);
imagePanel.setBackground(Color.white);
imagePanel.setBorder(blackline);
imageBlock1 = new JLabel();
imageBlock1.setPreferredSize(new Dimension(100, 100));
imageBlock1.setOpaque(true);
imageBlock1.setBackground(Color.white);
imageBlock1.setBorder(blackline);
imageBlock2 = new JLabel();
imageBlock2.setPreferredSize(new Dimension(100, 100));
imageBlock2.setOpaque(true);
imageBlock2.setBackground(Color.white);
imageBlock2.setBorder(blackline);
imageBlock3 = new JLabel();
imageBlock3.setPreferredSize(new Dimension(100, 100));
imageBlock3.setOpaque(true);
imageBlock3.setBackground(Color.white);
imageBlock3.setBorder(blackline);
bear = new ImageIcon("Bear.png");
tiger = new ImageIcon("Tiger.png");
lion = new ImageIcon("Lion.png");
animalOption = new JButton();
//add action listener to each button
animalOption.addActionListener(this);
//set button size
animalOption.setPreferredSize(new Dimension(100, 50));
//set text for each button
animalOption.setText("Animal");
animalOption.setToolTipText("press to select your animal");
//add buttons to gui
buttonPanel.add(animalOption);
save = new JButton();
//add action listener to each button
save.addActionListener(this);
//set button size
save.setPreferredSize(new Dimension(100, 50));
//set text for each button
save.setText("Save");
save.setToolTipText("press to save your selection");
//add buttons to gui
buttonPanel.add(save);
load = new JButton();
//add action listener to each button
load.addActionListener(this);
//set button size
load.setPreferredSize(new Dimension(100, 50));
//set text for each button
load.setText("Load");
load.setToolTipText("press to load your selection");
//add buttons to gui
buttonPanel.add(load);
clear = new JButton();
//add action listener to each button
clear.addActionListener(this);
//set button size
clear.setPreferredSize(new Dimension(100, 50));
//set text for each button
clear.setText("Clear");
clear.setToolTipText("press to clear your selection");
//add buttons to gui
buttonPanel.add(clear);
this.add(buttonPanel);
this.add(imagePanel);
imagePanel.add(imageBlock1);
imagePanel.add(imageBlock2);
imagePanel.add(imageBlock3);
}
public void actionPerformed(ActionEvent e) {
if (count == 1) {
currImageBlock = imageBlock1;
} else if (count == 2) {
currImageBlock = imageBlock2;
} else if (count == 3) {
currImageBlock = imageBlock3;
} else if (count > 3 && e.getSource().equals(animalOption)) {
JOptionPane.showMessageDialog(imagePanel, "Your choices have exceeded, please press clear.");
}
if (e.getSource().equals(animalOption) && count < 4) {
choice = selectAnimal();
if (choice == 1) {
currImageBlock.setIcon(bear);
currImageBlock.setToolTipText("This is a bear");
} else if (choice == 2) {
currImageBlock.setIcon(tiger);
currImageBlock.setToolTipText("This is a tiger");
} else if (choice == 3) {
currImageBlock.setIcon(lion);
currImageBlock.setToolTipText("This is a lion");
}
chooseNumber();
count++;
}
if (e.getSource().equals(clear)) {
imageBlock1.setIcon(null);
imageBlock2.setIcon(null);
imageBlock3.setIcon(null);
imageBlock1.revalidate();
imageBlock2.revalidate();
imageBlock3.revalidate();
count = 1;
}
}
static int selectAnimal() {
int animal = 0;
String theAnimal = JOptionPane.showInputDialog("Please enter animal, type 1 for bear, type 2 for tiger, type 3 for lion");
animal = Integer.parseInt(theAnimal);
return animal;
}
And this is what it looks like when I run the code and after I've selected which Animal I want
I have a clear all button where if I click it, it clears all the images in inside the imageBlock Jlabel, however I want to add a feature where if I right click on the specific JLabel the image and all its contents will be deleted inside that specific JLabel. Any help would really be appreciated.
This example code shows how a mouse listener can be used to perform an action (in this case - remove) on an image set as icon within a JLabel. Note a MouseAdapter is used in the code but a MouseListener interface can be implemented with similar result.
Other ways of performing this function:
Select an image label and click a button to remove it.
Open a context or pop-up menu with remove image menu option - when the image label is right-clicked upon.
The example code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ImageLabelAction {
private JLabel imageBlock;
private ImageIcon koala = new ImageIcon("koala.jpg");
public static void main(String [] args) {
new ImageLabelAction().gui();
}
private void gui() {
JFrame frame = new JFrame();
frame.setTitle("Frame with Image Label");
imageBlock = new JLabel();
imageBlock.setPreferredSize(new Dimension(100, 100));
imageBlock.setOpaque(true);
imageBlock.setBackground(Color.white);
imageBlock.setBorder(BorderFactory.createLineBorder(Color.black));
imageBlock.setIcon(koala);
imageBlock.addMouseListener(new PictureRemoveListener());
frame.add(imageBlock);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(250, 250);
frame.setVisible(true);
}
private class PictureRemoveListener extends MouseAdapter {
#Override public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
imageBlock.setIcon(null);
}
}
}
}
You could set a mouse listener to just move it way out of the frame when right clicked. Or you can make a boolean if mouse is clicked set true and only show that object if the boolean is true, so where you set the image from the file only run that code if right mouse button hasn't been clicked
Something like the following pseudo code:
imageBlock1.addMouseListener(new MouseAdapter() {
public void mouseClicked (MouseEvent e) {
// use flags to figure out if it is right mouse click
imageBlock1.setIcon(null);
}
});
Do this for imageBlock2, 3, 4 etc.
It has been a while but something along those lines could do what you are asking.

JButton not responsive - have to click twice

I created a GUI using java swing and in a specific situation, the JButton is unresponsive and I have to click it twice. On the click, it takes the info in the textArea and sends it to a TextParser class to be parsed. If I type more stuff in the area after, and click the evaluateButton, it doesn't respond and I have to click it again to work. Does anyone know if this is a known bug or how I can fix this?
The code for the class is as follows.
/**
* Add the components to the GUI.
* #param pane - the pane for the GUI
*/
public static void addComponentsToPane(Container pane) {
pane.setLayout(new BorderLayout());
JPanel instructionsPanel = new JPanel();
JLabel instructions = new JLabel("Enter the email text below");
instructionsPanel.setBackground(Color.LIGHT_GRAY);
instructionsPanel.add(instructions);
pane.add(instructionsPanel, BorderLayout.NORTH);
JPanel textAreaPanel = new JPanel();
textAreaPanel.setBackground(Color.LIGHT_GRAY);
final JTextArea textArea = new JTextArea();
textArea.setBackground(Color.WHITE);
textArea.setMinimumSize(new Dimension(400,350));
textArea.setMaximumSize(new Dimension(400,350));
textArea.setPreferredSize(new Dimension(400,350));
textArea.setLineWrap(true);
Border border = BorderFactory.createLineBorder(Color.BLACK);
textArea.setBorder(border);
textArea.setMinimumSize(new Dimension(500, 200));
textArea.setFont(new Font("Serif", Font.PLAIN, 16));
textAreaPanel.add(textArea);
pane.add(textAreaPanel, BorderLayout.CENTER);
JPanel scoringPanel = new JPanel();
JButton evaluateButton = new JButton("Evaluate Email");
final JLabel scoreLabel = new JLabel("");
JButton uploadFileBtn = new JButton("Upload File");
JButton importTermsBtn = new JButton("Import Terms");
scoringPanel.add(evaluateButton);
scoringPanel.add(uploadFileBtn);
scoringPanel.add(importTermsBtn);
scoringPanel.add(scoreLabel);
pane.add(scoringPanel, BorderLayout.SOUTH);
evaluateButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
try {
String email = textArea.getText();
TextParser textParser = new TextParser(email);
double score = textParser.parse();
scoreLabel.setText(score+"");
} catch (Exception ex) {
System.out.println(ex);
}
}
});
uploadFileBtn.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
scoreLabel.setText("Feature not yet available.");
}
});
importTermsBtn.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
DatabaseInput d = new DatabaseInput();
d.main(null);
}
});
}
/**
* Create the GUI and show it.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("EmailGUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setLocationRelativeTo(null);
frame.setPreferredSize(new Dimension(500,500));
frame.setTitle("Email Text Input");
frame.setResizable(true);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize(screenSize.width, screenSize.height);
//Set up the content pane.
addComponentsToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
My main method just calls createAndShowGUI(). I am new to StackOverflow so if I need to give more or less information in my post please let me know!
As Reimeus and Jason C said in the comments, I should have been using ActionListener which works perfectly.

Java Swing Components Drawing Over Multiple Panels

I'm having an issue that I've been trying to solve all day. I have two panels inside a frame and in one panel I've added components. The components, however, seem to have an equal hierarchy value as the panel and as such treat the Frame as the parent instead, ignoring where the panels are located. Basically the components are added to one panel but display on top of both across the whole frame. (Unfortunately I can't post a picture at this time, please up vote the question to allow me to if needed). What is causing this and how can I fix it?
The relevant code:
JFrame arranFrame = new JFrame("Edit Arrangement");
arranFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel grid = new JPanel();
JPanel tools = new JPanel();
grid.setSize(700, 600);
tools.setSize(200, 600);
JLabel widthLabel = new JLabel("Width");
JLabel depthLabel = new JLabel("Depth");
JLabel columnLabel = new JLabel("Columns");
final JTextField rowWidthInput = new JTextField(30);
final JTextField rowsInput = new JTextField(30);
final JTextField columnInput = new JTextField(30);
rowWidthInput.setSize(40, 30);
rowsInput.setSize(40, 30);
columnInput.setSize(40, 30);
rowWidthInput.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
chartWidth = Integer.parseInt(rowWidthInput.getText());
}
});
rowsInput.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
chartRows = Integer.parseInt(rowsInput.getText());
}
});
columnInput.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
chartColumns = Integer.parseInt(columnInput.getText());
}
});
//Enter button for grid modifying creation and setup
JButton enterButton = new JButton("Enter");
enterButton.setSize(180, 50);
enterButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
chartWidth = Integer.parseInt(rowWidthInput.getText());
chartRows = Integer.parseInt(rowsInput.getText());
chartColumns = Integer.parseInt(columnInput.getText());
}
});
//Save Arrangement button creation and setup
JButton saveButton = new JButton("Save Arrangement");
saveButton.setSize(180, 50);
saveButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
SaveArrangement(userDocuments + "\\TSA Seating Chart\\Arrangements\\Period" + period + ".txt");
}
});
tools.setBackground(Color.RED); //Temp for visualization where the panes are
tools.add(widthLabel);
tools.add(rowWidthInput);
tools.add(depthLabel);
tools.add(rowsInput);
tools.add(columnLabel);
tools.add(columnInput);
tools.add(enterButton);
tools.add(saveButton);
arranFrame.getContentPane().add(grid);
arranFrame.getContentPane().add(tools);
//Finalize the GUI
arranFrame.pack(); //Pack all the content together
arranFrame.setSize(900, 600); //Set the size of the window
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
arranFrame.setLocation(dim.width/2-arranFrame.getSize().width/2, dim.height/2-arranFrame.getSize().height/2);
arranFrame.setVisible(true); //Display the seatingFrame

JFrame crashes when trying to replace a panel with another panel

I have a JFrame which is initialized as follows:
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(PREFERRED_SIZE);
setTitle("Game Set");
setLayout(new BorderLayout());
background = new JLabel(new ImageIcon("images/gameSetBackground.jpg"));
background.setPreferredSize(PREFERRED_SIZE);
add(background);
loginPane = new LoginPane();
background.setLayout(new GridBagLayout());
loginPane.setOpaque(false);
background.add(loginPane, constraints);
pack();
setVisible(true);
I did it this way because it let me set the background to the jpg I specify. Now I have the loginPane() class as follows:
public class LoginPane extends JPanel {
JLabel label = new JLabel("Login");
JLabel secondLabel = new JLabel("If you don't have a profile, click below to create one!");
JTextField userName;
JPasswordField password;
public LoginPane() {
setLayout(new GridBagLayout());
userName = new JTextField(20);
password = new JPasswordField(20);
constraints.insets = new Insets(2, 2, 2, 2);
constraints.gridx = 0;
constraints.gridy = 0;
add(label, constraints);
// etc add all of them the same way
constraints.gridy = 3;
add(secondLabel, constraints);
userName.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
password.requestFocus();
}
});
password.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (userName.getText().equals("Mike")) {
}
}
});
}
}
What I want to happen is that when I hit enter after a username and password has been entered, I will check if that is a valid username/password pair. After that I want to remove everything here and display a different JPanel. Inside the password.ActionListener, I tried the following:
loginPane.removeAll();
background.removeAll();
Those were two separate cases, but both cause the JFrame to crash, the TextFields become unresponsive and I have to exit out. What am I doing wrong?
"JFrame crashes when trying to replace a panel with another panel"
Simple/and correct solution would be to use a CardLayout to switch between panels. See more at How to use CardLayout and see a simple example here.
The CardLayout has methods like show() to to show a certain panel by name, next() to show the next panel, and previous() to show the previous panel. This is preferred way, over removing and adding panels.

Adding ScrollPane to JTextArea

I am working on a project for my college course. I was just wondering if anyone knew how to add a scrollBar to a JTextArea. At present I have the GUI laid out correctly, the only thing missing is the scroll bar.
This is what the GUI looks like. As you can see on the second TextArea I would like to add the Scrollbar.
This is my code where I create the pane. But nothing seems to happen... t2 is the JTextArea I want to add it to.
scroll = new JScrollPane(t2);
scroll.setBounds(10,60,780,500);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
Any help would be great, thanks!
The Scroll Bar comes when your text goes beyond the bounds of your view area. Don't use Absolute Positioning, for such a small talk at hand, always prefer Layout Managers, do read the first para of the first link, to know the advantage of using a Layout Manager.
What you simply need to do is use this thingy :
JTextArea msgArea = new JTextArea(10, 10);
msgArea.setWrapStyleWord(true);
msgArea.setLineWrap(true);
JScrollPane msgScroller = new JScrollPane();
msgScroller.setBorder(
BorderFactory.createTitledBorder("Messages"));
msgScroller.setViewportView(msgArea);
panelObject.add(msgScroller);
Here is a small program for your understanding :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JTextAreaScroller
{
private JTextArea msgArea;
private JScrollPane msgScroller;
private JTextArea logArea;
private JScrollPane logScroller;
private JButton sendButton;
private JButton terminateButton;
private Timer timer;
private int counter = 0;
private String[] messages = {
"Hello there\n",
"How you doing ?\n",
"This is a very long text that might won't fit in a single line :-)\n",
"Okay just to occupy more space, it's another line.\n",
"Don't read too much of the messages, instead work on the solution.\n",
"Byee byee :-)\n",
"Cheers\n"
};
private ActionListener timerAction = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (counter < messages.length)
msgArea.append(messages[counter++]);
else
counter = 0;
}
};
private void displayGUI()
{
JFrame frame = new JFrame("Chat Messenger Dummy");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(0, 1, 5, 5));
logArea = new JTextArea(10, 10);
logArea.setWrapStyleWord(true);
logArea.setLineWrap(true);
logScroller = new JScrollPane();
logScroller.setBorder(
BorderFactory.createTitledBorder("Chat Log"));
logScroller.setViewportView(logArea);
msgArea = new JTextArea(10, 10);
msgArea.setWrapStyleWord(true);
msgArea.setLineWrap(true);
msgScroller = new JScrollPane();
msgScroller.setBorder(
BorderFactory.createTitledBorder("Messages"));
msgScroller.setViewportView(msgArea);
centerPanel.add(logScroller);
centerPanel.add(msgScroller);
JPanel bottomPanel = new JPanel();
terminateButton = new JButton("Terminate Session");
terminateButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (timer.isRunning())
timer.stop();
else
timer.start();
}
});
sendButton = new JButton("Send");
bottomPanel.add(terminateButton);
bottomPanel.add(sendButton);
contentPane.add(centerPanel, BorderLayout.CENTER);
contentPane.add(bottomPanel, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, timerAction);
timer.start();
}
public static void main(String... args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new JTextAreaScroller().displayGUI();
}
});
}
}
Here is the outcome of the same :
The scroll bar by default will only be shown when the content overfills the available viewable area
You can change this via the JScrollPane#setVerticalScrollBarPolicy method, passing it ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS

Categories