opening only one window on actionPerformed - java

I've looked through topics on how to open only one window when a button is clicked but none of the solutions there helped, perhaps because my code was structured a bit differently.
So I have a main window class extending JFrame and one of the buttons is supposed to open a new window when clicked. I have defined the widgets/panels etc for the new window in a separate class. At the moment, every time I click on the button a new window is opened. I want to make it so that if a window is already opened then it would switch to that window once the button is clicked again.
Here is a bit of my code:
public class MainWindow extends JFrame{
/*
* create widgets and panels
*/
Button.addActionListener(new ActionListener() { // the button that opens
//a new window
#Override
public void actionPerformed(ActionEvent e) {
Window2 ww = new Window2(); //creating the new window here
}
});
}
NB. The Window2 class is also extending JFrame, if that's of any help.
Thanks

pull out ojbect creation from actionPerformed method beacuse each time you click button it's create new object. below can help you :-
Make a Window2 class singalton for more detail about singalton click here.
2 . add null check as below :-
....
Window2 ww = null; // static or instence variable
......
#Override
public void actionPerformed(ActionEvent e) {
if(ww==null)
{
ww = new Window2();
ww.someMethod();
}
else
{
ww.someMethod();
}
}
});

Here is a full working example:
Window2.java
public class Window2 extends JFrame {
private static final long serialVersionUID = 7843480295403205677L;
}
MainWindow.java
public class MainWindow extends JFrame {
private static final long serialVersionUID = -9170930657273608379L;
public static void main(String[] args) {
MainWindow mw = new MainWindow();
mw.go();
}
private void go() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
private void createAndShowGUI() {
JButton button = new JButton("Click me");
button.addActionListener(new ActionListener() {
private Window2 ww = null;
#Override
public void actionPerformed(ActionEvent e) {
if (ww==null) {
ww = new Window2(); //creating the new window here
ww.setDefaultCloseOperation(HIDE_ON_CLOSE);
ww.setTitle("Window2 created on " + new Date());
ww.setSize(500, 200);
}
pack();
ww.setVisible(true);
}
});
setLayout(new BorderLayout());
add(button);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setVisible(true);
}
}

What you can try is make two windows and put the actionPeformed method in the main class so that when the button is pressed it displays the second window

Related

opening a frame by clicking on the button

