How do I use requestFocus in a Java JFrame GUI? - java

I am given an assignment but I am totally new to Java (I have been programming in C++ and Python for two years).
So we are doing GUI and basically we extended JFrame and added a couple fields.
Say we have a field named "Text 1" and "Text 2". When user presses enter with the cursor in Text 1, move the focus to Text 2. I tried to add
private JTextField textfield1() {
textfield1 = new JTextField();
textfield1.setPreferredSize(new Dimension(200, 20));
textfield1.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
textfield1text = textfield1.getText().trim();
textfield1.setText(textfield1text);
System.out.println(textfield1text);
textfield1.requestFocus();
}
});
return textfield1;
}
But that doesn't work at all.
I noticed that requestFocus is not recommended, and instead one should use requestFocusWindows. But I tried that too. Upon some readings it seems like I have to do keyboard action and listener? But my teacher said it only requires 1 line...

Well, you have textfield1.requestFocus(), but your description would imply you need textfield2.requestFocus(). (that's 2).

Another option might be to use:
textField1.transferFocus();
This way you don't need to know the name of the next component on the form.

Related

How to detect when a user presses a key outside of the app [duplicate]

This question already has answers here:
Java - checking if parseInt throws exception
(8 answers)
Closed 1 year ago.
So I tried to look a bit in forums and StackOverflow but nothing worked for me I need when enter is pressed to stop my code this is my code `
JFrame f;
JTextField I;
// JButton
JToggleButton b;
// label to display text
JLabel l;
f = new JFrame("AutoClicker");
i = new JTextField("100");
// create a label to display text
l = new JLabel("clicks/seconds");
// create a new buttons
b = new JToggleButton("Start");
// create a panel to add buttons
JPanel p = new JPanel();
// add buttons and textfield to panel
p.add(b);
p.add(i);
p.add(l);
// setbackground of panel
p.setBackground(Color.red);
// add panel to frame
f.add(p);
// set the size of frame
f.setSize(280, 80);
f.setVisible(true);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int jml = Integer.parseInt(i.getText());
if(jml < 50)
{
jml = 50;
}
AutoClicker(jml);
}
});
}
static void AutoClicker(int jml)
{
while(true)
{
try{
Robot r = new Robot();
int button = InputEvent.BUTTON1_DOWN_MASK;
r.mousePress(button);
Thread.sleep(jml);
r.mouseRelease(button);
Thread.sleep(jml);
}
catch(Exception e){
e.printStackTrace();
System.out.println("not good");
}
}
}
}`
I tried to add a KeyListener but it did not work.
I don't understand why it doesn't work so if you can just help me know why it doesn't work it would be much apreciated.
KeyListener isn't going to solve the problem of the fact that you are simply not handling the potential of Integer.parseInt to throw an exception - I mean, how can it convert "" or "This is not a number" to an int. In those cases it throws an exception
The JavaDocs clearly state
Throws:NumberFormatException - if the string does not contain a
parsable integer.
Go back and have a look at the original error you were getting from your previous question on this exact topic
java.lang.NumberFormatException: For input string: "Enter"
It's telling you exactly what the problem is - the text "Enter" can not be converted to an int value.
YOU have to handle this possibility. No offence, but this is honestly basic Java 101. See Catching and Handling Exceptions
Another option which "might" help is to use a formatted text field
You also don't seem to have a firm grip on the concept of what a "event driven environment" is or what the potential risk of what doing something like while (true) will do if executed within the context of the Event Dispatching Thread. This makes me think you've got yourself in over all head.
You're going to want to learn about Concurrency in Swing as AutoClicker should never be called within the context of the Event Dispatching Thread, which is going to lead you another area of complexity, concurrency and all the joys that brings.
Updated
Wow, you changed the title. Maybe a better description of the problem you're trying to solve would have a gotten a better answer. In short, you can't, not natively in Java anyway. The only way you can detect keyboard input out side of the app is using native integration, JNA/JNI. Plenty of examples about, for example

Use result from if statement in another if statement [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am writing a quiz app, where you get marks as you answer the correct questions and your score increases, and I have to use if statements. Please does any one know how to use a value in an if statement in another if statement! I'm kinda confused about it and its hooking me up at work here....Thanks for the help!... here is a little code example;
int x = 3;
String xy = Integer.toString(x);
int y = 0;
String yy = Integer.toString(y);
JButton one = new JButton ("Quest 1");
one.addActionListener (new ActionListener (){
public void actionPerformed(ActionEvent p) {
JFrame ex = new JFrame ();
ex.setTitle("Question 1);
ex.setSize(400, 400);
ex.setLayout(new FlowLayout());
ex.setBackground(Color.WHITE);
JLabel ey = new JLabel ("What is the capital of Japan?);
Font tan = new Font ("Script MT Bold", Font.BOLD, 18);
ey.setFont(tan);
ey.setForeground(Color.BLACK);
ex.add(ey, BorderLayout.NORTH);
JButton answ = new JButton("submit");
JTextField g = new JTextField (10);
g.setFont(tan);
String ans = "Tokyo";
String merit = "Correct";
String flop = "wrong";
String mer = merit + ans;
String flip = flop + ans;
answ.addActionListener(new ActionListener(){
public void actionPerformed (ActionEvent p) {
if (g.getText.equals("Tokyo") {
JOptionPane.showMessageDialog(null, mer);
one.setText(xy);
}
else {
JOptionPane.showMessageDialog(null,flip);
one.setText(yy);
}
//In my next Action Listener, I would love to
//pick the score from the previous listener....and add to the next score....
//So that we have something like ....
//x(updated from previous listener) + x
ex.add(g, BorderLayout.SOUTH);
}
});
}
});
The only problem I can guess at in the code supplied is that you're testing if a JTextField's text contains a specific String, "Tokyo" in your GUI creational code. This is code that runs at GUI creation and before the user has had any chance to enter data. To fix this, the if test should be within some listener, perhaps a JButton's ActionListener. Otherwise I have no idea what you mean by if within an if.
Edit
Regarding your new information:
I am writing a quiz app, where you get marks as you answer the correct questions and your score increases, and I have to use if statements.
You need to completely re-design your code as you're hard coding your code logic within the GUI, making for a very rigid, huge, and difficult to enhance program (as you're finding out) since the code logic must change as the state of the program changes.
Instead you should split out your program logic, the "model" from the GUI, the "view", and try to create them and test them independently, something similar to (or equal to) a "Model-View-Controller" or "MVC" program design. Start with the model, the "guts" of the program and create your non-GUI Question class, one with instance fields, methods, and any other supporting classes. Once this has been tested and debugged, then try to create a GUI or view class that can use this model and display its state. You might also want to create a "Controller" class with listeners that help connect the view to the model.
For example, if your quiz is to be a multiple-choice type of program, then consider:
A Question class that contains the question String, possible answer Strings and the correct answer String.
Give it a public boolean test(String testString) that returns true if the correct answer String is passed into it.
Allow the Question class to randomize the order of the possible answer Strings, likely held in an ArrayList.
Then create a Quiz class that holds an ArrayList of Questions.
Then create a GUI to display these.
I generally create GUI's that are geared to create JPanels, not JFrames for increased flexibility and then create the JFrame when needed.
Create a QuestionPanel that displays the question String and the randomized possible answer Strings.
Display the possible answers as JRadioButtons with a ButtonGroup to limit the selection to one.
etc....
You'll also want a class to read from a text file data for each question, and load that data into the Quiz class.
You'll also want a mechanism to grade.
Please make all required variables as class level variables instead of declaring it in actionlistner method. Class level variables will be visible in all methods so no need to pass those. Declare score variable as class level.
public class ClassTest {
int score=0;
public void acgionlistner1(Event ev)
{
if(ans.equals(userinput))
{
score++;
}
}
public void acgionlistner2(Event ev)
{
if(ans.equals(userinput))
{
score++;
}
}
.
.

Java: JCheckBox won't stay checked with ItemListener

Ok, I'm new to listeners (still learning the language), and this is my first full-scale attempt to implement them (ie more than just a practice problem in a textbook).
So far, everything is working fine except one big bug: the checkboxes don't stay checked. The ItemListener I assign them runs perfectly (I have a JOptionPane set up to trigger to let me know if it's working or not), but the box itself doesn't stay checked.
I went even further and added conditional logic for if it's state is checked versus unchecked, and found that when I click the box BOTH states get triggered. So I get both JOptionPane popups, the one with the message for if the box is checked and the one for if the box isn't checked.
I'm including my code here. What am I doing wrong?
PS. You'll notice that the code has conditional logic to either add a radio button or a checkbox. When the program finally runs, this component is generated in multiple locations in both formats. The radio button works fine, it's the checkbox ones that I'm having the above issue with.
CODE THAT CREATES THE CHECKBOXES AND ASSIGNS THE LISTENERS:
public OtherField(int voteFor){
this.voteFor = voteFor;
otherPanel = new JPanel();
otherPanel.setLayout(new GridLayout(1, 3));
otherField = new JTextField(10);
otherField.setHorizontalAlignment(SwingConstants.CENTER);
JLabel otherLabel;
otherLabel = new JLabel("Other", SwingConstants.CENTER);
otherRadio = new JRadioButton("", false);
otherRadio.setHorizontalAlignment(SwingConstants.CENTER);
otherRadio.addActionListener(new OtherFieldRadioListener());
otherCheckBox = new JCheckBox("");
otherCheckBox.setHorizontalAlignment(SwingConstants.CENTER);
otherCheckBox.addItemListener(new OtherFieldCheckBoxListener());
otherPanel.add(otherLabel);
otherPanel.add(otherField);
if(voteFor == 1){
otherPanel.add(otherRadio);
}else{
otherPanel.add(otherCheckBox);
}
}
LISTENER CODE (it's a private class in the same class as the code above):
private class OtherFieldCheckBoxListener implements ItemListener{
public void itemStateChanged(ItemEvent e){
String name = otherField.getText();
if(e.getStateChange() == ItemEvent.SELECTED){
JOptionPane.showMessageDialog(null, name);
}else{
JOptionPane.showMessageDialog(null, "Not Selected");
}
}
}
First thing I would try is to set the checkbox either to true or false when you initialize it, i.e
otherCheckBox.setSelected(false)
If this does not work I would check whether OtherField gets called from somewhere else everytime the checkbox is selected and thus the components are redrawn/ the selection is reset (use the debugger and set a breakpoint at the beginning of OtherFields)

Refreshing display of a text panel in a GUI

I'm having more "I'm hopeless at programming" problems.
I have a piece of code which uses StringBuilder to display elements of an array in a text panel of a GUI when the program starts. Here's the StringBuilder code:
// memory tab
StringBuilder mList = new StringBuilder();
memLocList = new Memory[MEM_LOCATIONS];
mem = new Memory();
for (int i = 0; i < memLocList.length; i++) {
memLocList[i] = mem;
memLocList[i].setOpCode(00);
mList.append(String.format("%10s %04x %10s %6s", "Address: ", i,
"Value: ", memLocList[i].getOpCode()));
mList.append("\n");
}
JComponent memTab = makeTextPanel(mList.toString());
tabs.addTab("Memory", new JScrollPane(memTab));
}
protected JComponent makeTextPanel(String t) {
text = t;
JPanel panel = new JPanel(false);
JTextPane filler = new JTextPane();
filler.setFont(new Font("Courier", Font.PLAIN, 14));
filler.setText(text);
filler.setAlignmentX(LEFT_ALIGNMENT);
panel.setLayout(new GridLayout(1, 1));
panel.add(filler);
return panel;
}
The GUI also has a text entry panel where a String of hex values can be entered.
On clicking a button, the user is prompted for another value, which corresponds to the position in the array where the first hex value should be inserted.
Once these values have been entered, I'd like the display to be updated / refreshed to reflect this but am unsure of how to go about it.
I found this question here, which is similar but I'm not sure if implementing Observer/Observable pattern is the right way to proceed, and even if it is, how I'd go about it:
Best Way to Constantly Update GUI Elements
My initial approach was to add an "updateDisplay()" method, which I could call after processing the button click and re-call the makeTextPanel method:
public void updateDisplay() {
makeTextPanel(text);
}
I thought this might refresh it but it has no effect of the display.
Any help appreciated.
You hold your array in a model class, and you allow other classes to "listen" to this by giving this class a SwingPropertyChangeSupport object as well as an addPropertyChangeListener(...) method. Then give the array a setXXX(...) method, and in that method fire the SwingPropertyChangeSupport object after updating the array. There are examples of just this sort of thing on this site, some written by me.
For example: here, here, here, ...
By the way, I'm not surprised that your call to makeTextPanel(text) doesn't work. It creates a JPanel, but you don't appear to do anything with the JPanel that is returned from the method. But nor should you. I don't think that creating new JPanels is the solution you want, but rather updating the Strings displayed by a component of some sort such as a JList or JTextArea using the listener framework that I've described above.
If any of this is confusing, please ask for clarification.

Example text in JTextField

I am looking for a way to put example text into a swing JTextField and have it grayed out. The example text should then disappear as soon as any thing is entered into that text field. Some what similar to what stackoverflow does when a user is posting a question with the title field.
I would like it if it was already a extended implementation of JTextField so that I can just drop it in as a simple replacement. Anything from swingx would work. I guess if there is not an easy way to do this my option will probably be to override the paint method of JTextField do something that way maybe.
Thanks
The Text Prompt class provides the required functionality without using a custom JTextField.
It allows you to specify a prompt that is displayed when the text field is empty. As soon as you type text the prompt is removed.
The prompt is actually a JLabel so you can customize the font, style, colour, transparency etc..:
JTextField tf7 = new JTextField(10);
TextPrompt tp7 = new TextPrompt("First Name", tf7);
tp7.setForeground( Color.RED );
Some examples of customizing the look of the prompt:
If you can use external librairies, the Swing components from Jide software have what you are looking for; it's called LabeledTextField (javadoc) and it's part of the JIDE Common Layer (Open Source Project) - which is free. It's doing what mklhmnn suggested.
How about initialize the text field with default text and give it a focus listener such that when focus is gained, if the text .equals the default text, call selectAll() on the JTextField.
Rather than overriding, put a value in the field and add a KeyListener that would remove the value when a key stroke is registered. Maybe also have it change the foreground.
You could wrap this up into your own custom JTextField class that would take the default text in a constructor.
private JLabel l;
JPromptTextField(String prompt) {
l = new JLabel(prompt, SwingConstants.CENTER);
l.setForeground(Color.GRAY);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (this.getText().length() == 0) {
// Reshape the label if needed, then paint
final Rectangle mine = this.getBounds();
final Rectangle its = l.getBounds();
boolean resized = (mine.width != its.width) || (mine.height != its.height);
boolean moved = (mine.x != its.x) || (mine.y != its.y);
if (resized || moved)
l.setBounds(mine);
l.paint(g);
}
}
You can't do that with a plain text field, but you can put a disabled JLabel on top of the JTextField and hide it if the text field gets the focus.
Do it like this:
Define the string with the initial text you like and set up your TextField:
String initialText = "Enter your initial text here";
jTextField1.setText(initialText);
Add a Focus Listener to your TextField, which selects the entire contents of the TextField if it still has the initial value. Anything you may type in will replace the entire contents, since it is selected.
jTextField1.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
if (jTextField1.getText().equals(initialText)) {
jTextField1.selectAll();
}
}
});

Categories