I have multiple text fields and buttons. When a text field is selected, text should be added to it when a button is pressed but nothing is inserted with bellow code. what i have missed.
thanks for your help.
public class ButtonExample_Extended extends JFrame implements ActionListener {
public JPanel createContentPane (){
buttonPanel = new JPanel();
buttonPanel.setLayout(null);
buttonPanel.setLocation(10, 50);
buttonPanel.setSize(1370, 770);
totalGUI.add(buttonPanel);
B9 = new JButton("9");
B9.setLocation(1190, 570);
B9.setSize(50, 50);
B9.addActionListener(this);
buttonPanel.add(B9);
JPasswordField passwordField = new JPasswordField(20);
passwordField.setLocation(900,565);
passwordField.setSize(120,30);
buttonPanel.add(passwordField);
}
private JTextComponent selectedTextField;
// TextFields onFocus event
private void a33FocusGained(java.awt.event.FocusEvent evt) {
selectedTextField = (JTextComponent) evt.getSource();
}
// action for button
public void actionPerformed (ActionEvent evt) {
if (evt.getSource() == B9)
selectedTextField.setText( selectedTextField.getText() + "9" );
}
}
with above code i expected to insert 9 to textPasswordField but it doesn't.
Are you sure that
private void a33FocusGained(java.awt.event.FocusEvent evt) {
selectedTextField = (JTextComponent) evt.getSource();
}
is ever called? I guess your class should implement FocusListener and add something like
passwordField.addFocusListener(this);
#Override
public void focusGained(FocusEvent e) {
selectedTextField = (JTextComponent) e.getSource();
}
#Override
public void focusLost(FocusEvent e) {
selectedTextField = null;
}
This is a sample code of what you should do (if I understood you correctly), note that at first you need to set cursor to the password field and after that the button will work, however you can see the bad side of this approach in the focusLost method
public class Snippet implements ActionListener, FocusListener {
public JFrame totalGUI = new JFrame();
private JPanel buttonPanel;
private JButton B9;
public Snippet() {
createContentPane();
}
public void createContentPane() {
buttonPanel = new JPanel(new GridBagLayout());
B9 = new JButton("9");
B9.addActionListener(this);
buttonPanel.add(B9);
JPasswordField passwordField = new JPasswordField(20);
passwordField.setSize(120, 30);
passwordField.addFocusListener(this);
buttonPanel.add(passwordField);
totalGUI.getContentPane().add(buttonPanel);
totalGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
totalGUI.pack();
}
private JTextComponent selectedTextField;
#Override
public void actionPerformed(ActionEvent evt) {
if (evt.getSource() == B9 && selectedTextField != null)
selectedTextField.setText(selectedTextField.getText() + "9");
}
public static void main(String[] args) {
new Snippet().totalGUI.setVisible(true);
}
#Override
public void focusGained(FocusEvent e) {
if(e.getSource() instanceof JTextComponent)
selectedTextField = (JTextComponent) e.getSource();
}
#Override
public void focusLost(FocusEvent e) {
// when you push the button the text field will lose focus
// selectedTextField = null;
}
}
Don't use a FocusListener and ActionListener together. This assumes that events will be fired in a certain order, that is first the focusGained and then the actionPerformed. Swing provides no guarantees about the order of the events.
Instead you can extend TextAction. TextAction is a special Action used be Swing components because it tracks the last component that had focus. For example to create an Action that selects all the text you can do:
class SelectAll extends TextAction
{
public SelectAll()
{
super("Select All");
}
public void actionPerformed(ActionEvent e)
{
JTextComponent component = getFocusedComponent();
component.selectAll();
component.requestFocusInWindow();
}
}
Then to use the Action you would do:
b9.addActionListener( new SelectAll() );
Related
I have a JDialog with two JTextFields, one ButtonGroup with two RadioButtons and an OK-Button. The button has to be disabled until the TextFields are filled and at least one of the RadioButtons clicked. I'm not sure how to do this.
It works for with the JTextFields using this code:
public class Test {
public static void main(String... args) {
ButtonTest.show();
}
}
class ButtonTest {
private ButtonTest() {
JFrame frame = new JFrame("Button Test");
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(true);
JPanel mainPanel = new JPanel(new GridLayout(4, 1));
JTextField field1 = new JTextField(20);
JTextField field2 = new JTextField(20);
JLabel text = new JLabel();
JButton printButton = new JButton("Print");
printButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
text.setText(field1.getText() + " - " + field2.getText());
}
});
printButton.setEnabled(!field1.getText().isEmpty() && !field2.getText().isEmpty());
for (JComponent c : Arrays.asList(field1, field2, text, printButton)) {
mainPanel.add(c);
}
setDocumentListener(field1, field2, printButton);
setDocumentListener(field2, field1, printButton);
frame.add(mainPanel);
frame.pack();
frame.setVisible(true);
}
private void setDocumentListener(JTextField field, JTextField other, JButton button) {
field.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
changed();
}
#Override
public void insertUpdate(DocumentEvent e) {
changed();
}
#Override
public void changedUpdate(DocumentEvent e) {
changed();
}
private void changed() {
setButtonStatus(button, field.getText(), other.getText());
}
});
}
private void setButtonStatus(JButton button, String field1, String field2) {
button.setEnabled(!field1.isEmpty() && !field2.isEmpty());
}
public static void show() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ButtonTest();
}
});
}
}
But what about the RadioButtons? I guess I have to somehow implement an ItemListener?
Greetings
You need two tests:
Does the JTextField contain non-whitespace text, tested like so, !textField.getText().trim().isEmpty(), and
Is one JRadioButton selected, which can be tested by seeing if the ButtonGroup contains a non-null ButtonModel selection via buttonGroup.getSelection() != null
Combined, it could look something like:
private void testToActivateButton() {
boolean value = !textField.getText().trim().isEmpty() && buttonGroup.getSelection() != null;
submitButton.setEnabled(value);
}
Then simply call the above method in ActionListeners added to the JRadioButtons and your JTextField's DocumentListener. For example:
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class ActivateButton extends JPanel {
private static final String[] RADIO_TEXTS = {"Hello", "Goodbye"};
private ButtonGroup buttonGroup = new ButtonGroup();
private JTextField textField = new JTextField(10);
private JButton submitButton = new JButton("Submit");
public ActivateButton() {
textField.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
testToActivateButton();
}
#Override
public void insertUpdate(DocumentEvent e) {
testToActivateButton();
}
#Override
public void changedUpdate(DocumentEvent e) {
testToActivateButton();
}
});
for (String radioText : RADIO_TEXTS) {
JRadioButton radioButton = new JRadioButton(radioText);
radioButton.addActionListener(e -> testToActivateButton());
buttonGroup.add(radioButton);
add(radioButton);
}
submitButton.setEnabled(false);
add(textField);
add(submitButton);
}
private void testToActivateButton() {
boolean value = !textField.getText().trim().isEmpty() && buttonGroup.getSelection() != null;
submitButton.setEnabled(value);
}
private static void createAndShowGui() {
ActivateButton mainPanel = new ActivateButton();
JFrame frame = new JFrame("ActivateButton");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
You can use isSelected() to check whether the radio button is selected.
Eg:
printButton.setEnabled(!field1.getText().isEmpty() && !field2.getText().isEmpty() && (radioBtn1.isSelected() || radioBtn2.isSelected()) );
Check out: Validation of text fields and contact no text field
It provides a general solution for enabling a button when data is entered in all text fields.
You can enhance that solution to also support radio buttons.
But what about the RadioButtons? I guess I have to somehow implement an ItemListener?
You can modify the DataEntered class found in the link above to do the following:
implement an ItemListener to simply invoke the isDataEntered() method.
create a new addButtonGroup(...) method. This method would save the ButtonGroup and then iterate through all the radio buttons in the group to add the ItemListener to the radio button.
then you would need to modify the isDataEntered() method to iterate through each ButtonGroup and invoke the getSelection() method on the ButtonGroup. If the value is null that means no radio button has been selected and you just return false.
Basically an object with a few ints. I want the ints to change when their respective button is pressed. For example if you press JButton 2 then the second int should change based on the method within it's if statement in the actionPerformed method. Not sure what I did wrong but the buttons do absolutely nothing right now.
public class Object {
public int someInt;
//public int someOtherInt;
//etc. I have a few different ints that I do the same thing with throughout the code, each JButton changes a different int
public Object() {
this.someInt = someInt;
JFrame frame = new JFrame();
frame.setLayout(new FlowLayout());
frame.setDefaultCloseOperation(3);
frame.setSize(325, 180);
frame.setVisible(true);
frame.setTitle("Title");
//String message = blah blah
JLabel confirmMessage = new JLabel(message);
JButton button1 = new JButton("1");
JButton button2 = new JButton("2");
JButton button3 = new JButton("3");
//creating action listener and adding it to buttons and adding buttons to frame
}
public class listen implements ActionListener {
private int someInt;
private int someOtherInt;
public listen(int someInt, int someOtherInt) {
this.someInt = someInt;
this.someOtherInt = someOtherInt;
}
public void actionPerformed() {
if (aE.getSource() == button1) {
//change someInt
}
//same thing for other buttons
}
}
}
It's standard practice to attach a separate listener to each button:
// syntax for Java 1.8:
button1.addActionListener(e -> {
// do whatever
});
// syntax for Java 1.7 and earlier:
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// do whatever
}
});
Define action commands and set them to all of your buttons. Then use them in actionPerformed to determine which button is clicked.
public class Object {
private static final String FIRST_ACTION = "firstAction";
private static final String SECOND_ACTION = "firstAction";
public Object() {
JButton button1 = new JButton("1");
button1.setActionCommand(FIRST_ACTION);
JButton button2 = new JButton("2");
button2.setActionCommand(SECOND_ACTION);
JButton button3 = new JButton("3");
// creating action listener and adding it to buttons and adding buttons
// to frame
}
public class listen implements ActionListener {
//some code
public void actionPerformed(ActionEvent aE) {
if (aE.getActionCommand().equals(FIRST_ACTION)) {
// change someInt
} else if (aE.getActionCommand().equals(SECOND_ACTION)) {
}
// same thing for other buttons
}
}
}
button1.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
exite.setEnabled(true);
}
});
button2.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
exite.setEnabled(true);
}
});
button3.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
exite.setEnabled(true);
}
});
I have 3 buttons here, but they are doing same thing. It takes some space in code. How can I group them all and assigned to one ActionListener?
Something like this. I don't know how it should be.
button1.button2.button3.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
exite.setEnabled(true);
}
});
Just assign the ActionListener to a different variable first:
ActionListener listener = new ActionListener() {
...
};
button1.addActionListener(listener);
button2.addActionListener(listener);
button3.addActionListener(listener);
It's just a reference after all - the only "special" thing here is the use of an anonymous inner class to create an instance of ActionListener.
If there are multiple things that you want to do with all your buttons, you may well want to put them into a collection rather than having three separate variables for them, too.
Juste create a variable :-)
ActionListener listener = new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
exite.setEnabled(true);
}
};
button1.addActionListener(listener);
button2.addActionListener(listener);
button3.addActionListener(listener);
ActionListener listener = new ActionListener(){
#Override
public void actionPerformed(ActionEvent ae) {
exite.setEnabled(true);
}
};
button1.addActionListener(listener);
button2.addActionListener(listener);
button3.addActionListener(listener);
Implement ActionListener in your class
public class YourClass implements ActionListener
That should make you have to implement an actionPerformed method in just one place where it can handle all your actions.
Your addActionListener lines should then become:
button1.addActionListener(this);
button2.addActionListener(this);
etc.
Then use:
public void actionPerformed(ActionEvent event) {
if(event.getSource() == button1 || event.getSource() == button2 || event.getSource() == button3) {
exite.setEnabled(true);
}
}
You can create a class called event that implements the ActionListener for JButtons. Then use the parameter getCommand() method to get the text of the JButton and create if statements for all of the buttons based on the text that the JButton has, the code would be:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*
public class MultipleJButtons extends JFrame {
JButton button1, button2, button3;
public static void main(String args[]) {
MultipleJButtons gui = new MultipleJButtons();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.pack();
gui.setTitle("Multiple Buttons");
gui.setVisible(true);
}
public MultipleJButtons() {
event e = new event();
setLayout(new FlowLayout());
button1 = new JButton("Button 1");
add(button1);
button1.addActionListener(e);
button2 = new JButton("Button 2");
add(button2);
button2.addActionListener(e);
button3 = new JButton("Button 3");
add(button3);
button3.addActionListener(e);
}
public class event implements ActionListener {
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("Button 1")) {
System.out.println("You pressed button 1");
} else if (command.equals("Button 2")) {
System.out.println("You pressed button 2");
} else if (command.equals("Button 3")) {
System.out.println("You pressed button 3");
}
}
I have been working with Swing for a while now on my CS project and, this may sound redundant, but I am unable to pop in my JButton in my JPanel. There are two other buttons which follow the same code and they get displayed but this one I create just refuses to show up. The button is "View Question" button. Similar buttons like the OK and CANCEL work fine. Any help would be much appreciated. The code:
public class CatNodePicker {
private final JDialog dialog;
private String selectedNodeCode;
private XMLTreeNode selectedNode;
private JTree cat;
public CatNodePicker(Container container, JTree cat) {
this.cat = cat;
selectedNodeCode = null;
selectedNode = null;
dialog =new JDialog(findParentFrame(container), "Pick a LEAF node", true);
JPanel buttonPanel = new JPanel();
final JButton okButton = new JButton("OK");
okButton.setEnabled(false);
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
dialog.dispose();
}
});
JButton cancelButton = new JButton("Cancel");
cancelButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
selectedNodeCode = null;
selectedNode = null;
dialog.dispose();
}
});
JButton viewQuestion = new JButton("View Question");
viewQuestion.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
getQuestionLabel();
}
});
buttonPanel.add(okButton);
buttonPanel.add(viewQuestion);
buttonPanel.add(cancelButton);
cat.expandRow(1);
JScrollPane jsp = new JScrollPane(cat);
cat.addTreeSelectionListener(new TreeSelectionListener() {
#Override
public void valueChanged(TreeSelectionEvent e) {
TreePath path=e.getNewLeadSelectionPath();
if(path==null) {
selectedNodeCode = null;
selectedNode = null;
}
if (path.getLastPathComponent().equals(path.getPathComponent(1))) {
selectedNodeCode = null;
selectedNode = null;
}
else {
XMLTreeNode n=((XMLTreeNode)path.getLastPathComponent());
//System.out.println(n.toString());
if(n.isLeaf() || n.isFilter() || n.isLayer()) {
selectedNodeCode = n.getCode();
selectedNode = n;
okButton.setEnabled(true);
}
else
okButton.setEnabled(false);
}
}
});
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
selectedNodeCode = null;
selectedNode = null;
dialog.dispose();
}
});
dialog.getContentPane().add(jsp, BorderLayout.CENTER);
dialog.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
dialog.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
dialog.setSize(new Dimension(600,800));
dialog.setLocationRelativeTo(null);
dialog.pack();
}
public JComponent getQuestionLabel(){
JLabel questionText= new JLabel("Question here");
return questionText;
}
}
In short, I want a "View Question" button in between the OK and CANCEL buttons. Please help. Thank you so much :)
I'm posting this though I don't expect it to help very much. It illustrates that what you are doing works in the simple case, and that to answer your question we need to figure out where you deviate from the simple case (and from correct Swing usage).
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
public class Dialoger
{
public static void main(String[] args)
{
Dialoger dialoger = new Dialoger();
dialoger.go();
}
public void go()
{
JDialog jd = new JDialog();
JButton one = new JButton("one");
JButton two = new JButton("two");
JButton three = new JButton("three");
JPanel panel = new JPanel();
panel.add(one);
panel.add(two);
panel.add(three);
jd.add(panel, BorderLayout.SOUTH);
jd.pack();
jd.setVisible(true);
}
}
I have one frame in which one TestArea is there. When I append some string from this class then String is appended but when I want to append String from other class then String is not appended. I created one method to append string in TextArea, when I call this method in this class then string is appended on text Area. But when I call this method from other Class then String is not appended on TextArea.
Code (MainClass):
public class MainClass {
private JFrame frame;
private TextArea textArea;
private Font font;
private JButton button1;
private JButton button2;
private SecondClass secondClass;
public MainClass() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
frame = new JFrame("XXX");
frame.setBounds(200, 200, 600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
button1 = new JButton("Button1");
font = new Font("Arial", Font.BOLD, 13);
button1.setFont(font);
button1.setBounds(4, 4, 289, 30);
button2 = new JButton("Button2");
button2.setFont(font);
button2.setBounds(300, 4, 289, 30);
font = null;
textArea = new TextArea();
textArea.setBounds(4, 38, 585, 322);
textArea.setEnabled(true);
font = new Font("Arial", Font.PLAIN, 13);
textArea.setFont(font);
frame.add(button1);
frame.add(button2);
frame.add(textArea);
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
textArea.append("*** I am in actionPerformed() ***\n");
appendToTextArea("Call from actionPerformed() method\n");
}
});
button2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
secondClass = new SecondClass();
secondClass.printOnTextArea();
}
});
} catch (Exception e) {
textArea.append(e.toString());
}
}
public void appendToTextArea(String str) {
System.out.println(str+"\n");
textArea.append(str+"\n"); //this line not work when I call this method from other class
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MainClass window = new MainClass();
window.frame.setVisible(true);
}
});
}
}
Code(SecondClass):
import com.grissserver.MainClass;
public class SecondClass extends MainClass{
void printOnTextArea() {
System.out.println("*** printOnTextArea() ***");
super.appendToTextArea("call from Second Class in printOnTextArea()");
}
}
Please give some Idea, why this is not working.
I think the problem is that the way you try to paint to the text area is wrong.
In your action method you create a new object of SecondClass which extends MainClass. This means this object has its own textarea object. But this new object (frame) is not displayed, because you only call setVisibile in MainClass#main, and hence you cannot see the displayed text!
In short: There are two different text areas! And one of them is not visible
The SecondClass has its own textArea. So you may need to pass MainClass's textArea to SecondClass.
public class SecondClass {
private TextArea tArea;
SecondClass(TextArea ta) {
tArea = ta;
}
void printOnTextArea() {
System.out.println("*** printOnTextArea() ***");
tArea.append("call from Second Class in printOnTextArea()");
}
}
You should change your MainClass like this.
....
button2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
secondClass = new SecondClass(textArea);
secondClass.printOnTextArea();
}
});
....
hope this helps...