I have 3 JFrames which use a common JFrame for the purpose of selecting a customer from the complete list. These are the 3 JFrames.
AddPayment
AddInvoice
AddPurchase
All these interfaces use a common JFrame called SelectCustomer which has a listbox from which the user can select one customer from the complete customer list. The name of the selected customer should appear in the JFrame which called the SelectCustomer JFrame.
I know I can use a static jTextField to access and set the value. What I want to know is how can I know which of the above 3 called this SelectCustomer JFrame so that I can decide where the selected value should go.
One of the gui which causes the SelectCustomer JFrame to appear:
http://i.imgur.com/l85k4kQ.png
Select Customer JFrame:
http://i.imgur.com/sD7hp7s.png
I hope my question is clear. Thanks!!
if you are using a button to open the frame and then use this in the same action listener
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(!frame2.isVisible())
frame2.setVisible(true);
}
});
Ehm, maybe this answer seems silly, but have you tried sending some reference when you are calling the class, either from the 3 JFrames?, since I think there is no function that can tell you who called the current JFrame.
So, when you call the SelectCustomerFrame, you could do something like
new SelectCustomerFrame(whatever params, this);
It will require three different constructors in the SelectCustomerFrame in order to sort out who actually called the SelectCustomerFrame, each of them capturing the distinct classes.
Hope to have sourted out your troubles.
Related
I have a problem about modify button background. I am using netbeans gui builder for build form. I am trying change button background when the second frame is open and turn it back when second frame close.
public void update(boolean x){
if(x==true){
circleButton.setOpaque(true);
circleButton.setBackground(new java.awt.Color(0, 0, 0));
System.out.println("testoutput");
}
}
this is my update method from first class.
I added window listener to second frame.
private void formWindowOpened(java.awt.event.WindowEvent evt) {
isitopen = true;
//this is first class which includes button
homework hwork = new homework();
hwork.update(isitopen);
System.out.println("testoutput2");
}
I got 2 testoutput but color of the button didn't change.
What can i do to fix this issue ?
You're creating a new homework object in your formWindowOpened(...) method, one completely unrelated to the homework object that is displayed, and changing the state of the new object will have no effect on the displayed one.
A simple and WRONG solution is to use static fields or methods.
Instead one simple solution is to give the calss with your formWindowOpened(...) method a valid reference to the displayed homework object, something that can be done with a constructor parameter or a setHomework(...) method.
A much better and even simpler solution:
Make the 2nd window a modal JDialog, not a JFrame
This way homework will know when the window is open and can set its own button colors. When the 2nd window opens, program flow in the calling class is put on hold, and only resumes when the 2nd window closes -- just like using a JOptionPane.
For more on this, please see The Use of Multiple JFrames, Good/Bad Practice?
As an aside, you will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
It might be confusing for some to answer this but I will try to put my question in the best way. I am working with jdbc and gui. Basically I want to display (in buttons format) the particular data received from my sql database. I could get the data correctly and put it to my array of buttons as their names. In other words, I have an ArrayList of buttons with different names/texts received from my database. Thus i really need to make an arraylist of buttons since data are dynamically populated. My problem is, I am so confused of how am going to create an actionListener to each button. Everytime each button is clicked, it must show the values associated with its name. I don't know how am i supposed to pass at least the names of the buttons to my actionListener method (or action Event Handler). If you find it confusing, here is the code for my buttons.
todayTaskButton.add(new JButton(taskForToday.get(i)));
todayTaskButton.get(i).setPreferredSize(new Dimension(300,75));
todayTaskButton.get(i).setBackground(Color.GRAY);
todayTaskButton.get(i).setFont(new Font("Century Gothic",Font.PLAIN,30));
todayTaskButton.get(i).setForeground(Color.WHITE);
todayTaskButton.get(i).setFocusable(false);
Thank you so much
You don't need to pass the name of the button to the ActionListener. It is automatically detected. You just need to implement the method actionPerformed(ActionEvent) in you class.
Then add the listener to the button :
todayTaskButton.get(i).addActionListener(this);
In your actionPerformed method, you can do:
JButton b = (JButton) e.getSource();
String text = b.getText();
Honestly there are so many ways you might achieve this, the problem is picking the right one for you...
You could...
Create a anonymous class for each button, each time your create them
todayTaskButton.get(i).addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...
}
});
While this can work, it can make the code really messy, you also still need a way to map the action back to the button in some way, which can be done using the actionCommand property or using the source property if you don't mind iterating through the list of available buttons
You could...
Create a purpose build class which implements ActionListener for each button, which possibly takes some kind of reference to the data
todayTaskButton.get(i).addActionListener(new TodayActionListener(taskForToday.get(i)));
This is a little more focused, as you don't really care about the button, as you have the "today" value for the listener, so all the normally repeated code could be isolated into a single class and you would simply pass in the "variable" element
You could...
Take full advantage of the Action API and make individual, self contained actions for each button...
public class TaskAction extends AbstractAction {
public TodayAction(String task) {
putValue(NAME, task);
}
#Override
public void actionPerformed(ActionEvent e) {
// Specific action for task
}
}
Then you could simply use
todayTaskButton.add(new JButton(new TaskAction(taskForToday.get(i))));
While this is similar to the previous option, the Action is a self contained unit of work and has a number of properties which the JButton can use to configure it self. The Action can also be re-used for JMenuItems and key bindings, making it incredibly flexible
Have a closer look at How to Use Actions for more details
I have a JFrame with buttons and when I click one of the buttons an integer decreases by 1. I am trying to show the integer in another JFrame but when I reference it I get an error saying non static variable cannot be referenced in a static context. How can I make this a non static variable?
Here is the code from when a button is clicked.
private void DietPepsiBTNActionPerformed(java.awt.event.ActionEvent evt) {
MessageLBL.setText("Enjoy your Diet Pepsi!");
credit -= 1.00;
stCredit = Double.toString(credit);
CreditAMT.setText("$" + stCredit);
Refresh();
dietPepsi -= 1;
Provide some kind accessor in the master frame (to allow other components to read the value) (something like getValue() for example).
When ever the value is changed, fire some kind of event. You could cheat and use a PropertyChange event which would require you not to add any additional code, or you could fire something like a change event that notifies the other frame that the value has changed.
The second frame would then use the getValue method to read the value.
This would require the second frame to have a reference to the master (so it can get the value).
Better yet, just create a model, allow the model to fire events and share the model.
Have a look at Observer Pattern for more details
Brendon's answer is close. Ideally what you do what he suggests, create a separate object and pass it in to each frame. The frames then share the objects. Since the frames themselves will have references to the object, you don't need any kind of global reference.
YourModel model = new YourModel();
Frame1 frame1 = new Frame1(yourModel);
Frame2 frame2 = new Frame2(yourModel);
Additionally, you implement the PropertyChangeListener idiom to where each frame subscribes to the property changes in YourModel.
That way, when Frame1 makes changes to YourModel, Frame2 will be notified of them and can keep itself up to date automatically.
Then the game becomes a matter wiring together objects and their listeners. After that, it's almost magic how it all works together.
Ref: http://docs.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html
Make a third object and pass a reference to both jframes. This shared object can store any properties that you need
I've been working on a Java Swing project where I need to retrieve the object/instance that created a panel in order to call a simple save method particular to that instance.
You have a JFrame with a JTabbedPane that has tabs created by instancing a class which builds a JPanel and adds it to the JTabbedPane, I need to find the specific instance from the selected JPanel/tab on the JTabbedPane to then call it's save method.
Any ideas?
Thanks for your time!
public class frame extends JFrame implements ActionListener{
Builds a frame dubbed "frame" that is static.
Builds a static JTabbedPane dubbed "pane"and adds it to the frame.
Creates a button that creates a new instance of sheet.
public void actionPerformed(MAGIC!){
See if a button on the panel has been pressed and uses the currently selected tab to locate the correct instance of sheet to run it's save method.
}
}
public class sheet extends JPanel{
In constructor makes a JPanel and adds it to "pane"
Describes a save method that outputs a variable unique to the instance.
}
I figured out all I needed to do was store new tab objects in an ArrayList derp. Thanks for your attempts though guys!
Rather than just connecting back to the original creator, my approach to this was to create / use an interface that expicitly supports saving. I created something for this in TUS, my sourceforge project
http://tus.svn.sourceforge.net/viewvc/tus/tjacobs/io/filepersist/
Check out Persistable and Persistable2. Of course anything can be a Persistable, but the abstraction let's you get away from explicit ties back to the creator class
You can add a field in the new JPanels that point to the instance of the creator. I don't think there is any such method to point back to parent class in the API.
--EDIT--
You may want to check
http://docs.oracle.com/javase/tutorial/uiswing/components/tabbedpane.html
getSelectedIndex() may be what you are looking for.
So as you may know, if you have a text field and you add an ActionListener to it, it will only listen to the keypress of the enter button. However, I want to let my ActionListener listen to changes in text of the . So basically I've got this:
public static JPanel mainPanel() {
JPanel mainp = new JPanel();
JTextArea areap = new JTextArea("Some text in the textarea");
JTextField fieldp = new JTextField("Edit this");
areap.setEditable(false);
fieldp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(//change in textfield, for instance a letterpress or space bar)
{
//Do this
}
}
});
mainp.add(areap);
mainp.add(fieldp);
return mainp;
}
Any way I can listen to changes in text (like documented in the actionPerformed event)?
From an answer by #JRL
Use the underlying document:
myTextField.getDocument().addDocumentListener();
Yeah, but what is a document listener and how do you use it? You're not really answering the question.
I have a JTextField in my app's user interface. When the user makes any change to it, I want a nearby JCheckBox to be checked. The purpose is to tell the app to USE the value that was entered. Users often enter a value there but if they don't explicitly tell the app to use it then the app continues to ignore it. Instead of "training" users I'm supposed to follow the principle of least astonishment and automatically check the "Use this value" box.
But how do I listen for a change? Can't you guys just tell me the easy way, instead of "educating me" about document listeners?
Documents are the mechanisms java swing uses to store the text inside of a JTextField. DocumentListeners are objects that implement the DocumentListener interface and thus make it possible for you to list to changes in the document, i.e. changes in the text of the JTextField.
To use the document and documentlistener capabilities, as suggested above extend your class (probably but not necessarily a JFrame) so that it implements the DocumentListener interface. Implement all the methods for the interface (most likely your java ide can do that semi-automatically for you. FYI, the DocumentListener interface has three methods, one for inserting characters (into the text field), one for removing characters, and one for changing attributes. You are going to want to implement the first two as they are called when characters are added (the first one) or deleted (the second one). To get the changed text, you can either ask the document for the text, or more simply call myTextField.getText().
C'est tout!
Phil Troy