Clear current FocusOwner (jTextfield) - java

Developing an application in swing, just a little query :-
I want to clear the current focus owner textfield using a button. It is possible to determine whether a textfield is the current focus owner or not using isFocusOwner() but how to clear the textfield which is currently on focus?
Thanks!!!

You might be able use a TextAction. A TextAction has access to the last text component that had focus. So then in the text action you just clear the text in the component. All the logic is fully contained in the one place.
Here is an example that demonstrates the concept of using a TextAction. In this case the number represented by the button is appended to the text field with focus:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.*;
public class NumpadPanel extends JPanel
{
public NumpadPanel()
{
setLayout( new BorderLayout() );
JTextField textField1 = new JTextField(4);
JTextField textField2 = new JTextField(2);
JTextField textField3 = new JTextField(2);
JPanel panel = new JPanel();
panel.add( textField1 );
panel.add( textField2 );
panel.add( textField3 );
add(panel, BorderLayout.PAGE_START);
Action numberAction = new TextAction("")
{
#Override
public void actionPerformed(ActionEvent e)
{
JTextComponent textComponent = getFocusedComponent();
if (textComponent != null)
textComponent.replaceSelection(e.getActionCommand());
}
};
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
add(buttonPanel, BorderLayout.CENTER);
for (int i = 0; i < 10; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( numberAction );
button.setMargin( new Insets(20, 20, 20, 20) );
button.setFocusable( false );
buttonPanel.add( button );
}
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("Numpad Panel");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new NumpadPanel() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
In your case instead of using the replaceSelection() method you would just use the setText() method.

If you want to clear a textfield using the clicking of a button, you have to write the code to clear the textfield in the the ActionListener class's ActionPerformed method. This method is called when the button is pressed. But in order to press the button you have to get the focus from other component to this button. So in the method ActionPerformed you would get false to textField.isFocusOwner().
My suggestion to overcome this problem is:
add focus listeners to these 6 text fields.
declare a variable say lastFocused as type JTextField in initialise it to null in the Class that you are implementing all these.
write the following code to the focusListerners Overridden methods
void focusGained(FocusEvent e){
lastFocused = (JTextField) e.getComponent();
}
void focusLost(FocusEvent e){
lastFocused = null;
}
now in the ActionListener overridden method write the following:
void actionPerformed(ActionEvent e){
if(lastFocused != null){
lastFocused.setText("");
}
}
I feel this should solve your problem.

Related

Individual class for each Action Listener?

My application has 15 different buttons and I've been wondering if it's a good idea to have a individual class for each button listener?
I currently have only one class that handles all buttons using switch/case but it's hard to maintain and read.
I'm not huge fan of using anonymous classes - again because of the readability.
Any suggestions that can help me resolve this issue would be appreciated.
I'm using Java Swing if this matters.
You can use one class but it is not a good dsign because you need to apply a principle of separation of concerns. You want coherance in a class so that the methods are meaningfull and logical according to the business domain your are dealing with. Also in some cases the same action listener can handle many buttons.
Example: assuming I am building a calculator. I know that the behavior of operators is similar when they are clicked on. And so is it with the digits buttons. Therefore I can have some classes, let's say
public class OperationActionListener {
public void actionPerformed(ActionEvent e) {
// Handle what happens when the user click on +, -, * and / buttons
}
}
public class DigitActionListener {
public void actionPerformed(ActionEvent e) {
// Handle what happens when the user click on a digit button
}
}
etc.
Now in my user interface I will add an instance of the same action listener
JButton buttonPlus = new JButton("+")
JButton buttonMinus = new JButton("-");
...
JButton buttonOne = new JButton("1");
JButton buttonTwo = new JButton("2");
...
OperationActionListener operationListener = new OperationActionListener();
DigitActionListener digitListener = new DigitsActionListener();
buttonPlus.addActionListener(operationListener);
buttonMinus.addActionListener(operationListener);
....
buttonOne.addActionListener(digitListener);
buttonTwo.addActionListener(digitListener);
....
Hope this helps.
Here is an example of the same listener being used by multiple buttons:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class CalculatorPanel extends JPanel
{
private JTextField display;
public CalculatorPanel()
{
Action numberAction = new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
// display.setCaretPosition( display.getDocument().getLength() );
display.replaceSelection(e.getActionCommand());
}
};
setLayout( new BorderLayout() );
display = new JTextField();
display.setEditable( false );
display.setHorizontalAlignment(JTextField.RIGHT);
add(display, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
add(buttonPanel, BorderLayout.CENTER);
for (int i = 0; i < 10; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( numberAction );
button.setBorder( new LineBorder(Color.BLACK) );
// button.setPreferredSize( new Dimension(50, 50) );
buttonPanel.add( button );
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke(text), text);
inputMap.put(KeyStroke.getKeyStroke("NUMPAD" + text), text);
button.getActionMap().put(text, numberAction);
}
}
private static void createAndShowUI()
{
UIManager.put("Button.margin", new Insets(10, 10, 10, 10) );
JFrame frame = new JFrame("Calculator Panel");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new CalculatorPanel() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}

How to keep Focus on JTextField while clicking input number buttons?

I am new to GUI stuff and am having trouble with the following problem. I have 3 JTextFields, credit card number, expiration date, and security number. I am able to input information into the fields. I also implemented the focus listener for each button. If I click it, it says gained focus, if I click anywhere else, it loses focus. Under these text fields, I have a number pad (touch screen/mouse click) to enter the numbers. How do I keep focus on that particular text field until ONLY and SPECIFICALLY one of the other two textfields are clicked? The textfield that currently has focus will lose focus once I try to click to input numbers. I don't want this to happen. I searched online and wasn't able to find something specific to my case. Any help or tips would be appreciated.
myJButton.setFocusable(false);
or if a bunch of buttons held in an allMyButtons collection:
for (JButton button: allMyButtons) {
button.setFocusable(false);
}
That's it.
In additions to #Hovercrafts suggestion (+1) you will probably want to extend TextAction for the logic to insert the number into the text field. The TextAction gives you access to the last text field that had focus so the insertion code becomes very generic:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.*;
public class NumpadPanel extends JPanel
{
public NumpadPanel()
{
setLayout( new BorderLayout() );
JTextField textField1 = new JTextField(4);
JTextField textField2 = new JTextField(2);
JTextField textField3 = new JTextField(2);
JPanel panel = new JPanel();
panel.add( textField1 );
panel.add( textField2 );
panel.add( textField3 );
add(panel, BorderLayout.PAGE_START);
Action numberAction = new TextAction("")
{
#Override
public void actionPerformed(ActionEvent e)
{
JTextComponent textComponent = getFocusedComponent();
if (textComponent != null)
textComponent.replaceSelection(e.getActionCommand());
}
};
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
add(buttonPanel, BorderLayout.CENTER);
for (int i = 0; i < 10; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( numberAction );
button.setMargin( new Insets(20, 20, 20, 20) );
button.setFocusable( false );
buttonPanel.add( button );
}
// Optionally auto tab when text field is full
//SizeDocumentFilter sf = new SizeDocumentFilter();
//sf.installFilter(textField1, textField2, textField3);
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("Numpad Panel");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new NumpadPanel() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
You might also want to consider using Text Field Auto Tab so focus moves from text field to text field as the text field becomes full.

jbutton changes text of text field

I am simply trying to make an employee clock. I have a keypad of numbers 0-9 and a text field. I want to be able to click the numbers and the numbers will appear on the text field. This seems so easy but I can't find any answers for it.
I'm using netbeans and I created the design of the Jframe in the Design.
I added action events to all of the buttons.
I'm calling each button like Btn0 (the button with 0 on it, Btn1, etc etc.
You need to retrieve the JButton on which ActionEvent is fired and then append the text retrieved from the JButton to the JTextField. Here is the short Demo:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class EClock extends JFrame
{
JTextField tf;
public void createAndShowGUI()
{
setTitle("Eclock");
Container c = getContentPane();
tf = new JTextField(10);
JPanel cPanel = new JPanel();
JPanel nPanel = new JPanel();
nPanel.setLayout(new BorderLayout());
nPanel.add(tf);
cPanel.setLayout(new GridLayout(4,4));
for (int i =0 ; i < 10 ; i++)
{
JButton button = new JButton(String.valueOf(i));
cPanel.add(button);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
String val = ((JButton)evt.getSource()).getText();
tf.setText(tf.getText()+val);
}
});
}
c.add(cPanel);
c.add(nPanel,BorderLayout.NORTH);
setSize(200,250);
setLocationRelativeTo(null);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
EClock ec = new EClock();
ec.createAndShowGUI();
}
});
}
}
Add action listener on your button first (double click on button in GUI Designer :) ):
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//Set text by calling setText() method for your textfield
textfield.setText("Desired text");
}
});
Regards.
Create an Action that can be shared by all the buttons. Something like:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class ButtonCalculator extends JFrame implements ActionListener
{
private JButton[] buttons;
private JTextField display;
public ButtonCalculator()
{
display = new JTextField();
display.setEditable( false );
display.setHorizontalAlignment(JTextField.RIGHT);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
buttons = new JButton[10];
for (int i = 0; i < buttons.length; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( this );
button.setMnemonic( text.charAt(0) );
button.setBorder( new LineBorder(Color.BLACK) );
buttons[i] = button;
buttonPanel.add( button );
}
getContentPane().add(display, BorderLayout.NORTH);
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
setResizable( false );
}
public void actionPerformed(ActionEvent e)
{
JButton source = (JButton)e.getSource();
display.replaceSelection( source.getActionCommand() );
}
public static void main(String[] args)
{
ButtonCalculator frame = new ButtonCalculator();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
I know nothing of netbeans, however, a search on google gave me this
Netbeans GUI Functionality
it seems to have the data needed, give it a read and no doubt you can figure out what needs to be amended for it to suit your purposes

Dialog that returns an Object

Is it possible to create a JDialog in swing that would return an object when OK button is clicked?
For example the Dialog box has text fields that have components that make up an adress ( street name, country etc.)
When the OK button is clicked an Address object is returned.
Why I thought this to be possible was because of this. But what I want is something like I mentioned above.
Any pointers on how to get this done would be very helpful.
Like the previous people suggested: JOptionPane can help you do what you want. But if you're determined to implement this from scratch, here is an SSCCE that does exactly what you want (well, it returns a String, but it can be easily modified to suit your needs):
import java.awt.Font;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
class MyDialog
{
private JFrame parent;
private JDialog dialog;
private String information;
MyDialog (JFrame parent)
{
this.parent = parent;
}
private JPanel createEditBox ()
{
JPanel panel = new JPanel ();
JLabel dialogtitlelabel = new JLabel ("Enter Info");
panel.add (dialogtitlelabel);
dialogtitlelabel.setFont (new Font ("Arial", Font.BOLD, 20));
final JTextArea informationtxt = new JTextArea ();
informationtxt.setEditable (true);
informationtxt.setLineWrap (true);
informationtxt.setWrapStyleWord (true);
JScrollPane jsp = new JScrollPane (informationtxt);
jsp.setVerticalScrollBarPolicy (ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
jsp.setHorizontalScrollBarPolicy (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jsp.setPreferredSize (new Dimension (180, 120));
panel.add (jsp);
JButton btnok = new JButton ("OK");
panel.add (btnok);
JButton btncancel = new JButton ("Cancel");
panel.add (btncancel);
btnok.addActionListener (new ActionListener ()
{
#Override public void actionPerformed (ActionEvent a)
{
if (informationtxt.getText () == null || informationtxt.getText ().isEmpty ())
{
return;
}
information = informationtxt.getText ();
dialog.dispose ();
}
});
btncancel.addActionListener (new ActionListener ()
{
#Override public void actionPerformed (ActionEvent a)
{
dialog.dispose ();
}
});
return panel;
}
void display ()
{
final int DWIDTH = 200;
final int DHEIGHT = 240;
dialog = new JDialog (parent, "Information", true);
dialog.setSize (DWIDTH, DHEIGHT);
dialog.setResizable (false);
dialog.setDefaultCloseOperation (JDialog.DISPOSE_ON_CLOSE);
dialog.setContentPane (createEditBox ());
dialog.setLocationRelativeTo (parent);
dialog.setVisible (true);
}
String getInformation ()
{
return information;
}
}
public class ReturningDialogTest
{
public static void main (String[] args)
{
SwingUtilities.invokeLater (new Runnable ()
{
public void run ()
{
final JFrame frame = new JFrame ();
frame.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
final JPanel panel = new JPanel ();
JButton btn = new JButton ("show dialog");
panel.add (btn);
final JLabel lab = new JLabel ("");
panel.add (lab);
frame.add (panel);
btn.addActionListener (new ActionListener ()
{
public void actionPerformed (ActionEvent e)
{
MyDialog diag = new MyDialog (frame);
diag.display ();
String info = diag.getInformation ();
lab.setText (info);
frame.pack ();
}
});
frame.setLocationRelativeTo (null);
frame.pack ();
frame.setVisible (true);
}
});
}
}
What you enter in that text-area is displayed on the main window when you press OK, just to prove it works :) .
Put GUI components to hold the address, into a panel. Provide the panel to the dialog. Once the dialog is closed, read the values from the components on the panel to construct the Address object.
Is it possible to create a JDialog in swing that would return an object when OK button is clicked?
this is reason why JOptionPane exist
When the OK button is clicked an Address object is returned.
please see JOptionPane Features

Regarding how to add an something from a text field into a JList

I have a program that needs to take user input (from an input box) and add it to a JList. When I click the Add button on my program however, errors occur.
Heres the code I hoped would work
JButton addButton = new JButton( "<-Add" );
addButton.addActionListener(
new ActionListener() {
public void actionPerformed( ActionEvent event )
{
final String name=inputField.getText();
// prompt user for new philosopher's name
// add new philosopher to model
philosophers.addElement( name );
}
}
);
Edit: Heres all of the code although ive tested this part and i'm confident it works (Except for the listner I tried to add to the text box)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PhilosophersJList extends JFrame {
private DefaultListModel philosophers;
private JList list;
private JTextField inputField;
public PhilosophersJList()
{
super( "Favorite Philosophers" );
// create a DefaultListModel to store philosophers
philosophers = new DefaultListModel();
philosophers.addElement( "Socrates" );
philosophers.addElement( "Plato" );
philosophers.addElement( "Aristotle" );
philosophers.addElement( "St. Thomas Aquinas" );
philosophers.addElement( "Soren Kierkegaard" );
philosophers.addElement( "Immanuel Kant" );
philosophers.addElement( "Friedrich Nietzsche" );
philosophers.addElement( "Hannah Arendt" );
// create a JList for philosophers DefaultListModel
list = new JList( philosophers );
JButton addButton = new JButton( "<-Add" );
addButton.addActionListener(
new ActionListener() {
public void actionPerformed( ActionEvent event )
{
final String name=inputField.getText();
// prompt user for new philosopher's name
// add new philosopher to model
philosophers.addElement( name );
}
}
);
// create JButton for removing selected philosopher
JButton removeButton =
new JButton( "Rem->" );
removeButton.addActionListener(
new ActionListener() {
public void actionPerformed( ActionEvent event )
{
// remove selected philosopher from model
setTitle("Now Removing Contact");
try
{
Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)
}
catch(InterruptedException e)
{
e.printStackTrace();
}
philosophers.removeElement(list.getSelectedValue());
setTitle("My Contacts List");
}
}
);
JTextField inputField=new JTextField();
inputField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
// allow user to select only one philosopher at a time
list.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION );
//Create the text field
// create JButton for adding philosophers
// lay out GUI components
JPanel inputPanel = new JPanel();
inputPanel.add( addButton);
inputPanel.add( removeButton);
inputPanel.setLayout(new BoxLayout(inputPanel,BoxLayout.Y_AXIS));
inputField.setLayout(new FlowLayout());
inputField.setBounds(5, 5, 100, 100);
inputField.setPreferredSize(new Dimension(120,20));
JScrollPane scrollPane=new JScrollPane(list);
scrollPane.setPreferredSize(new Dimension(200,200));
Container container = getContentPane();
add(scrollPane);
container.add( inputPanel);
add( inputField);
container.setLayout(new FlowLayout());
setDefaultCloseOperation( EXIT_ON_CLOSE );
setSize( 500, 250 );
setVisible( true );
} // end PhilosophersJList constructor
// execute application
public static void main( String args[] )
{
new PhilosophersJList();
}
}
You don't initialize the inputField field. The problem is on line 69, where you declare a new local variable named inputField, instead of assigning the field. You need to actually refer to the inputField field.
So instead of
JTextField inputField = new JTextField();
you should write just
inputField = new JTextField();

Categories

Resources