I made this sample:
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class JDialogTest extends JDialog implements ActionListener{
private boolean actionPerformed;
private JButton okButton;
private JTextField textField;
private JDialogTest(String title, JFrame frame){
super(frame, title, true);
setDefaultCloseOperation(HIDE_ON_CLOSE);
setMinimumSize(new Dimension(200, 200));
init();
}
public static String getInput(String title, JFrame frame){
JDialogTest input = new JDialogTest(title, frame);
input.setVisible(true);
while(true){
if(input.actionPerformed){
input.setVisible(false);
String text = input.textField.getText();
return text;
}
}
}
private void init(){
textField = new JTextField();
okButton = new JButton("OK");
okButton.addActionListener(this);
setLayout(new GridLayout(2, 1, 5, 5));
add(textField);
add(okButton);
pack();
}
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("click");
actionPerformed = true;
}
public static void main(String[] args) {
System.out.println(JDialogTest.getInput("Test", null));
}
}
I create new Dialog via a static method witch returns a string.
But the while-loop witch should detect if the button was pressed won't get started!
I know about JOptionPanes but I don't want to use them. I tried using a JFrame instead but it doesn't work if I try to init the Dialog inside of another JFrame/JDialog (it doesn't render).
With while(true) running in the same thread as the gui, is gonna to freeze your view, and is not the proper way you are using listeners. As your dialog is modal then the dialog has the flowcontrol.
Look at this SSCCE based in your example , with a few changes.
Example:
public class JDialogTest {
private JDialog dialog;
private JTextField textField;
private JDialogTest (String title, JFrame frame){
dialog = new JDialog(frame, title, true);
dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
dialog.setMinimumSize(new Dimension(200, 200));
init();
}
public void setVisible(Boolean flag){
dialog.setVisible(flag);
}
public static String getInput(String title, JFrame frame){
JDialogTest input = new JDialogTest (title, frame);
input.setVisible(true);
String text = input.textField.getText();
return text;
}
private void init(){
textField = new JTextField();
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
dialog.setLayout(new GridLayout(2, 1, 5, 5));
dialog.add(textField);
dialog.add(okButton);
dialog.pack();
}
public static void main(String args []){
String s = getInput("Dialog",null);
System.out.println(s);
}
}
Here is one possible solution. Take special note of the changes to the JDialogTest constructor, getInput() and actionPerformed().
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JDialogTest extends JDialog implements ActionListener{
private JButton okButton;
private JTextField textField;
private JDialogTest(String title, JFrame frame){
super(frame, title, true);
this.setModal(true); // Set the dialog as modal
setDefaultCloseOperation(HIDE_ON_CLOSE);
setMinimumSize(new Dimension(200, 200));
init();
}
public static String getInput(String title, JFrame frame){
JDialogTest input = new JDialogTest(title, frame);
input.setVisible(true);
return input.textField.getText(); // If this is executed, the dialog box has closed
}
private void init(){
textField = new JTextField();
okButton = new JButton("OK");
okButton.addActionListener(this);
setLayout(new GridLayout(2, 1, 5, 5));
add(textField);
add(okButton);
pack();
}
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("click");
setVisible(false); // Close the modal dialog box
}
public static void main(String[] args) {
System.out.println(JDialogTest.getInput("Test", null));
}
}
Again you wan to use a a modal JDialog and then query it for the text it holds once it has been dealt with. Since the dialog is modal, your calling application will know when the button has been pressed, if you make the dialog invisible within the button's ActionListener. This will then return control to the calling program. Your calling program can then query the dialog by calling a public method that you give it (here I called it getText() then then returns the String held by the dialog's JTextField.
For example, using your code...
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JDialogTest extends JDialog implements ActionListener {
// private boolean actionPerformed;
private JButton okButton;
private JTextField textField;
private JDialogTest(String title, JFrame frame) {
super(frame, title, true);
setDefaultCloseOperation(HIDE_ON_CLOSE);
setMinimumSize(new Dimension(200, 200));
init();
}
// public static String getInput(String title, JFrame frame) {
// JDialogTest input = new JDialogTest(title, frame);
// input.setVisible(true);
//
// while (true) {
// if (input.actionPerformed) {
// input.setVisible(false);
// String text = input.textField.getText();
// return text;
// }
// }
// }
private void init() {
textField = new JTextField();
okButton = new JButton("OK");
okButton.addActionListener(this);
// UGLY layout
setLayout(new GridLayout(2, 1, 5, 5));
add(textField);
add(okButton);
pack();
}
// I've added this method to allow outside methods to get text
public String getText() {
return textField.getText();
}
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("click");
// actionPerformed = true;
setVisible(false);
}
private static void createAndShowGui() {
final JTextField textField = new JTextField(20);
JFrame frame = new JFrame("Test JFrame");
final JDialogTest jDialogTest = new JDialogTest("Dialog", frame);
JButton button = new JButton(
new AbstractAction("Press Me to Show Dialog") {
#Override
public void actionPerformed(ActionEvent arg0) {
jDialogTest.setVisible(true); // code is frozen here
// until the dialog is no longer visible
// when code flow reaches here, we know that the dialog
// is no longer visible and
// we now can query our JDialog to get its text
textField.setText(jDialogTest.getText());
}
});
textField.setFocusable(false);
JPanel panel = new JPanel();
panel.add(button);
panel.add(textField);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Edit
If you want to display the dialog in a static way, change your getInput method to simply:
public static String getInput(String title, JFrame frame) {
JDialogTest input = new JDialogTest(title, frame);
input.setVisible(true);
return input.getText();
}
Changes to calling code:
final JTextField textField = new JTextField(20);
final JFrame frame = new JFrame("Test JFrame");
JButton button = new JButton(
new AbstractAction("Press Me to Show Dialog") {
#Override
public void actionPerformed(ActionEvent arg0) {
String result = JDialogTest.getInput("Get Input", frame);
textField.setText(result);
}
});
Edit 2
Note that JOptionPane works great:
String result = JOptionPane.showInputDialog(frame, "Please enter input:",
"Get Input", JOptionPane.PLAIN_MESSAGE);
Edit 3
You ask:
The solution in the edit seems to work but what method should I use in the action listener to close the JDialog and return the text?
The dialog button's ActionListener will make the dialog invisible by either calling setVisible(false) or dispose(). See my code above or nachokk's code for examples.
Related
I want to dispose a JDialog from another class, because i am trying to keep classes and methods clean, and not create buttons and handle the listeners in the same class. So here is the problem.
I tried creating a get method from the first class to get the dialog and then dispose it on the third but didnt work.
public class AddServiceListener extends JFrame implements ActionListener {
/**
* Creates listener for the File/New/Service button.
*/
public AddServiceListener() {
}
/**
* Performs action.
*/
public void actionPerformed(ActionEvent e) {
AddServiceWindow dialog = new AddServiceWindow();
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
}
}
public class AddServiceWindow extends JDialog {
private JPanel contentPanel;
private JFrame frame;
private JPanel buttonPanel;
private JLabel nameLabel;
private JTextField nameField;
private JLabel destinationLabel;
private JTextField destinationField;
private JButton destinationButton;
private JButton okButton;
private JButton cancelButton;
/**
* Creates the dialog window.
*/
public AddServiceWindow() {
ManageMinder mainFrame = new ManageMinder();
frame = mainFrame.getFrame();
contentPanel = new JPanel();
contentPanel.setLayout(null);
setTitle("New Service File");
setSize(340, 220);
setLocationRelativeTo(frame);
getContentPane().setLayout(new BorderLayout());
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
getContentPane().add(contentPanel, BorderLayout.CENTER);
buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
createLabels();
createTextFields();
createButtons();
addListeners();
}
/**
* Creates the labels.
*/
private void createLabels() {
nameLabel = new JLabel("Name:");
nameLabel.setHorizontalAlignment(SwingConstants.RIGHT);
nameLabel.setBounds(25, 25, 52, 16);
contentPanel.add(nameLabel);
destinationLabel = new JLabel("Path:");
destinationLabel.setHorizontalAlignment(SwingConstants.RIGHT);
destinationLabel.setBounds(7, 70, 70, 16);
contentPanel.add(destinationLabel);
}
/**
* Creates the text fields.
*/
private void createTextFields() {
nameField = new JTextField();
nameField.setBounds(87, 22, 220, 22);
contentPanel.add(nameField);
nameField.setColumns(10);
destinationField = new JTextField();
destinationField.setBounds(87, 68, 220, 20);
contentPanel.add(destinationField);
destinationField.setColumns(10);
}
/**
* Creates the buttons of the window.
*/
private void createButtons() {
destinationButton = new JButton("Select...");
destinationButton.setBounds(87, 99, 82, 23);
destinationButton.setFocusPainted(false);
contentPanel.add(destinationButton);
okButton = new JButton("OK");
okButton.setFocusPainted(false);
buttonPanel.add(okButton);
cancelButton = new JButton("Cancel");
cancelButton.setFocusPainted(false);
buttonPanel.add(cancelButton);
}
/**
* Adds listeners to buttons.
*/
private void addListeners() {
ActionListener destinationAction = new AddDestinationListener(destinationField);
destinationButton.addActionListener(destinationAction);
ActionListener okAction = new SaveNewServiceFileListener(nameField, destinationField);
okButton.addActionListener(okAction);
}
}
public class SaveNewServiceFileListener extends JFrame implements ActionListener {
private JTextField nameField;
private JTextField destinationField;
private String path;
private File newService;
/**
* Creates listener for the File/New/Add Service/OK button.
*/
public SaveNewServiceFileListener(JTextField nameField, JTextField destinationField) {
this.nameField = nameField;
this.destinationField = destinationField;
}
/**
* Performs action.
*/
public void actionPerformed(ActionEvent e) {
path = destinationField.getText() + "\\" + nameField.getText() + ".csv";
try {
newService = new File(path);
if(newService.createNewFile()) {
System.out.println("Done!");
// DISPOSE HERE
}
else {
System.out.println("Exists!");
}
} catch (IOException io) {
throw new RuntimeException(io);
}
}
}
What should i do, so the dialog disposes on the third one, when OK is clicked and file is created?
The way to change the state of another object is to 1) have a reference to that object, and 2) call a public method on it.
Here the other object is the JDialog, and the state that you wish to change is its visibility by calling either .close() or .dispose() on it. The problem that you're having is that the reference to the JDialog is not readily available since it is buried within the actionPerformed(...) method of your AddServiceListener class.
So don't do this -- don't bury the reference but rather put it into a field of the class that needs it.
If you absolutely need to have stand-alone ActionListener classes, then I think that the simplest thing to do is to take the dialog out of the listener class and into the view class, your main GUI, and then have the listener call methods on the view. For example
Assume that the dialog class is called SomeDialog and the main GUI is called MainGui. Then put the reference to the dialog in the MainGui class:
public class MainGui extends JFrame {
private SomeDialog someDialog = new SomeDialog(this);
And rather than have your listeners create the dialog, have them call a method in the main class that does this:
public class ShowDialogListener implements ActionListener {
private MainGui mainGui;
public ShowDialogListener(MainGui mainGui) {
// pass the main GUI reference into the listener
this.mainGui = mainGui;
}
#Override
public void actionPerformed(ActionEvent e) {
// tell the main GUI to display the dialog
mainGui.displaySomeDialog();
}
}
Then MainGUI can have:
public void displaySomeDialog() {
someDialog.setVisible(true);
}
An example MRE program could look like so:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.*;
import javax.swing.*;
public class FooGui002 {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MainGui mainGui = new MainGui();
mainGui.setVisible(true);
});
}
}
#SuppressWarnings("serial")
class MainGui extends JFrame {
private SomeDialog someDialog;
private JButton showSomeDialogButton = new JButton("Show Some Dialog");
private JButton closeSomeDialogButton = new JButton("Close Some Dialog");
public MainGui() {
super("Main GUI");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setPreferredSize(new Dimension(500, 200));
someDialog = new SomeDialog(this);
showSomeDialogButton.addActionListener(new ShowDialogListener(this));
showSomeDialogButton.setMnemonic(KeyEvent.VK_S);
closeSomeDialogButton.addActionListener(new CloseSomeDialogListener(this));
closeSomeDialogButton.setMnemonic(KeyEvent.VK_C);
setLayout(new FlowLayout());
add(showSomeDialogButton);
add(closeSomeDialogButton);
pack();
setLocationByPlatform(true);
}
public void displaySomeDialog() {
someDialog.setVisible(true);
}
public void closeSomeDialog() {
someDialog.setVisible(false);
}
}
#SuppressWarnings("serial")
class SomeDialog extends JDialog {
public SomeDialog(Window window) {
super(window, "Some Dialog", ModalityType.MODELESS);
setPreferredSize(new Dimension(300, 200));
add(new JLabel("Some Dialog", SwingConstants.CENTER));
pack();
setLocationByPlatform(true);
}
}
class ShowDialogListener implements ActionListener {
private MainGui mainGui;
public ShowDialogListener(MainGui mainGui) {
this.mainGui = mainGui;
}
#Override
public void actionPerformed(ActionEvent e) {
mainGui.displaySomeDialog();
}
}
class CloseSomeDialogListener implements ActionListener {
private MainGui mainGui;
public CloseSomeDialogListener(MainGui mainGui) {
this.mainGui = mainGui;
}
#Override
public void actionPerformed(ActionEvent e) {
mainGui.closeSomeDialog();
}
}
I have two frames with contents . The first one has a jlabel and jbutton which when it is clicked it will open a new frame. I need to repaint the first frame or the panel that has the label by adding another jlabel to it when the second frame is closed.
//Edited
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class FirstFrame extends JPanel implements KeyListener{
private static String command[];
private static JButton ok;
private static int count = 1;
private static JTextField text;
private static JLabel labels[];
private static JPanel p ;
private static JFrame frame;
public int getCount(){
return count;
}
public static void createWindow(){
JFrame createFrame = new JFrame();
JPanel panel = new JPanel(new GridLayout(2,1));
text = new JTextField (30);
ok = new JButton ("Add");
ok.requestFocusInWindow();
ok.setFocusable(true);
panel.add(text);
panel.add(ok);
text.setFocusable(true);
text.addKeyListener(new FirstFrame());
createFrame.add(panel);
createFrame.setVisible(true);
createFrame.setSize(600,300);
createFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
createFrame.setLocationRelativeTo(null);
createFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.out.println(command[count]);
if(command[count] != null){
p.add(new JLabel("NEW LABEL"));
p.revalidate();
p.repaint();
count++;
System.out.println(count);
}
}
});
if(count >= command.length)
count = 1;
ok.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(command[count] == null)
command[count] = text.getText();
else
command[count] = command[count]+", "+text.getText();
text.setText("");
}
});
}
public FirstFrame(){
p = new JPanel();
JButton create = new JButton ("CREATE");
command = new String[2];
labels = new JLabel[2];
addKeyListener(this);
create.setPreferredSize(new Dimension(200,100));
//setLayout(new BorderLayout());
p.add(new JLabel("dsafsaf"));
p.add(create);
add(p);
//JPanel mainPanel = new JPanel();
/*mainPanel.setFocusable(false);
mainPanel.add(create);
*/
create.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
createWindow();
}
});
//add(mainPanel, BorderLayout.SOUTH);
}
public static void main(String[] args) {
frame = new JFrame();
frame.add(new FirstFrame());
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER)
if(ok.isDisplayable()){
ok.doClick();
return;}
}
}
}
});
}
}
As per my first comment, you're better off using a dialog of some type, and likely something as simple as a JOptionPane. For instance in the code below, I create a new JLabel with the text in a JTextField that's held by a JOptionPane, and then add it to the original GUI:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class FirstPanel2 extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = 300;
private JTextField textField = new JTextField("Hovercraft rules!", 30);
private int count = 0;
public FirstPanel2() {
AddAction addAction = new AddAction();
textField.setAction(addAction);
add(textField);
add(new JButton(addAction));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class AddAction extends AbstractAction {
public AddAction() {
super("Add");
}
#Override
public void actionPerformed(ActionEvent e) {
String text = textField.getText();
final JTextField someField = new JTextField(text, 10);
JPanel panel = new JPanel();
panel.add(someField);
int result = JOptionPane.showConfirmDialog(FirstPanel2.this, panel, "Add Label",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
JLabel label = new JLabel(someField.getText());
FirstPanel2.this.add(label);
FirstPanel2.this.revalidate();
FirstPanel2.this.repaint();
}
}
}
private static void createAndShowGui() {
FirstPanel2 mainPanel = new FirstPanel2();
JFrame frame = new JFrame("My Gui");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Also, don't add KeyListeners to text components as that is a dangerous and unnecessary thing to do. Here you're much better off adding an ActionListener, or as in my code above, an Action, so that it will perform an action when the enter key is pressed.
Edit
You ask:
Just realized it is because of the KeyListener. Can you explain please the addAction ?
This is functionally similar to adding an ActionListener to a JTextField, so that when you press enter the actionPerformed(...) method will be called, exactly the same as if you pressed a JButton and activated its ActionListener or Action. An Action is like an "ActionListener" on steroids. It not only behaves as an ActionListener, but it can also give the button its text, its icon and other properties.
I have tried to add my jPanel to a jDialog and when I trigger the button nothing happens. Why? I have the code below:
public class fontFormat{
public void fontPanel(){
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.getPreferredSize();
Dimension size = new Dimension();
size.width = 400;
size.height = 600;
panel.setPreferredSize(size);
panel.add(new JLabel("label"));
panel.add(new JButton("button"));
JDialog fontDialog = new JDialog();
fontDialog.add(fontDialog);
}
}
Here:
JDialog fontDialog = new JDialog();
fontDialog.add(fontDialog);
You appear to be trying to add your JDialog to itself, which should cause your code to not function. While this code may compile, running this method should cause the JVM to throw an IllegalArgumentException on the fontDialog.add(fontDialog); line.
Please note that you show a JDialog similar to how you show a JFrame:
When you call your JDialog constructor, you will want to pass in the parent window into it, especially if your desire is to display a modal dialog.
You will also want to pass into the constructor the correct ModalityType enum.
You give your JDialog content, often a JPanel with your components on it.
You pack it
then you call setVisible(true) on it, and it should display
For example,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogEg {
private static void createAndShowGUI() {
MainPanelGen mainPanelGen = new MainPanelGen();
JFrame frame = new JFrame("DialogEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanelGen.getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
class MainPanelGen {
private JPanel mainPanel = new JPanel();
private JTextField field = new JTextField(10);
private JButton btn = new JButton(new BtnActn());
private JDialog dialog;
private DialogPanel dialogPanel = new DialogPanel();
public MainPanelGen() {
mainPanel.add(field);
mainPanel.add(btn);
field.setEditable(false);
field.setFocusable(false);
}
public JPanel getMainPanel() {
return mainPanel;
}
private class BtnActn extends AbstractAction {
BtnActn() {
super("Button");
}
#Override
public void actionPerformed(ActionEvent arg0) {
if (dialog == null) {
Window win = SwingUtilities.getWindowAncestor(mainPanel);
if (win != null) {
dialog = new JDialog(win, "My Dialog",
Dialog.ModalityType.APPLICATION_MODAL);
dialog.getContentPane().add(dialogPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
}
}
dialog.setVisible(true); // here the modal dialog takes over
System.out.println (dialogPanel.getFieldText());
field.setText(dialogPanel.getFieldText());
}
}
}
class DialogPanel extends JPanel {
private JTextField field = new JTextField(10);
private JButton exitBtn = new JButton(new ExitBtnAxn("Exit"));
public DialogPanel() {
add(field);
add(exitBtn);
}
public String getFieldText() {
return field.getText();
}
private class ExitBtnAxn extends AbstractAction {
public ExitBtnAxn(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent arg0) {
Window win = SwingUtilities.getWindowAncestor(DialogPanel.this);
if (win != null) {
win.dispose();
}
}
}
}
I'm having a JTextField problem. I am needing to get text from a JTextField and modify it later in a JDialog. I am using the same variable for the JTextField. As long as you don't enter the dialog, the string printed is whatever you entered in the text field. If you enter a string in the dialog, it will only print that string until you change it again in the dialog (renders the primary text field useless). I can fix this by adding a separate variable, but would like to try to avoid unnecessary declarations. I was under the impression that this shouldn't matter since I'm creating a new JTextField object and also disposing of the dialog. Am I missing something? Any thoughts?
Here is a mock up of my problem.
import java.awt.event.*;
import javax.swing.*;
public class textfield extends JPanel {
private JTextField textfield;
private JButton printButton, dialogButton, okayButton;
private static JFrame frame;
public static void main(String[] args) {
frame = new JFrame();
frame.setSize(200,200);
frame.getContentPane().add(new textfield());
frame.setVisible(true);
}
private textfield() {
textfield = new JTextField(10);
add(textfield);
((AbstractButton) add(printButton = new JButton("Print"))).addActionListener(new printListener());
((AbstractButton) add(dialogButton = new JButton("Dialog"))).addActionListener(new dialogListener());
}
private class printListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String string = null;
string = textfield.getText();
System.out.println(string);
}
}
private class dialogListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
final JDialog dialog = new JDialog(frame, "Dialog", true);
JPanel p = new JPanel();
textfield = new JTextField(10);
p.add(textfield);
p.add(okayButton = new JButton(new AbstractAction("Okay") {
public void actionPerformed(ActionEvent e) {
String string = null;
string = textfield.getText();
System.out.println(string);
dialog.dispose();
}
}));
dialog.add(p);
dialog.pack();
dialog.setVisible(true);
}
}
}
you need to make JTextField inside the dialog, because when you are using one textfield, your main panel will point to new JTextField that was created in child dialog that was disposed when you press okey button (destroyed all its components). so don't change panel textfield pointer to new textfield object in disposed window.
your variable private JTextField textfield; is used twice, firstly for JFrame, and second time for JDialod, little bit changed ..
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class MyTextfield extends JPanel {
private static final long serialVersionUID = 1L;
private JTextField textfield, textfield1; //added new variable
private JButton printButton, dialogButton, okayButton;
private static JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {//added initial thread
#Override
public void run() {
frame = new JFrame();
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//added default close operation
frame.getContentPane().add(new MyTextfield());
frame.setVisible(true);
}
});
}
private MyTextfield() {
textfield = new JTextField(10);
add(textfield);
((AbstractButton) add(printButton = new JButton("Print"))).addActionListener(new printListener());
((AbstractButton) add(dialogButton = new JButton("Dialog"))).addActionListener(new dialogListener());
}
private class printListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String string = null;
string = textfield.getText();
System.out.println(string);
}
}
private class dialogListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
final JDialog dialog = new JDialog(frame, "Dialog", true);
JPanel p = new JPanel();
textfield1 = new JTextField(10);
p.add(textfield1);
p.add(okayButton = new JButton(new AbstractAction("Okay") {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
String string = null;
textfield.setText(textfield1.getText());
System.out.println(string);
dialog.dispose();
}
}));
dialog.add(p);
dialog.pack();
dialog.setVisible(true);
}
}
}
i have a situation where i show a dialog where user has to fill some menus and then press OK. It works fine, but now i have another button on this dialog that if user wants to add some certain value, i want another dialog to popup where user fills the additional value and while pressing ok, this dialog disappears and user comes back to the main dialog.
I have tried this, but every time i call the new dialog, the focus does not go away from the main dialog, how can i do such a task.
Is there any relevant example or what is the proper way of doing such things.
EDIT:
public static class EdgeMenu extends JPopupMenu {
// private JFrame frame;
public MyMenu(final JFrame frame) {
super("My Menu");
// this.frame = frame;
this.addSeparator();
this.add(new EdgePropItem(frame));
}
}
//this shows the first dialog, another class because i have some other
//functions to be performed here
public static class EdgePropItem extends JMenuItem{
//...
public EdgePropItem(final JFrame frame) {
super("Edit Properties");
this.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
EdgePropertyDialog dialog = new EdgePropertyDialog(frame, edge);
dialog.setVisible(true);
}
});
}
}
and now in other dialog, in the button even listener i am trying to call another dialog:
private void newDialogHandler(java.awt.event.ActionEvent evt) {
MyNewDialog rdialog = new MyNewDialog(edge);
rdialog.setVisible(true);
}
It appears fine, but the previous dialog, does not leave the focus, and it goes away only if i press finish/done on that dialog, what i want is the new dialog to come in focus, while pressing ok on here, focus should come back to the old main dialog, but it is not working?
maybe this code could be demonstate your issues,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SuperConstructor extends JFrame {
private static final long serialVersionUID = 1L;
public SuperConstructor() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(300, 300));
setTitle("Super constructor");
Container cp = getContentPane();
JButton b = new JButton("Show dialog");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
FirstDialog firstDialog = new FirstDialog(SuperConstructor.this);
}
});
cp.add(b, BorderLayout.SOUTH);
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
System.exit(0);
}
});
add(bClose, BorderLayout.NORTH);
pack();
setVisible(true);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
SuperConstructor superConstructor = new SuperConstructor();
}
});
}
private class FirstDialog extends JDialog {
private static final long serialVersionUID = 1L;
FirstDialog(final Frame parent) {
super(parent, "FirstDialog");
setPreferredSize(new Dimension(200, 200));
setLocationRelativeTo(parent);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
JButton bNext = new JButton("Show next dialog");
bNext.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
SecondDialog secondDialog = new SecondDialog(parent, false);
}
});
add(bNext, BorderLayout.NORTH);
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
setVisible(false);
}
});
add(bClose, BorderLayout.SOUTH);
pack();
setVisible(true);
}
}
private int i;
private class SecondDialog extends JDialog {
private static final long serialVersionUID = 1L;
SecondDialog(final Frame parent, boolean modal) {
//super(parent); // < --- Makes this dialog
//unfocusable as long as FirstDialog is visible
setPreferredSize(new Dimension(200, 200));
setLocation(300, 50);
setModal(modal);
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setTitle("SecondDialog " + (i++));
JButton bClose = new JButton("Close");
bClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
setVisible(false);
}
});
add(bClose, BorderLayout.SOUTH);
pack();
setVisible(true);
}
}
}
You can achieve this as follows:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JOptionPane;
public class MultipleDialogs
{
public MultipleDialogs()
{
JButton btnOpen = new JButton("Open another dialog!");
btnOpen.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(null, "This is the second dialog!");
}
});
Object[] options = {"OK", "Cancel", btnOpen};
int selectedOption = JOptionPane.showOptionDialog(null,
"This is the first dialog!", "The title",
JOptionPane.NO_OPTION, JOptionPane.PLAIN_MESSAGE,
null, options, options[0]);
if(selectedOption == 0) // Clicking "OK"
{
}
else if(selectedOption == 1) // Clicking "Cancel"
{
}
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new MultipleDialogs();
});
}
}
}
You can replace "This is the first dialog!" and "This is the second dialog!" with JPanel's which can contain any swing components you want.
Create the second dialog from a constructor that takes dialog and boolean as parameters and that solves the problem.