In my project I am trying to open LoginFrame from WelcomeFrame by clicking a button and I want myWelcomeFrameto be closed as well.
I have successfully opened theLoginFrameby usingsetVisible(true).
To close theWelcomeFrameI have writtenframe.SetVisible(false)where frame is the object ofWelcomeFrame` but this line shows an error: frame cannot be resolved ....
Here's my code.. Please help
public class WelcomeFrame extends JFrame{
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WelcomeFrame frame = new WelcomeFrame(); //object of WelcomeFrame
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
JButton btnNewButton = new JButton("Librarian Portal\r\n");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
LoginFrame l=new LoginFrame();
l.setVisible(true);
frame.setVisible(false); //error:frame cannot be resolved
}
});
Because object of WelcomeFrame is not accessible.
You need to create another object before trying to call setVisible method.
WelcomeFrame closing_frame = new WelcomeFrame();
closing_frame.setVisible(false);
public class WelcomeFrame extends JFrame{
private JPanel contentPane;
private WelcomeFrame frame;
after
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new WelcomeFrame();
I think it'll help you
a CardLayout is more adapted to your needs; the general idea is to create a jPanel instead of a JFrame, the CardLayout enables you to switch between them by showing only one at a time. if this is what you need have alook here

Pass a String to another class

I'm writing an application where I need to get two String objects from the GUI to the nullObject class.
I'm relatively new to programming, and am trying my best to learn. If you have any tips on how to make this better, I'd be really thankful!
My GUI class:
package com.giuly.jsoncreate;
public class GUI {
private JFrame startFrame;
private JFrame chkFrame;
private JFrame osFrame;
private JFrame appVFrame;
private JPanel controlPanel;
private JButton nextPage;
private JButton cancel;
private JButton save;
public GUI() {
generateGUI();
}
public static void main(String[]args) {
GUI gui = new GUI();
}
public void generateGUI() {
//Creation of the First Frame
startFrame = new JFrame("JSCON Creator");
startFrame.setSize(1000, 700);
startFrame.setLayout(new FlowLayout());
startFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//Panel Creation
controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
//Button Creation
cancel = new JButton("Cancel");
cancel.setSize(100, 100);
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
nextPage = new JButton("Next");
nextPage.setSize(100, 100);
nextPage.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
startFrame.setVisible(false);
showText();
}
});
startFrame.add(controlPanel);
startFrame.add(cancel);
startFrame.add(nextPage);
startFrame.setVisible(true);
startFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public void showText() {
JFrame textFrame = new JFrame();
textFrame.setSize(1000, 700);
textFrame.setTitle("Text");
textFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JPanel textPanel = new JPanel();
JLabel titleLabel = new JLabel("Title");
textPanel.add(titleLabel);
JLabel descrLabel = new JLabel("Description");
JTextField tfTitle = new JTextField("",15);
tfTitle.setForeground(Color.BLACK);
tfTitle.setBackground(Color.WHITE);
JTextField tfDescr = new JTextField("",30);
tfDescr.setForeground(Color.BLACK);
tfDescr.setBackground(Color.WHITE);
textPanel.add(tfTitle);
textPanel.add(descrLabel);
textPanel.add(tfDescr);
JButton buttonOK = new JButton("OK");
textPanel.add(buttonOK);
buttonOK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String jsonTitle = tfTitle.getText();
String jsonDescr = tfDescr.getText();
System.exit(0);
}
});
textFrame.add(textPanel);
textFrame.setVisible(true);
}
I want to get the Strings jsonTitle and jsonDescr into another class, so I can store them. In the end I will have some Strings and I need to save them in a JSON file. I need a way to get those two Strings, what advice do you guys have?
Erick is correct with his answer. Just thought I should add additional info. If you declare jstonTitle and jsonDescr like your other fields using private you still will not be able to access these fields from another class. Coding up a getter for the fields along with declaring them at the top of GUI should solve your problem. Then just create an instance of GUI in your other class and call the method.
public String getJsonTitle(){
return this.jsonTitle;
}
You're declaring jstonTitle and jsonDescr inside the actionPerformed() method. That means that as soon as actionPerformed() exits you'll lose those variables. You need to declare them in an enclosing context. For example, you could make them fields on the GUI class. Still assign them in actionPerformed(), but declare them up at the top of GUI where you're declaring startFrame, chkFrame, etc.
That will give you the ability to access those values from anywhere within GUI.
Oh, BTW, get rid of System.exit(0);. (Have you actually tried to run your program?)

How to dynamically create JPanel with given parameters?

I have main JFrame in my project. And one main JPanel with Y-AXIS BoxLayout which is used to contain another panels in it. This is the way i use my JFrame to show this JPanel by default (I'm not quite convinced if this is the right way):
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
mainPanel = new MainScreenPanel();
MainFrame mainFrame = new MainFrame();
mainFrame.setContentPane(mainPanel);
mainFrame.invalidate();
mainFrame.validate();
mainFrame.setVisible(true);
}
});
}
Next I add two JPanels into mainPanel like this:
public class MainScreenPanel extends javax.swing.JPanel {
public MainScreenPanel() {
StatusPanel sPanel = new StatusPanel();
LogPanel lPanel = new LogPanel();
add(sPanel);
add(lPanel);
}
}
lPanel has different gui elements on it. One of them is a button which opens another panel (addConnectionPanel), and replaces mainPanel in the jFrame Here is the way i do it:
private void addCnctButtonActionPerformed(java.awt.event.ActionEvent evt) {
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
topFrame.setContentPane(new AddConnectionPanel());
topFrame.invalidate();
topFrame.validate();
}
AddConectionPanel has some labels and input text boxes. It has two buttons ok and cancel. Here is the code of cancel button:
private void cancelCnctBtnActionPerformed(java.awt.event.ActionEvent evt) {
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
topFrame.setContentPane(new MainScreenPanel());
topFrame.invalidate();
topFrame.validate();
}
sPanel is empty. It must be empty until input boxes on AddConnectionPanel are not filled and 'ok' button is not pressed. When these actions are performed, I want to dynamically create JLabels which take parameters from inputs on sPanel. Labels should be grouped, so when the actions performed second time new group must be created. Can some one give me advice on how to do this? And show me my mistakes? Keep in mind I'm using NetBeans.
This would be my approach:
public interface ConnectionPanelListener{
void onOkButtonClicked(String... options);
void onCancelButtonClicked();
}
public class AddConnectionPanel extends JPanel {
private static final long serialVersionUID = 1L;
private ConnectionPanelListener listener;
public AddConnectionPanel(){
final Map<ConnectionOptions, JTextField> components = new HashMap<>(ConnectionOptions.values().length);
for(ConnectionOptions option:ConnectionOptions.values()){
this.add(new JLabel(option.labelCaption));
JTextField textField = new JTextField();
//setup textField;
this.add(textField);
components.put(option, textField);
}
JButton button = new JButton("OK");
button.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(final MouseEvent pE) {
super.mouseClicked(pE);
//TODO validate TextFields
Collection<String> inputs = new Stack<>();
for(Entry<?,JTextField> e : components.entrySet()){
String text = e.getValue().getText();
if(text==null || text.trim().isEmpty()){
//TODO improve input validation
System.out.println("Input text is empty for: "+e.getKey());
} else {
inputs.add(e.getKey() + ": " + text);
}
}
listener.onOkButtonClicked(inputs.toArray(new String[inputs.size()]));
}
});
this.add(button);
button = new JButton("cancel");
button.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(final MouseEvent pE) {
super.mouseClicked(pE);
listener.onCancelButtonClicked();
}
});
this.add(button);
}
public void setConnectionPanelListener(final ConnectionPanelListener l){
listener = l;
}
private enum ConnectionOptions{
IP_ADDRESS("IP-Address:"), PORT("Port:"), WHATEVER_ATTRIBUTE_YOU_NEED("Extras:");
private String labelCaption;
private ConnectionOptions(final String caption) {
labelCaption = caption;
}
}
}
As you can see, AddConnectionPanel expects a Listener to register for the case, that "OK" or "CANCEL" are clicked. So your adjusted implementation could be like:
private void addCnctButtonActionPerformed(java.awt.event.ActionEvent evt) {
JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this);
AddConnectionPanel panel = new AddConnectionPanel();
panel.setConnectionPanelListener(new ConnectionPanelListener(){
#Override
void onOkButtonClicked(String... options){ TODO: fill sPanel using the given Strings }
#Override
void onCancelButtonClicked(){ TODO }
});
topFrame.setContentPane(panel);
topFrame.invalidate();
topFrame.validate();
}

use actionlistener to call void function in same class

I have problem to use action listener to call function void in same class.
example..
code:
public class Product extends JPanel {
JButton add;
JPanel pAdd;
JLabel test;
JFrame frame;
public Product() {
add = new JButton("Add Product");
add.addActionListener(new ButtonListener());
add(add);
}
public void panelAdd(){
pAdd = new JPanel();
pAdd.add(new JLabel("try"));
add(pAdd);
}
private class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
panelAdd();
}
}
}
How to make call the panelAdd void method?
When you add components to visible JFrame/JPanel/other components, you neet to call revalidate() andrepaint() methods after adding. Change your panelAdd() like next:
public void panelAdd(){
pAdd = new JPanel();
pAdd.add(new JLabel("try"));
add(pAdd);
revalidate();
repaint();
}
If you put
System.out.println("hi");
to
public void panelAdd(){
System.out.println("hi");
pAdd = new JPanel();
pAdd.add(new JLabel("try"));
add(pAdd);
}
you will see hi printed to your console , your code are working, but you have problem in Layout .

enabling/disabling a JFrame after hiding another JFrame

I have this 2 JFrame classes:
public class Frame1 extends javax.swing.JFrame {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
private JButton button1;
button1 = new JButton("Open Frame2");
private void button1ActionPerformed(java.awt.event.ActionEvent evt) {
this.setEnabled(false); // disable Frame1 until Frame2 is showing
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Frame2 obj2 = new Frame2 ();
obj2.setVisible(true);
}
});
}
}
public class Frame2 extends javax.swing.JFrame {
setDefaultCloseOperation(javax.swing.WindowConstants.HIDE_ON_CLOSE);
public Frame2 () {
this.setVisible(false);
}
Frame1 obj1 = new Frame1 ();
private JButton button2;
button2 = new JButton("Hide Frame2 and go to Frame1");
private void button2ActionPerformed(java.awt.event.ActionEvent evt) {
this.setVisible(false);
}
}
As you can see, when I click on button1 Frame1 gets disabled and Frame2 obj2 is created.
First of all I'd to know whether what I have done is a correct way to disable/defocus one parent JFrame to show another on top with focus.
And then I just need to enable Frame1 after hiding Frame2, something like obj1.setEnabled(true). How can I do that?
All what you have to do is to create an ref of your first class frame right inside it:
public 1_class_name obj;
//call the second class method getobj(o)
getobj(obj);
and then create a method and a ref in the second class frame:
1_class_name a;
public void getobj(1_class_name o){
a=o;
}
After you do that, you create a listener in the second class frame:
public void windowClosing(WindowEvent e) {
a.setEnabled(true);
dispose();
}
};
addWindowListener(exitListener);
It worked for me, I hope it will work for you too ;)

Categories