I've made a program which prints a value in a text field. The problem is that when a user right clicks in the text field, a menu like this won't open:
Is there a way the user can have this menu open upon right click?
This is my code:
public class A extends JFrame{
private JTextField txt1;
private JTextField txt2;
private JLabel val;
private JLabel prt;
private JButton bt1;
public A() {
getContentPane().setLayout(null);
txt1 = new JTextField();
txt1.setBounds(178, 93, 87, 28);
getContentPane().add(txt1);
txt2 = new JTextField();
txt2.setBounds(178, 148, 87, 28);
getContentPane().add(txt2);
val = new JLabel("Enter Value");
val.setBounds(84, 93, 69, 28);
getContentPane().add(val);
prt = new JLabel("Printed Value");
prt.setBounds(80, 148, 87, 28);
getContentPane().add(prt);
bt1 = new JButton("Click This");
bt1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int n=Integer.parseInt(txt1.getText());
txt2.setText(n+"");
}
});
bt1.setBounds(178, 188, 105, 28);
getContentPane().add(bt1);
setSize(400, 399);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
}
Main Method:
public class Main {
public static void main(String[] args) {
A object = new A();
}
}
Read the Swing tutorial on How to Use Menus for the basics of creating a popup menu.
Then you can use the Actions provided by the DefaultEditorKit to create your popup menu.
For the "Delete" action you will need to create your own custom Action. Read the Swing tutorial on How to Use Actions for the basics. Except you would extend TextAction since it has methods that allow you to access the text component with focus so you can create reusable code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
public class TextFieldPopup extends JPanel
{
public TextFieldPopup()
{
JTextField textField = new JTextField(10);
add( textField );
JPopupMenu menu = new JPopupMenu();
Action cut = new DefaultEditorKit.CutAction();
cut.putValue(Action.NAME, "Cut");
cut.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control X"));
menu.add( cut );
Action copy = new DefaultEditorKit.CopyAction();
copy.putValue(Action.NAME, "Copy");
copy.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control C"));
menu.add( copy );
Action paste = new DefaultEditorKit.PasteAction();
paste.putValue(Action.NAME, "Paste");
paste.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control V"));
menu.add( paste );
Action selectAll = new SelectAll();
menu.add( selectAll );
textField.setComponentPopupMenu( menu );
}
static class SelectAll extends TextAction
{
public SelectAll()
{
super("Select All");
putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control S"));
}
public void actionPerformed(ActionEvent e)
{
JTextComponent component = getFocusedComponent();
component.selectAll();
component.requestFocusInWindow();
}
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("TextFieldPopup");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TextFieldPopup() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Static class to instantly add regular popup menu to a textfield.
import javax.swing.*;
import java.awt.event.ActionEvent;
import javax.swing.undo.*;
public class JTextFieldRegularPopupMenu {
public static void addTo(JTextField txtField)
{
JPopupMenu popup = new JPopupMenu();
UndoManager undoManager = new UndoManager();
txtField.getDocument().addUndoableEditListener(undoManager);
Action undoAction = new AbstractAction("Undo") {
#Override
public void actionPerformed(ActionEvent ae) {
if (undoManager.canUndo()) {
undoManager.undo();
}
else {
System.out.println("No Undo Buffer.");
}
}
};
Action copyAction = new AbstractAction("Copy") {
#Override
public void actionPerformed(ActionEvent ae) {
txtField.copy();
}
};
Action cutAction = new AbstractAction("Cut") {
#Override
public void actionPerformed(ActionEvent ae) {
txtField.cut();
}
};
Action pasteAction = new AbstractAction("Paste") {
#Override
public void actionPerformed(ActionEvent ae) {
txtField.paste();
}
};
Action selectAllAction = new AbstractAction("Select All") {
#Override
public void actionPerformed(ActionEvent ae) {
txtField.selectAll();
}
};
cutAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control X"));
copyAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control C"));
pasteAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control V"));
selectAllAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control A"));
popup.add (undoAction);
popup.addSeparator();
popup.add (cutAction);
popup.add (copyAction);
popup.add (pasteAction);
popup.addSeparator();
popup.add (selectAllAction);
txtField.setComponentPopupMenu(popup);
}
}
Usage:
JTextFieldRegularPopupMenu.addTo(jTxtMsg);
Instantly adds popup menu to the chosen JTextFIeld.
I'd start with How to use menus and Bringing Up a Popup Menu (although I'd personally use JComponent#setComponentPopupMenu instead of a MouseListener)
Then I'd have a look at JTextField#copy, JTextField#cut and JTextField#paste
Related
How do I make Action Handler ignore arrow keys? Currently, when I try to use arrow keys to navigate my combo box, the combo box moves down/up once, changes the selection, and then triggers the Action Handler moving the focus to the button.
I would like to be able to navigate the combo box with the arrow keys, and hit Enter when I'm ready to move on to the next component.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class test {
JFrame window = new JFrame("testGUI");
JPanel windowPanel = new JPanel();
public static JLabel labelSize;
public static JComboBox<String> comboSize;
public static JLabel labelButton;
public static JButton buttonButton;
public test () {
super();
labelSize = new JLabel("Monster Size:");
String[] sizeChoices = { "None", "Tiny", "Small", "Medium", "Large", "Huge", "Colossal"};
comboSize = new JComboBox<String>(sizeChoices);
comboSize.setToolTipText("The creature's size.");
comboSize.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
comboSize.showPopup();
}
}
#Override
public void keyReleased(KeyEvent e) {
comboSize.showPopup();
}
#Override
public void keyPressed(KeyEvent e) {
}
});
labelButton = new JLabel("Button:");
buttonButton = new JButton();
buttonButton.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER)
buttonButton.doClick();
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
buttonButton.doClick();
}
});
windowPanel.setLayout(new FlowLayout());
windowPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
windowPanel.add(labelSize);
windowPanel.add(comboSize);
windowPanel.add(labelButton);
windowPanel.add(buttonButton);
windowPanel.setVisible(true);
window.setSize(500, 500);
window.setLayout(new FlowLayout());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.add(windowPanel);
comboSize.addActionListener(handler);
buttonButton.addActionListener(handler);
}
ActionHandler handler = new ActionHandler();
public class ActionHandler implements ActionListener {
public void actionPerformed(ActionEvent eventFocus){
if (eventFocus.getSource() == comboSize){
buttonButton.requestFocusInWindow();
}
if (eventFocus.getSource() == buttonButton){
comboSize.requestFocusInWindow();
}
}
}
#SuppressWarnings("unused")
public static void main(String[] args) {
test GUITest = new test();
}
}
the combo box moves down/up once, changes the selection, and then triggers the Action Handler moving the focus to the button. I would like to be able to navigate the combo box with the arrow keys, and hit Enter when I'm ready to move on to the next component.
You can set a property on the combo box to only generate the ActionEvent when Enter is pressed by using the following:
comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
Complete example:
/*
This works on non editable combo boxes
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
import javax.swing.text.*;
public class ComboBoxAction extends JFrame implements ActionListener
{
public ComboBoxAction()
{
JComboBox<String> comboBox = new JComboBox<String>();
comboBox.addActionListener( this );
comboBox.addItem( "Item 1" );
comboBox.addItem( "Item 2" );
comboBox.addItem( "Item 3" );
comboBox.addItem( "Item 4" );
// This prevents action events from being fired when the
// up/down arrow keys are used on the dropdown menu
comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
getContentPane().add( comboBox );
getContentPane().add( new JTextField(), BorderLayout.SOUTH );
}
public void actionPerformed(ActionEvent e)
{
System.out.println( e.getModifiers() );
JComboBox comboBox = (JComboBox)e.getSource();
System.out.println( comboBox.getSelectedItem() );
// make sure popup is closed when 'isTableCellEditor' is used
// comboBox.hidePopup();
}
public static void main(String[] args)
{
ComboBoxAction frame = new ComboBoxAction();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible( true );
}
}
See Combo Box No Action for more information.
I worked on a simple project on my own, which was to develop a calculator using Java, but I am getting the wrong output:
When I press button 1--> 1
When I press button 2-->2
When I press button 1-->11 (This is wrong) It should display 121 not 11
When I press button 2-->22
I asked everyone, I looked over my code and I could not find the solution. Most people say my code's logic is code.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JTextField;
public class ButtonListener implements ActionListener {
JTextField text;
String display = "";
String button[];
JButton buttons[];
public ButtonListener(JTextField text, String[] button, JButton[] buttons) {
this.text = text;
this.button = button;
this.buttons = buttons;
}
public void Display(String button) {
display = display + button;
// return display;
}
public void actionPerformed(ActionEvent Buttonpress) {
/******************** Constants ********************/
// Planks Constant
if (Buttonpress.getSource() == buttons[0]) {
// display+=button[0];
Display(button[0]);
}
// Elementary Charge
if (Buttonpress.getSource() == buttons[8]) {
// display+=Buttonpress.getSource();
Display(button[8]);
}
text.setText(display);
}
}
First of all method names should NOT start with an upper case character. "Display" should be "display".
Don't keep arrays of buttons and strings to determine which button was clicked and which text should be appended.
You can get all the information you need to update your display text field from the ActionEvent itself.
Here is an example for you to look at:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class CalculatorPanel extends JPanel
{
private JTextField display;
public CalculatorPanel()
{
Action numberAction = new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
// display.setCaretPosition( display.getDocument().getLength() );
display.replaceSelection(e.getActionCommand());
}
};
setLayout( new BorderLayout() );
display = new JTextField();
display.setEditable( false );
display.setHorizontalAlignment(JTextField.RIGHT);
add(display, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout(0, 5) );
add(buttonPanel, BorderLayout.CENTER);
for (int i = 0; i < 10; i++)
{
String text = String.valueOf(i);
JButton button = new JButton( text );
button.addActionListener( numberAction );
button.setBorder( new LineBorder(Color.BLACK) );
button.setPreferredSize( new Dimension(50, 50) );
buttonPanel.add( button );
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke(text), text);
inputMap.put(KeyStroke.getKeyStroke("NUMPAD" + text), text);
button.getActionMap().put(text, numberAction);
}
}
private static void createAndShowUI()
{
// UIManager.put("Button.margin", new Insets(10, 10, 10, 10) );
JFrame frame = new JFrame("Calculator Panel");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new CalculatorPanel() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
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.
I have created an ActionListener and the button but the button doesn't work.
The action listener is supposed to be integrated with the submit button, please help?
Code:
import javax.swing.*;
import javax.swing.event.DocumentListener;import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Executer {
private JLabel lblCommand;
private JTextField txtEnter;
private JButton btNext, btPrevious, btSubmit;
private JPanel panel;
public static void main(String[] args) {
new Executer();
}
public Executer() {
JFrame frame = new JFrame("Script Executer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,300);
frame.setVisible(true);
myPanel();
Text();
Fields();
Buttons();
frame.add(panel);
frame.setVisible(true);
}
public void myPanel() {
panel = new JPanel();
panel.setLayout(null);
}
public void Text() {
lblCommand = new JLabel("Enter Here");
lblCommand.setBounds(145, 100, 150, 20);
Font styleOne = new Font("Arial", Font.BOLD, 13);
lblCommand.setFont(styleOne);
panel.add(lblCommand);
}
public void Fields() {
txtEnter = new JTextField();
txtEnter.setBounds(230, 100, 120, 20);
panel.add(txtEnter);
}
public void Buttons() {
btNext = new JButton ("Next");
btNext.setBounds(300,215,100,20);
panel.add(btNext);
btPrevious = new JButton ("Previous");
btPrevious.setBounds(190,215,100,20);
panel.add(btPrevious);
btSubmit = new JButton("Submit");
btSubmit.setBounds(80,215,100,20);
panel.add(btSubmit);
btSubmit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String userEntered = txtEnter.getText();
if(userEntered.equalsIgnoreCase("yes"))
{
//run your script
}
}
});
}
}
Your code appears fine.
Enter a print statement and you can see it is working.
btSubmit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// here the click happend so you can check your Textfield
String userEntered = txtEnter.getText();
System.out.println("User enterd: " + userEntered);
if(userEntered.equalsIgnoreCase("yes"))
{
System.out.println("Entered Yes");
}
}
});
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.