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
Related
Hi I have this loop that created buttons for each of the number between an interval and I was wondering how do I access the action listener of these buttons?
////FOR EACH DATE
for (int i=(timeLine.getInterval())[0]; i<(timeLine.getInterval())[1] +1; i++)
{
listPanel.add(new JButton(""+i));
}
Normaly I would do this:
button.addActionListener(new ActionListener()...
but I dont have a name set to any of my buttons because the ammount is indefinite. Thank you:)
You need to write a generic ActionListener that can be used for all the buttons. The ActionListener will get the source of the event and then use information from the button to do process.
For example here is how you can create a simple "calculator panel" by using buttons that have the same functionality:
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(30, 30) );
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()
{
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();
}
});
}
}
You need to assign the new button to temp variable, and you need to be able to use the "amount" in the action:
for (int i=(timeLine.getInterval())[0]; i<(timeLine.getInterval())[1] +1; i++)
{
JButon b = new JButton(""+i);
final int amount = i;
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// do something with amount
aplyAmount(amount);
}
});
listPanel.add(b);
}
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();
}
});
}
}
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.
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.
I'm writing a program in Java where I'm using JTabbedPane. Each tab is associated with a different panel with labels, textfields and a button. I have used GridBagLayout in the panels.
I have added an actionlistener to the button, but when I click it nothing happens.
EDIT: I also have other buttons outside the JTabbedPane which works perfectly fine.
I can see that nothing is happening because I do this:
public void actionPerformed( ActionEvent e ) {
if ( e.getSource() == button ) {
System.out.println("blablabla");
}
and nothing is printed out.
Is there any common problems with using buttons and GridBagLayout/JTabbedPane?
EDIT with SSCCE
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class Hjelp extends JFrame {
private FlowLayout layout;
private JButton button1;
private JButton button2;
private JPanel menu, frontpage;
private JPanel present, previous, something;
public Hjelp() {
layout = new FlowLayout(FlowLayout.CENTER, 10, 20);
setLayout(layout);
setSize(900, 900);
setLocationRelativeTo(null);
setVisible(true);
setPanels();
something = something();
add(something, BorderLayout.CENTER);
something.setVisible(false);
button1 = new JButton("CLICK ME");
add(button1);
buttonListener();
}
private void buttonListener() {
Buttonlistener listener = new Buttonlistener();
button1.addActionListener(listener);
button2.addActionListener(listener);
}
private void setPanels() {
menu = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 0));
frontpage = new JPanel();
previous = frontpage;
present = frontpage;
add(menu);
}
public void visiblePanel() {
previous.setVisible(false);
present.setVisible(true);
}
private JPanel something() {
visiblePanel();
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(1, 1));
JTabbedPane tabbedPane = new JTabbedPane();
JComponent panel1 = tab();
tabbedPane.addTab("Click me", panel1);
tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
panel.add(tabbedPane);
return panel;
}
private JComponent tab() {
JPanel panel = new JPanel(false);
panel.setPreferredSize(new Dimension(870, 300));
panel.setLayout(new GridBagLayout());
GridBagConstraints cs = new GridBagConstraints();
cs.fill = GridBagConstraints.HORIZONTAL;
button2 = new JButton("Click me");
cs.gridx = 1;
cs.gridy = 6;
cs.gridwidth = 1;
panel.add(button2, cs);
return panel;
}
private class Buttonlistener implements ActionListener {
#Override
public void actionPerformed( ActionEvent e ) {
if ( e.getSource() == button1 ) {
present = something;
button1.setVisible(false);
something();
previous = something;
}
else if (e.getSource() == button2) {
System.out.println("Blablabla");
}
}
}
public static void main(String [] args) {
final Hjelp vindu = new Hjelp();
vindu.addWindowListener(
new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
} );
}
}
SOLVED
Solution
You don't need the getSource check at all—your listener is (hopefully) attached to just one button, so if it was invoked, that already means the button was clicked. Remove the check and unconditionally print your string. If you still don't see anything, then you have a problem.
You may not have attached a handler to the actual button, and therefore the event will never get called.
Part 1:
ButtonHandler handler = new ButtonHandler();
button.addActionListener( handler );
Part 2:
public class ButtonHandler implements ActionListener
{
#Override
public void actionPerformed(ActionEvent event) {
}
}
ALSO: Java GUI can be finicky, rather than using "e.getSource() == button" you could try "button..isFocusOwner()"