I create some JButtons with a method, but I don't give them a variable i can call them with. i was wondering if it is possible to change the text somehow, after the button is created from another method. I am aware of that i can get the action command when the button is pressed but i want to change the button text, without it being pressed. I can give the buttons names like but would prefer not to. since I am only going to call half of them, and then I don't think its a good idea. or is it?
JButton button1 = buttons(0,0,0);
public JButton buttons(int coord, int coord1, int number) {
JButton box = new JButton("");
box.setFont(new Font("Tahoma", Font.PLAIN, 60));
box.setBounds(coord, coord1, 100, 100);
contentPane.add(box);
box.addActionListener(this);
box.setActionCommand(Integer.toString(number));
return box;
}
public static void main(String[] args) {
buttons(0,0,0);
buttons(98,0,1);
buttons(196,0,2);
buttons(0,98,3);
addText();
}
public void addText() {
//help me guys
button.setText("Please fix me");
}
You can get pressed button from actionEvent
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
}
Why not just have them in a public arraylist?
ArrayList<JButton> buttons = new ArrayList<JButton>();
public JButton buttons(int coord, int coord1, int number) {
JButton box = new JButton("");
box.setFont(new Font("Tahoma", Font.PLAIN, 60));
box.setBounds(coord, coord1, 100, 100);
contentPane.add(box);
box.addActionListener(this);
box.setActionCommand(Integer.toString(number));
buttons.add(box);//Add it here
return box;
}
This way you can loop through them later and change something if you want to,
for(JButton b : buttons){
if(/*Whatever*/){
b.setText("New name");
}
}
I can give the buttons names like but would prefer not to. since I am only going to call half of them, and then I don't think its a good idea. or is it?
You are creating problems for yourself. Even if you may only need the call a few/none of them, there is significant advantage for not keeping a reference for them.
If you have too many JButtons and you do not want to have a separate variable name for each of them, you can have an array/collection of JButtons.
JButton[] btns = new JButton[size];
//or
ArrayList<JButton> btns= new ArrayList<JButton>();
To change text for all buttons:
for(JButton b : btns)
btns.setText("whatever here");
To change text for a specific button:
btns[x].setText("whatever here"); //from array
btns.get(x).setText("whatever here"); //from list
Alternatively, if you do not keep a reference. You can get the list of buttons from the content pane:
Component[] components = myPanel.getComponents();
for(Component c : components)
if(c instanceof JButton)
((JButton)c).setText("whatever here");
Related
I have a JPanel which consists of a dropdown and a text field inside my JFrame. There is a button in my JFrame, when user clicks on that button, application adds new JPanel with the same components i.e. drop down and a text field. So, for this I have created a function which gets called on clicking on the button using ActionListener.
Everything works fine from GUI side but the problem is when user is done with adding JPanels and entering the values in these drop downs and text fields, it will click on Submit button. Upon clicking on Submit button, I should be able to fetch the values from all drop downs and text fields. This is a challenge, since I am using the same functions to create JPanels, I can't call its name to get the values since that will give me the last JPanel values.
Any suggestion how I should go about this? I have added the screenshot of my JFrame and the function to create the JPanel. Any help is appreciated. Thanks.
public static void AddPanel(final Container pane) {
panel1 = new JPanel();
String text = "<html><b>Property" + nooftimes + " :</b></html>";
JLabel label = new JLabel(text);
label.setPreferredSize(new Dimension(80, 30));
panel1.add(label);
panel1.add(new JLabel("Please enter the property"));
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>();
model.addElement("value1");
model.addElement("value2");
model.addElement("value3");
model.addElement("value4");
model.addElement("value5");
final JComboBox<String> comboBox1 = new JComboBox<String>(model);
AutoCompleteDecorator.decorate(comboBox1);
comboBox1.setPreferredSize(new Dimension(120, 22));
panel1.add(comboBox1);
final JTextField txtfield1 = new JTextField(
"Please enter your value here");
txtfield1.setPreferredSize(new Dimension(200, 22));
panel1.add(txtfield1);
txtfield1.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
txtfield1.setText("");
}
public void focusLost(FocusEvent e) {
// nothing
}
});
container.add(panel1);
nooftimes++;
frame.revalidate();
frame.validate();
frame.repaint();
}
Screenshot:
}
You could return the JPanel and store it in a List<JPanel>. When you click your submit-Button you are able to iterate through the JPanels and its Components.
public class Application {
private static List<JPanel> panels = new ArrayList<>();
private static Container someContainer = new Container();
public static void main(String[] args) {
panels.add(addPanel(someContainer));
panels.add(addPanel(someContainer));
panels.add(addPanel(someContainer));
submit();
}
public static JPanel addPanel(final Container pane) {
JPanel panel1 = new JPanel();
// shortened code
final JComboBox<String> comboBox1 = new JComboBox<String>();
panel1.add(comboBox1);
final JTextField txtfield1 = new JTextField("Please enter your value here");
txtfield1.setText(String.valueOf(Math.random()));
panel1.add(txtfield1);
return panel1;
}
private static void submit() {
for (JPanel panel : panels) {
Component[] components = panel.getComponents();
for (Component comp : components) {
// Cast comp to JComboBox / JTextField to get the values
if (comp instanceof JTextField) {
JTextField textField = (JTextField) comp;
System.out.println(textField.getText());
}
}
}
}
}
You could simply have a class (extending JPanel) with specific methods to add your components , and to get inputs from user (i.e. get the combo box selected index and text from textfield ).
Every time you add a panel, you don't call a static method, but you create an instance of this class, keeping the reference somewhere (for example adding it to an arraylist).
But you could consider a different scenario: personally i don't like to add components "on fly", you could have a component (for example another JComboBox), where user can select the number of values he needs.
You decide a default value (for example 4), so at the beginning you create 4 panels of your class, and you can use a simple array containing them.
If the user changes the number of panels, you could dispose frame and create a new one.
Of course this solution does not woork good if you want to keep inputs inserted, or if the frame construction takes a lot of time.
Here there is a screenshot of a gui i created: user can select the number of partials, when the choice changes i just recreate the panels below,containing the textfields (which are memorized in a two-dimensional array).
I have a main frame : JFrame>contentFrame>ScrollPane>BigPanel>panel_1T
private JPanel contentPane;
private JPanel BigPanel;
private JPanel panel_1T;
In panel_1T, I have put a FOOD button WITH its actionListener:
JButton button_19 = new JButton("FOOD");
button_19.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
newFoodUI nf = new newFoodUI();//Open other class
nf.setVisible(true);
nf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
});
panel_1T.setLayout(new GridLayout(0, 2, 0, 0));
panel_1T.add(button_19);
When user click FOOD button, new JFrame in newFoodUI class will be shown.:
JFrame>contentPane>panel>tabbedPane>panel_3>panel_5
In panel_5, I put a JTextField:
public static JTextField textField_3;
textField_3 = new JTextField();
panel_5.add(textField_3, "9, 4, fill, default");
textField_3.setColumns(10);
User will write some text into textField_3. Then user click SAVE button in panel_3, it will perform this:
JButton button_4 = new JButton("SAVE");
button_4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
setContentPane(contentPane);
panel_3.revalidate();
panel_3.repaint();
panel_3.updateUI();
panel_5.revalidate();
panel_5.repaint();
panel_5.updateUI();
contentPane.revalidate();
contentPane.repaint();
JOptionPane.showMessageDialog(null, "Saved !");
}
});
button_4.setBounds(873, 396, 75, 33);
contentPane.add(button_4);
}
The result is, when I click SAVE button and close the Frame in newFoodUI, I will reopen back by click the FOOD button to check whether the text I wrote has been saved or not. But its not saving the text I wrote.
You have to save the value from the textfeld textField_3.getText() and set this value manually to textfeld when showing textField_3.setText(value). So you have to keep your value in your project or store persistent somewhere.
There are a couple of things to fix here and I will not give you complete code but I will point out some errors. First let's consider your button_19 listener
public void actionPerformed(ActionEvent ae) {
newFoodUI nf = new newFoodUI();//Open other class
nf.setVisible(true);
nf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
When this is performed, it creates a totally new object of newFoodUI and gives it no parameters. So how could this frame know about anything that happened before its creation if you give it nothing? Additionally, you explicitly say DISPOSE_ON_CLOSE, when you could use HIDE_ON_CLOSE if you wish to reuse it.
Then in your JButton button_4 = new JButton("SAVE"); listener you want to save the data in the text field, but your implementation does nothing to the text field. You should, for example, get the text from textField_3 and write it to a file or send back to the first JFrame.
Then there is the issue of using multiple JFrames in the first place.
I have two buttons and in the second one I want to use a variable made in the first button. So Netbeans is generating code of the button. ActionEvent generated by netbeans is
"private void buttonActionPerformed(java.awt.event.ActionEvent evt)"
and I cant change it. I tried to change button to public in button setting. I changed it to public but in code it is still private. I dont know what to do. Anyone know where the problem might be?
Thanks.
What you want to do is, there is a blank line above the private void buttonActionPerformed(ActionEvent evt) you create your variable in that line the example: int a; now the a will turn green. This is called a global variable
JFrame jtfMainFrame;
JButton jbnButton1, jbnButton2;
JTextField jtfInput;
JPanel jplPanel;
//Declaring the string variable setText
String setText;
public JButtonDemo2() {
jtfMainFrame = new JFrame("Which Button Demo");
jtfMainFrame.setSize(50, 50);
jbnButton1 = new JButton("Button 1");
jbnButton2 = new JButton("Button 2");
jtfInput = new JTextField(20);
jplPanel = new JPanel();
jbnButton1.setMnemonic(KeyEvent.VK_I); //Set ShortCut Keys
jbnButton2.setMnemonic(KeyEvent.VK_I);
jbnButton1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Setting the setText variable
setText = "Do whatever you want";
}
});
jbnButton2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//Displaying the setText variable
jtfInput.setText(setText);
}
});
jplPanel.setLayout(new FlowLayout());
jplPanel.add(jtfInput);
jplPanel.add(jbnButton1);
jplPanel.add(jbnButton2);
jtfMainFrame.getContentPane().add(jplPanel, BorderLayout.CENTER);
jtfMainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jtfMainFrame.pack();
jtfMainFrame.setVisible(true);
}
Simply declare it as a global means when the class definition starts at that time declare the variable which you want to use at the two buttons click and change the value of variable according to your use.
No need to change the ActionPerformed(). All you have to do is declare the variable as a global variable and then do whatever the task inside the button's ActionPerformed().
Similar questions to my own have been asked, but I'm at a bit of a loss as to how to proceed. I really have a poor grasp of some of the more subtle nuances of java, so I apologize if anything isn't clear.
Say for example I wanted to compare one JButton within a 2D array with another. To be more specific, all of these JButton's would be stores within a 2D array and displayed in grid format. All of the buttons would have the same action listener that, upon the button being pressed, calls the setselected() method.
How would I go about comparing one of these selected JButton's with another selected JButton within the same array? And upon doing so, how could I swap the positions or more specifically, the icons of said buttons.
Below, I've included some example code and my own attempt on the subject. I understand that I can use .getSource() to grab a JButton object itself, but would this not only allow me to capture 1 selected button at a time. This is all considering the use of the same actionlistner code for each button, but a secular listener for each button.
The code below sets every icon to 1 of 7 randomly generated image icons. A frame is generated within secular main class. Upon being pressed or "selected" the image icons change to a selected iteration of the same image.
EDIT: Based on Ameer's suggestion, I've run into several nullpointer exceptions that are caused by my actionPerformed method. Is this as a result to my button array not being filled with button objects at this point, or am I simply presuming something within my code?
public class SButtonGame extends JFrame implements ActionListener {
public static ImageIcon[] icons={
new ImageIcon("img1.png"),
new ImageIcon("img2.png"),
new ImageIcon("img3.png"),
new ImageIcon("img4.png"),
new ImageIcon("img5.png"),
new ImageIcon("img6.png"),
new ImageIcon("img7.png"),
};
public static ImageIcon[] selectedIcons={
new ImageIcon("simg1.png"),
new ImageIcon("simg2.png"),
new ImageIcon("simg3.png"),
new ImageIcon("simg4.png"),
new ImageIcon("simg5.png"),
new ImageIcon("simg6.png"),
new ImageIcon("simg7.png"),
};
int rowNum=0;
int colNum=0;
JButton[][] Buttons;
boolean swaptf=false;
JButton CButton; // Selected button "holder". Doesn't accomplish anything I think it should
public SButtonGame(String title) {
//Constructs frame
super(title);
getContentPane().setLayout(null)
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(578,634);
int colLoc=10;
int rowLoc=10;
this.colNum=0;
this.rowNum=0;
for(int r=0; r<8; r++)
{
this.Buttons= new JButton[9][9];
this.rowNum++;
for(int c=0; c<8; c++)
{
ActionListener listner = new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if(e.getSource() instanceof JButton)
{
((JButton) e.getSource()).setSelected(true);
CButton=(JButton)e.getSource();
}
}
};
int ranImg;
ranImg=0+(int)(Math.random()*7);
int sranImg=ranImg;
this.Buttons[this.colNum][this.rowNum]= new JButton(icons[ranImg]);
this.Buttons[this.colNum][this.rowNum].setSelectedIcon(selectedIcons[sranImg]);
this.Buttons[this.colNum][this.rowNum].addActionListener(listner);
this.Buttons[this.colNum][this.rowNum].setSize(59,59);
this.Buttons[this.colNum][this.rowNum].setLocation(rowLoc,colLoc);
rowLoc=rowLoc+69;
this.Buttons[this.colNum][this.rowNum].setVisible(true);
this.Buttons[this.colNum] [this.rowNum].setBorder(BorderFactory.createLineBorder(Color.black));
add(this.Buttons[this.colNum][this.rowNum]);
}
this.colNum++;
colLoc=colLoc+69;
rowLoc=10;
}
JButton Newgame;
Newgame= new JButton("NewGame");
Newgame.setSize(100, 30);
Newgame.setLocation(350, 560);
Newgame.setVisible(true);
add(Newgame);
JButton Quit;
Quit= new JButton("Quit");
Quit.setSize(60, 30);
Quit.setLocation(480, 560);
Quit.setVisible(true);
add(Quit);
New.addActionListener(new ActionListener()
{
//dispose of current frame and generates a new one;
public void actionPerformed(ActionEvent e)
{
dispose();
SButtonGame Frame;
Frame = new SButtonGame("ShinyButtons");
Frame.setVisible(true);
}
});
Quit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
dispose();
}
});
}
#Override
public void actionPerformed(ActionEvent ae){
if(ae.getSource() instanceof JButton){
JButton sButton;
int rindex=0;
int cindex=0;
((JButton) ae.getSource()).setSelected(true);
sButton=(JButton)ae.getSource();
if(SButtonGame.this.Buttons[(int)sButton.getClientProperty("rownum")][(int)sButton.getClientProperty("colnum")].isEnabled()==true){
}
}
}
public static void main(String[] args)
{
SButtonGame Frame;
Frame = new SButtonGame("ButtonsGame");
Frame.setVisible(true);
}
}
Inside actionPerformed(ActionEvent e) method, you can access the 2D array of buttons by using SButtonGame.this.Buttons (ideally variable name should be buttons starting with small b).
You can then compare the clicked button with the buttons from array and do rest of your stuff.
I have a various panels with various buttons. Some buttons should call a method initiating a search through an array list, other buttons should call methods that send information to different JTextArea boxes.
After adding an event listener for each button, how do I create specific actions depending on the button clicked in my actionPerformed method? Below is my code for various gui properties, as you can see there are 3 different JPanels, the buttons of each needing to perform different functions. I just need to know how to determine which button was clicked so I can link it to the appropriate method (already written in another class). Does this require an if statement? Can my other class access the buttons on the GUI if I make them public, or is there a more efficient way to do this.
JPanel foodOptions;
JButton[] button= new JButton[4]; //buttons to send selected object to info panel
static JComboBox[] box= new JComboBox[4];
JPanel search;
JLabel searchL ;
JTextField foodSearch;
JButton startSearch; //button to initialize search for typed food name
JTextArea searchInfo;
JPanel foodProfile;
JLabel foodLabel;
JTextArea foodInfo;
JButton addFood; //but to add food to consumed calories list
JPanel currentStatus;
JLabel foodsEaten;
JComboBox foodsToday;
JLabel calories;
JTextArea totalKCal;
JButton clearInfo; //button to clear food history
As per people's comments, you need to use listeners of some sort, here is a real basic example to get you started, however I would define your listeners elsewhere in most cases, rather than on the fly:
JButton startSearch = new JButton("startSearch");
JButton addFood = new JButton("addFood");
startSearch.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
//DO SEARCH RELATED THINGS
}
});
addFood.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//DO FOOD ADD RELATED THINGS
}
});
Something like this:
JButton searchButton = new JButton("Start search");
searchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// do some search here
}
});
JButton addFoodButton= new JButton("Add food");
addFoodButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// add your food
}
});
and so on. If you need to reuse an behaviour through multiple buttons, create a ActionListener instance instead of using anonymous classes and assign it multiple times to your buttons.
Well there any many ways to do that I guess. I suppose you can do the following:
public class Myclass implements ActionListener
{
private JButton b1,b2;
private MyClassWithMethods m = new MyClassWithMethods();
// now for example b1
b1 = new JButton("some action");
b1.setActionCommand("action1");
b1.addActionListener(this);
public void actionPerformed(ActionEvent e) {
if ("action1".equals(e.getActionCommand()))
{
m.callMethod1();
} else {
// handle other actions here
}
}
}
And you can do the same for more buttons and test which action triggered the event and then call the appropriate methods from you class.