2

How they design i.e. JFileChooser?

JFileChooser chooser = new JFileChooser();
int returnVal = chooser.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
  System.out.println("You chose to open this file: " +
                chooser.getSelectedFile().getName());

How can I design such a frame with information exhange. For example, I have Frame1 and Frame2. Frame1 opens Frame2. Frame2 have a JTextArea where I will set some text and edit it. After pressing the ok button in frame2, it is closed and I want the text in a variable in Frame1.

Or say if I want to make a font chooser dialog.

JOptionPane is not a option for me. In frame2 I shall have a HTML editor. In frame1 I have JTable. Click a row on the table will open up the frame2 with HTML editor. I am using SHEF for this purpose. When I close the frame2 pressing OK/Save button, I want the html text String in frame1. And set the row content accordingly. But frame2 can be a modal dialog.

karim
  • 15,408
  • 7
  • 58
  • 96

4 Answers4

4

Start by having a read through The Use of Multiple JFrames: Good or Bad Practice?

Then have a read of How to make dialogs.

JFileChooser is a component that has a method that also displays a dialog. Your needs might be different, but it's not a bad pattern as it doesn't look your component into begin need to be always displayed on a dialog

Updated

You could use a JOptionPane

enter image description here

import java.awt.EventQueue;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestOptionPane12 {

    public static void main(String[] args) {
        new TestOptionPane12();
    }

    public TestOptionPane12() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JTextField field = new JTextField();
                int option = JOptionPane.showConfirmDialog(null, field, "Fill it out", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
                switch (option) {
                    case JOptionPane.OK_OPTION:
                        System.out.println("You entered " + field.getText());
                        break;
                }

            }

        });
    }

}

Or you could create a more custom solution...

enter image description here

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestOptionPane12 {

    public static void main(String[] args) {
        new TestOptionPane12();
    }

    public TestOptionPane12() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                FieldsPane pane = new FieldsPane();
                switch (pane.showDialog(null)) {
                    case JOptionPane.OK_OPTION:
                        String text = pane.getText();
                        System.out.println("You entered: " + text);
                        break;
                }                
            }
        });    
    }

    protected class FieldsPane extends JPanel {

        private JTextField field;
        private int state = JOptionPane.CANCEL_OPTION;

        public FieldsPane() {
            setLayout(new GridBagLayout());
            field = new JTextField(10);
            add(field);
        }

        public String getText() {
            return field.getText();
        }

        public int showDialog(Component parent) {

            JButton btnOkay = new JButton("Ok");
            JButton btnCancel = new JButton("Cancel");
            JPanel buttons = new JPanel();
            buttons.add(btnOkay);
            buttons.add(btnCancel);

            btnOkay.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    state = JOptionPane.OK_OPTION;
                    Window win = SwingUtilities.getWindowAncestor((Component)e.getSource());
                    win.dispose();
                }
            });
            btnCancel.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    state = JOptionPane.CANCEL_OPTION;
                    Window win = SwingUtilities.getWindowAncestor((Component)e.getSource());
                    win.dispose();
                }
            });

            JDialog dialog = new JDialog(parent == null ? (Window)null : SwingUtilities.getWindowAncestor(parent), "Fill it out");
            dialog.setModal(true);
            dialog.add(this);
            dialog.add(buttons, BorderLayout.SOUTH);
            dialog.pack();
            dialog.setLocationRelativeTo(null);
            dialog.setVisible(true);

            return state;            
        }        
    }    
}

Updated with JOptionPane and JEditorPane example

enter image description here

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestOptionPane12 {

    public static void main(String[] args) {
        new TestOptionPane12();
    }

    public TestOptionPane12() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JEditorPane editorPane = new JEditorPane("text/html", null);
                JScrollPane scrollPane = new JScrollPane(editorPane);
                scrollPane.setPreferredSize(new Dimension(200, 200));
                int option = JOptionPane.showConfirmDialog(null, scrollPane, "Fill it out", JOptionPane.OK_CANCEL_OPTION, -1);
                switch (option) {
                    case JOptionPane.OK_OPTION:
                        System.out.println("You entered " + editorPane.getText());
                        break;
                }

            }

        });
    }
}
Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 1
    Also consider the observer pattern in a modeless dialog, seen [here](http://stackoverflow.com/a/11832979/230513). – trashgod Jun 25 '13 at 08:55
  • I'll like to have JDialog. But still I need a pattern to handle the OK, Cancel or other events and get the text or other more objects in my Frame1 class. – karim Jun 25 '13 at 09:03
  • Start by creating component, maybe using `JPanel`, add you textfield to it. Provide a getter method to get the text. Create a method to create a dialog – MadProgrammer Jun 25 '13 at 10:14
  • Gotta love down votes with out comments. Help us out, leave a comment so we can discuss approach to fixing the problems – MadProgrammer Jun 25 '13 at 10:53
  • JOptionPane is not a option for me. I have added a bit more description of the issue in my question. – karim Jun 25 '13 at 10:57
  • Why is `JOptionPane` not a good option for you? The `message` parameter can take a `Component` which will be displayed in place of, what is normally, a `String`, for [example](http://stackoverflow.com/questions/12702689/joptionpane-displaying-html-problems-in-java/12702858#12702858) or [example](http://stackoverflow.com/questions/16450293/how-do-i-make-the-output-come-in-different-columns/16450826#16450826) – MadProgrammer Jun 25 '13 at 11:21
  • I think OP wants a general answer how to manage communication between different ui components. In this case, I would advocate my answer with "Event Driven Programming", but also the answer with mediator pattern is an good approach. – mrak Jun 25 '13 at 12:07
0

You can create special class that will hold result. Something like:

public class Result {
    private String result;

    public void setResult(String result) { ... }

    public String getResult() { ... }
}

Create instance of this class in first frame and pass it to second frame. Upon closing second frame sets result and then first frame can get it.

Mikita Belahlazau
  • 15,326
  • 2
  • 38
  • 43
0

Make it multiple dialogs instead of frames, and then read up about the mediator pattern :

http://blue-walrus.com/2013/06/mediator-pattern-in-swing/

Your basic problem is that you have a hierarchy of components, and a component on one branch wants to communicate with a component on another far away branch. You need some kind of mediator object to communicate between these far away branches.

Oliver Watkins
  • 12,575
  • 33
  • 119
  • 225
0

Have a look at "Event Driven Programming": Instead of tight coupling between components (every component must know every other component), you can send events and the components can respond to them.

mrak
  • 2,826
  • 21
  • 21