EDIT: The answer to the button generating part of this question can be found here:
Array that Holds JButton Objects
I used a for loop to generate some JButtons each labeled with their index. Within the loop, I attach an ActionListener to each button. The listener retrieves the label of the button and prints it. Currently, the only button which returns a value is the last one created, which makes sense. I'm wondering if there is a way to do this sort of mass-generation and then individual retrieval in an advantageous way.
IN SHORT:
Make a bunch of labeled JButtons in a loop.
Print the label when a button is clicked.
Here is a short, executable example of what my current process looks like:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
public class calc {
private JFrame mainFrame;
private JPanel mainPanel;
private JButton button;
public calc(){
mainFrame = new JFrame("Calculator");
mainPanel = new JPanel();
for (int i=0; i<10; i++){
int value = i;
String number = Integer.toString(value);
button = new JButton(number);
button.addActionListener(new ButtonListener());
mainFrame.add(button);
}
mainFrame.setLayout(new FlowLayout());
mainFrame.setSize(250, 300);
mainPanel.setLayout(new FlowLayout());
mainFrame.add(mainPanel);
mainFrame.setVisible(true);
}
class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
System.out.println(((JButton) e.getSource()).getText());
}
}
}
}
You can create an array of buttons, for example:
JButton[] btns = new JButtons[10];
for(int x=0; x<btns.length; x++)
btns[x] = new JButton(x + "");
Create your ActionListener:
private class ButtonHandler implements ActionListener{
#Override
public void actionPerformed(ActionEvent e){
System.out.println( ((JButton)e.getSource()).getText() );
}
}
Add each button to the ActionListener:
ButtonHandler handler = new ButtonHandler();
for(int x=0=; x<btns.length; x++)
btns[x].addActionListener(handler);
When you click any of the buttons, it will trigger the ActionListener and based on the button that was clicked, print the text from the JButton to the console.
Related
I am currently working on my school project to practice vocabulary, I have a method in my GUI that creates new vocabulary and the name of the list, I wanted to create a button that adds more Panels with input fields just this prototype image.
My idea is that when the user clicks
AddMoreButton it will add one JPanel just like P Panel, then the user can write vocabulary to send it to my database, is it possible to create something that?, I tried looping the P panel but it did not not change, any help would be appreciated.
private JPanel SetUpCreate() {
JPanel createPanel = new JPanel();
nameListInput = new JTextField(INPUT_FIELD_WIDTH);
termInput = new JTextField(INPUT_FIELD_WIDTH);
defintionInput = new JTextField(INPUT_FIELD_WIDTH);
p = new JPanel();
doneCreate = new JButton("Done");
doneCreate.addActionListener(new DoneCreateButtonAction());
addMoreButton = new JButton("Add");
addMoreButton.addActionListener(new AddMorePanelsListener());
p.setBorder(new BevelBorder(BevelBorder.RAISED));
p.add(termInput);
p.add(defintionInput);
JScrollPane pane = new JScrollPane(p);
createPanel.add(nameListInput);
createPanel.add(p);
createPanel.add(pane);
createPanel.add(doneCreate);
return createPanel;
}
private class DoneCreateButtonAction implements ActionListener {
public DoneCreateButtonAction() {
super();
}
public void actionPerformed(ActionEvent e) {
String namelist = nameListInput.getText();
String termglosa = termInput.getText();
String defintionglosa = defintionInput.getText();
try {
if (model.createWordList(namelist) && (model.createGlosa(termglosa, defintionglosa))) {
cl.show(cardPanel, "home");
}
} catch (IOException e1) {
JOptionPane.showMessageDialog(frame, "skapelsen av listan fungerar ej.");
}
}
}
private class AddMoreButtonAction implements ActionListener {
public AddMoreButtonAction() {
super();
}
public void actionPerformed(ActionEvent e) {
}
}
What I understand from your question is that you want to add another panel every time the user clicks the Add button and the panel to add contains fields for entering a word and its definition.
I see JScrollPane appears in the code you posted in your question. I think this is the correct implementation. In the below code, every time the user clicks the Add button I create a panel that contains the fields for a single word definition. This newly created panel is added to an existing panel that uses GridLayout with one column. Hence every time a new word definition panel is added, it is placed directly below the last word panel that was added and this GridLayout panel is placed inside a JScrollPane. Hence every time a word definition panel is added, the GridLayout panel height increases and the JScrollPane adjusts accordingly.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class MorPanel implements ActionListener, Runnable {
private static final String ADD = "Add";
private JFrame frame;
private JPanel vocabularyPanel;
#Override
public void run() {
showGui();
}
#Override
public void actionPerformed(ActionEvent actionEvent) {
String actionCommand = actionEvent.getActionCommand();
switch (actionCommand) {
case ADD:
vocabularyPanel.add(createWordPanel());
vocabularyPanel.revalidate();
vocabularyPanel.repaint();
break;
default:
JOptionPane.showMessageDialog(frame,
actionCommand,
"Unhandled",
JOptionPane.ERROR_MESSAGE);
}
}
public JButton createButton(String text) {
JButton button = new JButton(text);
button.addActionListener(this);
return button;
}
public JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(createButton(ADD));
return buttonsPanel;
}
private JScrollPane createMainPanel() {
vocabularyPanel = new JPanel(new GridLayout(0, 1));
vocabularyPanel.add(createWordPanel());
JScrollPane scrollPane = new JScrollPane(vocabularyPanel);
return scrollPane;
}
private JPanel createWordPanel() {
JPanel wordPanel = new JPanel();
JLabel wordLabel = new JLabel("Enter Term");
JTextField wordTextField = new JTextField(10);
JLabel definitionLabel = new JLabel("Enter Term Definition");
JTextField definitionTextField = new JTextField(10);
wordPanel.add(wordLabel);
wordPanel.add(wordTextField);
wordPanel.add(definitionLabel);
wordPanel.add(definitionTextField);
return wordPanel;
}
private void showGui() {
frame = new JFrame("Vocabulary");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.setSize(480, 200);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new MorPanel());
}
}
As your code is not an Minimal Reproducible Example, I cannot provide further assistance than this:
Red part: Your main JPanel with BoxLayout
Green part: another JPanel with your JTextField in it.
Purple part: JScrollPane
Blue parts: custom JPanels with 2 panes in them, one on top for the number, one on the bottom for both JTextFields and icon, so I would say GridBagLayout or BoxLayout + FlowLayout
Orange part: JPanel with GridBagLayout or FlowLayout
Each time you clic on the + icon, you just create a new instance of the custom blue JPanel and that's it.
My question is how I can print from more than one JTextField in Java clicking the button once.I can call the print method but from that i can print from the specific JTextField but i want to print from more than one JTextField after clicking the button just once.Please help me.Thanks in advance.
You can get the texts from every textfields and add them in to another textfield or console.
Try this example:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Example {
JFrame frame;
JPanel panel;
JTextField trextField1;
JTextField trextField2;
JTextField trextField3;
JTextField trextField4;
JButton button;
public Example() {
execute();
}
public void execute(){
frame = new JFrame("GridBag");
frame.setSize(400,400);
trextField1 = new JTextField("Hello");
trextField2 = new JTextField("Friend");
trextField3 = new JTextField("How r u");
trextField4 = new JTextField("");
trextField4.setSize(50, 10);
panel= new JPanel();
BoxLayout layout = new BoxLayout(panel, BoxLayout.Y_AXIS);
panel.setLayout(layout);
panel.setSize(400,400);
panel.add(trextField1);
panel.add(trextField2);
panel.add(trextField3);
panel.add(trextField4);
button = new JButton("Say it");
panel.add(button);
frame.add(panel);
frame.setVisible(true);
buttonAction();
}
public void buttonPress(){
//If you have lot of textfields you need to get values to array and iterate through them
String s = trextField1.getText() + trextField2.getText() + trextField3.getText();
trextField4.setText(s);
}
public void buttonAction(){
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
buttonPress();
}});
}
public static void main(String[] args){
Example g = new Example();
}
}
So if you want to print the text of multiple JTextFields to the console, all you really have to do is use the ".getText()" method for each JTextField. It would be best to create a method that does so.
An example using three JTextFields:
JTextfield txt1= new JTextField("Hello");
JTextfield txt2 = new JTextField("Hi");
JTextfield txt3 = new JTextField("Hey");
Create a method that gets and prints out the text of each textfield:
public void printAllTextFields() {
System.out.println(txt1.getText());
System.out.println(txt2.getText());
System.out.println(txt3.getText());
}
Then just call this method whenever you need to in your program.
The output of this example would be:
Hello
Hi
Hey
I believe you can just simply add
JTextField#.append([variable_here])
in the JButton Function that you are using and append that same data to multiple Text Field.
I am writing a GUI program in Java. The GUI consists of 9 buttons titled H. In run mode, when the mouse clicks on any button, that button should change the heading to T. I have a MouseListener code watching out for the clicks. But I have no way of finding out based on the mouse clicks that I need to change that particular button. Any help is appreciated.
Below is my code.
package flippingcoins;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class FlippingCoins extends JFrame
{
public FlippingCoins()
{
JPanel p = new JPanel();
p.setLayout(new GridLayout(3,3,1,1));
JButton jbt1=new JButton("H");
p.add(jbt1);
JButton jbt2=new JButton("H");
p.add(jbt2);
JButton jbt3=new JButton("H");
p.add(jbt3);
JButton jbt4=new JButton("H");
p.add(jbt4);
JButton jbt5=new JButton("H");
p.add(jbt5);
JButton jbt6=new JButton("H");
p.add(jbt6);
JButton jbt7=new JButton("H");
p.add(jbt7);
JButton jbt8=new JButton("H");
p.add(jbt8);
JButton jbt9=new JButton("H");
p.add(jbt9);
add(p);
}
public static void main(String[] args) //Main program begins here.
{
FlippingCoins frame = new FlippingCoins();//Instantiating an object.
frame.setTitle("Head or Tails");//Setting the frame title.
frame.setSize(300,300);//Setting the size.
frame.setLocationRelativeTo(null);//Setting the location.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// Default closing options.
frame.setVisible(true);//Setting visibility to true.
}//End of main program.
static class ChangeTiles extends JPanel
{
public ChangeTiles()
{
addMouseListener(new MouseAdapter()//Creating a listener
{
public void mouseClicked(MouseEvent e)//When the mouse is clicked.
{
int x=e.getX();
int y=e.getY();
System.out.println("x= "+ x + "y= "+y);
}
}
);
}
}
That's not the good strategy. Instead, add an ActionListener to every button. Not only will it be much easier, but users will then also be able to use their keyboard to click the buttons.
Also, consider using an array or list of buttons. That will allow using loops instead of copying and pasting the same code 9 times.
public FlippingCoins() {
final JPanel p = new JPanel();
p.setLayout(new GridLayout(3, 3, 1, 1));
for (int i = 0; i < 9; i++) {
final JButton jbt = new JButton("H");
jbt.setName("" + i);
jbt.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
jbt.setText("T");
System.out.println(jbt.getName());
}
});
p.add(jbt);
}
setContentPane(p);
}
Some notes:
use loops for repetitive tasks
listeners have to be added to the widget they should listen to
do not use MouseListeners for JButton, there is ActionListener
Alternative for JLabel:
public FlippingCoins2() {
final JPanel p = new JPanel();
p.setLayout(new GridLayout(3, 3, 1, 1));
for (int i = 0; i < 9; i++) {
final JLabel jlb = new JLabel("H", SwingConstants.CENTER);
jlb.setBorder(BorderFactory.createLineBorder(Color.blue));
jlb.setName("" + i);
jlb.addMouseListener(new MouseAdapter() {
public void mouseClicked(final MouseEvent e) {
jlb.setText("T");
System.out.println(jlb.getName());
}
});
p.add(jlb);
}
setContentPane(p);
}
This is how you should do it:
JButton jbt1=new JButton("H");
jbt1.addActionListener(new ButtonListener());
//add ButtonListener to all of the other buttons
//Somewhere in your code:
public class ButtonListener extends ActionListener {
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource();
source.setText("T");
}
}
This will be easy if you add an ActionListener. Inside the actionPerformed code you can make it print out which button was clicked.
getSource()
Returns: The object on which the Event initially occurred.
you can call getSource() on the ActionEvent generated by the ActionPerformed method. I haven't tried this but sounds like you can easily find out which button was clicked.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Concentration extends JFrame implements ActionListener {
private JButton buttons[][]=new JButton[4][4];
int i,j,n;
public Concentration() {
super ("Concentration");
JFrame frame=new JFrame();
setSize(1000,1000);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel=new JPanel(new GridLayout(4,4));
panel.setSize(400, 400);
for( i=0; i<buttons.length; i++){
for (j=0; j<buttons[i].length;j++){
n=i*buttons.length+buttons[i].length;
buttons[i][j]=new JButton();
panel.add(buttons[i][j]);
buttons[i][j].addActionListener(this);
}
}
add(panel);
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
buttons[i][j].setIcon(new ImageIcon(
getClass().getResource("/images/2.jpg")));
}
public static void main(String args[]){
new Concentration();
}
}
This is my code. I am making memory game. I want to make that, each time clicked a button, that button shows image but
buttons[i][j].addActionListener(this);
in that, methot can not take i and j and doesnot show any image.
But for example when i do
buttons[2][2].addActionListener(this);
it shows only in 2x2 . image. What can i do to solve that?
Possible solutions:
Inside the ActionListener, iterate through the button array to see which JButton in the array matches the button that was pressed, obtained by calling e.getSource()
Give your JButtons actionCommand Strings that correspond to i and j
Create a separate ActionListener implementing class that has i and j fields that can be set via a constructor, and give each button a unique ActionListener with i and j set.
Try this code:
public void actionPerformed(ActionEvent e) {
if(e.getSource() instanceof JButton){
JButton pressedButton = (JButton) e.getSource();
if(pressedButton.getIcon() == null){
pressedButton.setIcon(new ImageIcon(getClass().getResource("/images/2.jpg")));
} else {
pressedButton.setIcon(null);
}
}
}
Direct form EventObject javadoc:
public Object getSource()
The object on which the Event initially occurred.
Returns:
The object on which the Event initially occurred.
This means there's no need to know the array indexes of pressed button as it could be known through getSource() method.
i am trying to make an actionListener on a button in another button which has also an actionlistener and i just couldn't figure it out for some way. I am trying to make an action on the 2nd button but i couldn't figure it out.If anyone helps me i'd appreciate! here is the code below:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class basic implements ActionListener{
public static void main(String[] args) {
basic process = new basic ();
}
public basic(){
JFrame fan = new JFrame("Scheme");
JPanel one = new JPanel(new BorderLayout());
fan.add(one);
JPanel uno = new JPanel();
uno.setLayout(new BoxLayout(uno, BoxLayout.Y_AXIS));
JButton addB = new JButton("first choice");
addB.setAlignmentX(Component.CENTER_ALIGNMENT);
uno.add(addB);
addDButton.setActionCommand("hehe");
addDButton.addActionListener(this);
one.add(uno,BorderLayout.CENTER);
fan.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
fan.setSize(500,700);
fan.setLocationByPlatform(true);
fan.setVisible(true);
}
public void actionPerformed(ActionEvent evt) {
JPanel markP = new JPanel(new FlowLayout(FlowLayout.RIGHT,10,20));
JDialog dialog = new JDialog((JFrame)null);
dialog.getContentPane().add(markP,BorderLayout.CENTER);
if (evt.getActionCommand().equals("hehe")) {
JLabel title = new JLabel("Proceed");
title.setFont(new Font("Arial",Font.BOLD,15));
markP.add(title,BorderLayout.NORTH);
JButton exit = new JButton("Exit");
markP.add(exit);
//here i want to create another actionListener on the exit button only without affecting the other content which is in the button "addB " so that when i click on the addB button the J dialog pops up, and than when i click on exit button the program will return to the menu.I couldn't figure it out.
dialog.toFront();
dialog.setModal(true);
dialog.pack(); //
dialog.setLocationRelativeTo(null); //
dialog.setVisible(true);
}
// here the code goes on but the problem is that of the actionListener which is concerned.
JButton exit = new JButton("Exit");
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// you code here
}
});
You should use better variables names. It is not easy to follow your code
You could use the same ActionListener if you check the source of the action using
if (evt.getSource().equals(addDButton) { original code }
else { code for the other button }