for example i create this on click
//this creates autor object with default constructor properties defined in autor class
menuAutor.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e)
{
autor Autor = new autor("Autor");
}
});
so object named Autor is created, and when i click again on the button, it pops up again the same Autor object.. how can prevent opening the same window if one is already opened?
EDIT: FINALY A SOLUTION!
After lots of thinking about this.. i made my solution...
default value for autorOpen="no" i declaired at the beginning of my class, just to let you know because its not visible in code below, the solution itself:
public void mouseClicked(MouseEvent e)
{
if(autorOpen=="no") {
autor Autor = new autor("Autor");
autorOpen = "yes";
Autor.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
autorOpen = "no";
}
});
}
else
JOptionPane.showMessageDialog(null, "Demo notice... you can't open that window again.. its opened already!","Error",JOptionPane.ERROR_MESSAGE);
}
});
Store the variable a little bit more globally, and check whether it exists before creating a new one.
You could also consider implementing Autor as a singleton class (to ensure only one is ever instantiated).
public class Autor {
private static Autor instance = null;
//Must be protected or private, get a reference to this class with getInstance().
protected Autor() {
}
/**
* Returns reference to this class - use in place of constructor
*/
public static Autor getInstance() {
if(instance == null) {
instance = new Autor();
}
return instance;
}
}
Use a boolean flag to indicate if the dialog is up or not. Set it to true if the dialog is popped up, and set it to false when you close that dialog.
If you're creating something with 'new' on each click, you'll get a new window each time. One solution is to create autor before any clicks happen, then have the event move it from hidden to visible.
Related
My main class is called MainClass and it has the following code in it:
Startup startup = new Startup();
while (!startup.isDoneWelcoming()){
System.out.print("Waiting for welcoming to finish."+br);
try{Thread.sleep(5000);}catch(Exception waitEx){System.out.print(waitEx+br);}
}
And the value it checks for is from another class called Startup which has this code:
private boolean doneWelcoming=false;
void openWelcomeScreen(){
//irrelevant code...
//a welcome screen is displayed and when "get started" button is pressed
//it opens a new window from the Tutorial class
WelcomeScreen welcomeScreen = new WelcomeScreen();
welcomeScreen.openWelcomeScreen();
//irrelevant code...
}
void setWelcomeStatus(){
System.out.print("Boolean \"doneWelcoming\" is true."+br);
doneWelcoming=true;
}
public boolean isDoneWelcoming(){
System.out.print("Boolean \"doneWelcoming\" value returned as: "+doneWelcoming+br);
return doneWelcoming;
}
The WelcomeScreen class extends from Startup and has this code that initiates the method createTutorialWindow inside the Tutorial class:
void createTutorialWindow(){
//ActionListener detects when the button is pressed and it does this...
Tutorial startTutorial = new Tutorial();
startTutorial.createTutorialWindow();
}
The setWelcomeStatus method is called from another class called Tutorial which extends from Startup. There I have a button and when pressed it does this:
setWelcomeStatus();
My problem is that I see this in my console:
Waiting for welcoming to finish.
Button clicked. Will return welcoming process as complete.
Boolean "doneWelcoming" is true.
Boolean "doneWelcoming" value returned as: false
Which means that doneWelcoming's value does change but it doesn't get returned as true to the original class and so my loop never stops. What should I change to fix this?
EDIT: Added code for WelcomeScreen class in both Startup and the class itself.
NOTE: It is rather obvious that a lot of instances of classes are involved, so it get a little complicated. Thank you for your help.
After reading #Hovercraft Full Of Eels's comment again I figured that the problem lied in my inheritance and he was right. I removed the extends from both my classes: WelcomeScreen and Tutorial and then made small methods to return values from one class to another while using a single instance for each class, like so:
In the Startup I did:
private WelcomeScreen welcomeScreen = new WelcomeScreen();
public boolean isDoneWelcoming(){
System.out.print("Boolean \"doneWelcoming\" value returned as: "+doneWelcoming+br);
return welcomeScreen.returnToStartup();
}
In WelcomeScreen I added:
private Tutorial startTutorial = new Tutorial();
boolean returnToStartup(){
return startTutorial.returnToWelcome();
}
In Tutorial I added:
buttonClicked=false;
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
buttonClicked = true;
}
});
//and as a separate boolean
boolean returnToWelcome() {
while (!letsgoClicked) {
return false;
}
return true;
}
I have some doubts about the use of the PropertyChangeListener interface.
I have a class named GUI that implements the PropertyChangeListener interface.
In this class I have the following method that create and show a JFrame (LoginFrame is a custom class that extends JFrame):
private void showLoginFrame() {
loginFrame = new LoginFrame();
loginFrame.setVisible(true);
loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Notify every change to every bound property for that object:
loginFrame.addPropertyChangeListener(this);
}
So, on my LoginFrame object I add a PropertyChangeListener. So I think that I am adding a mechanism for which when change the value of a property in this object it notify this change that will be handle by the following method (declared in my GUI class):
#Override
public void propertyChange(PropertyChangeEvent arg0) {
System.out.println("GUI SingleFrameApplication ---> propertyChange(): " + arg0.getPropertyName());
if (arg0.getPropertyName().equals("buttonLogOffClicked")) {
//System.out.println("GUI SingleFrameApplication ---> richiamo exit");
//exit();
mainFrame.OnWindowClose();
mainFrame.dispose();
mainFrame = null;
showLoginFrame();
}
if (arg0.getPropertyName().equals("loginResult")) {
System.out.println("GUI SingleFrameApplication ---> richiamo MainFrame");
//loginFrame.setVisible(false);
loginFrame.dispose();
loginFrame = null;
showMainFrame();
}
}
In the specific case in my LoginFrame class I have a JButton that if clicked fire the event that will be handled by the previous method, in this way:
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("Button LogIn cliccked");
// this.addPropertyChangeListener(listener); // I add the PropertyChange Listener to this LoginFrame object
// I fire a PropertyChange: the event start and will be handled by the propper propertyChange() method definied in the listener class:
firePropertyChange("loginResult", false, loginResult);
}
Is it my reasoning correct?
Thanks
Andrea
Instead of firing property change from Action performed function directly, better extends your target bean class, define a setXXX() method to change the xxx property. All Java beans is incorporating with getXXX() and setXXX() method to get and set their Property xxxx. The setXXX() is the one changing the property. we should fire the property, After we change the property, in the context we are changing it, hence it is the setXXX() method. Let us look into setPreferredSize(Dimesion) method source code of Component class :
public void setPreferredSize(Dimension preferredSize) {
if (prefSizeSet) {
old = this.prefSize;
}
else {
old = null;
}
this.prefSize = preferredSize;
prefSizeSet = (preferredSize != null);
firePropertyChange("preferredSize", old, preferredSize);
}
See, we are firing the property upon changes of the property with the corresponding property name. The advantage is that it adds better clarity and make the code structure more readable.
Rather than with conditional checking with each property while listening, i would like to use: addPropertyChangeListener("aProperty", PropertyChangeListener) method: which will listen to specific property changes as defined by in place of "aProperty".
As recommended by #Hovercraft below, the property name be a public String constant so as not to run into spelling or capitalization issues.
I'm having a difficults to add rows to a table that located in different class.
Following are the classes structure:
The dashed arrow is the desired relation that I dont manage to have
in the AddPanel class I have a fileds and Addbutton.
when clicking the addButton I first creating an instance of Product (class located in Logic Package). Then I need to add row to the table (Using the TableModel.AddRow method).
Following are the GUI Looks (the focused tab is AddPannel):
I tried different approches but non of them were successed.
My last attempt was to create in the Table class the following method:
public void AddRow(Product p) {
tbmStock.addRow(new Object[] { p.getExternalId(), p.getName(),
p.getAmount(), p.getPriceForMe(), p.getPriceForCustomer() });
}
In addition, in the AddPanel class I tried to add the following method:
private void AddButtonAction() {
btnAddProduct.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
Product p = new Product(txtName.getText(), txtExternalID
.getText(), Integer.parseInt(txtAmount.getText()),
Double.parseDouble(txtPriceForMe.getText()),
Double.parseDouble(txtPriceForCustomer.getText()),
Integer.parseInt(txtFromYear.getText()), Integer
.parseInt(txtToYear.getText()), Integer
.parseInt(txtSupplier.getText()), Integer
.parseInt(txtCarType.getText()));
AddRow(p); //This call doesn't compiles
}
catch (Exception e1){
JOptionPane.showMessageDialog(null,"Error");
}
}
});
}
Any suggestions ? (actually I'm not sure even that my structure is good :S )
Provide a custom event and event listener. If you create a new product fire the event and notify all listeners. The MainPanel (assuming that's where you create the instance of AddPanel), should register a listener. In this listener you then can update the table as the MainPanel has access to the table.
This is also known as the Mediator pattern.
Some pointers:
Create an event class, e.g. ProductCreatedEvent extends EventObject. Pass the Product as an argument to the constructor and make it accessible with a getter.
Create an event listener class: interface ProductCreatedEventListener extends EventListener. Provide a method such as productCreated(ProductCreatedEvent productCreatedEvent).
In the AddPanel add something like:
private final List<ProductCreatedEventListener> productCreatedEventListeners = new ArrayList<>();
...
public void addProductCreatedEventListener(ProductCreatedEventListener productCreatedEventListener){
productCreatedEventListeners.add(productCreatedEventListener);
}
public void removeProductCreatedEventListener(ProductCreatedEventListener productCreatedEventListener){
productCreatedEventListeners.remove(productCreatedEventListener);
}
private void fireProductCreatedEvent(ProductCreatedEvent event){
for (ProductCreatedEventListener productCreatedEventListener : productCreatedEventListeners){
productCreatedEventListener.productCreated(event);
}
}
Replace:
AddRow(p); //This isn't working
with
fireProductCreatedEvent(new ProductCreatedEvent(AddPanel.this, p));
Found solution
decided it was easier to simply make a method outside of the actionListener called chairPrice which can be incremented by a method called getItemPrice(). This has been used to calculate the total price of items and works 100%
You need to use the Object.equals() method.
#Override
public void actionPerformed(ActionEvent buttonClick)
{
if(buttonClick.getSource().equals(guiButtons[0])) //if user clicks on 'add chair'
{
Chair chair = new Chair();
}
}
Edit in response to the OP's comment
I'm not exactly sure what you're wanting. myChair isn't the name of your chair. It's the name of the variable. It has no effect on Chair at all. If you want to make a new Chair object and have it available for the whole class, you're going to need to either add a new field variable or make a list of Chair.
public class GuiClass extends JPanel implements ActionListener
{
List<Chair> chairs = new ArrayList<Chair>(Arrays.asList(new Chair()));
Desk myDesk = new Desk();
Table myTable = new Table();
#Override
public void actionPerformed(ActionEvent buttonClick)
{
if(buttonClick.getSource().equals(guiButtons[0])) //if user clicks on 'add chair'
{
chairs.add(new Chair());
}
}
}
I have two forms : f_main and f_recruitment. I put a label in f_main with this code :
....
private void jLabel2MouseClicked(java.awt.event.MouseEvent evt) {
JOptionPane.showMessageDialog (null, "Recruitment Icon has been Clicked");
new F_Recruitment().setVisible(true);
}
// to display f_recruitment
Question is how can I have just one active f_recruitment open?
Update:
Thanks, what I mean is, how can I prevent user from re-click jLabel2 and another f_recruitment are open..? ( I let f_main form keep visible on purpose, while the new form f_recruitment is open)
I agree completely with glowcoder (1+), that more information would be helpful and perhaps essential to competently answering this question, but another option is to use lazy initiation -- to create an F_Recruitment variable field that's null, and instantiate it in the listener if it's null, but regardless of whether it was initially null or not, at the bottom of the listener display the field.
public class MyClass {
private F_Recruitment fRecruitment = null;
// ... more code goes here
private void jLabel2MouseClicked(java.awt.event.MouseEvent evt) {
JOptionPane.showMessageDialog (null, "Recruitment Icon has been Clicked");
if (fRecruitment == null) {
fRecruitment = new F_Recruitment();
}
fRecruitment.setVsible(true);
}
I really don't think there is enough information here to really answer your question.
You say you want just one active f_recruitment, but that implies there are more than one f_recruitment.
You could consider a toggle method:
private void toggleRecruitmentOn() {
f_main.setVisible(false);
f_recruitment.setVisible(true);
}
private void toggleMainOn() {
f_recruitment.setVisible(false);
f_main.setVisible(true);
}
I'll update this if more information gets posted about the issue at hand :)