How can I make a JFrame modal like a JOptionPane?

2019-02-19 08:25发布

问题:

First, I will make the question and then I will explain the application.

How can I make JFrames to behave like JOptionPanes? (tutorial didn't help) i.e.

[Show content >> return a value]. Aditionally I need it to be

[Show the frame >> Ask information >> Modify an object passed as parameter to the constructor >> return something]

I already made the "Ok" button get the answer i want (displaying it in the console), but i cant figure out where to put the return statement

i want the function to be something like

public static String getAnswer(Args, Answer)

Args, may contain name of the field, type of data, maximum lenght, and

Answer, is the object to be modified, after the user gives the information and clicks "ok"

There is always and argument and an answer for it. e.g. (look at the screenshot, to see how the "most complex" type of message I need to display, it is incomplete though, because it needs to display different kind of components depending on the data type).

| Arg                  |   Answer     |
--------------------------------------
| Type   | fldName     |              |
--------------------------------------
| int    | Age:        | 22           |
| String | Name:       | Roger        |
| Date   | Birth:      | 31/10/1989   |

What i did so far, is to display a JFrame (which is the dialog) with the desired content and make a button to show me the answer in console.

How do I build the JFrame? I have 4 classes, three of the classes are described below the screenshot and the last one, build a JPanel that contains the three other panels and add it to the JFrame. If you want to see the code click.

Why I dont use JDialog, because it needs a parent frame which I dont have. I need to display this from another not java application, so this, must already be the top frame.



You may not want to read this but if you are interested in reading what i'm i doing, please go ahead:

Im aware, that by using JOptionPane.showMessageDialog() and so on, my problem may be solved, but I cant figure out hot to make it fit my needs. The content showed on a JOptionPane seems limited to me and I don't know how to keep control nor reference to the childrens I put into it, everything changes its behaviour .

I have to make five different dialogs that would return values to another application (painful oracle forms 6i). The types of dialogs are:

  • Print dialog, which shows a list of printers or the option "Export to file"
  • Message dialog, shows html content (like an e-mail preview) and has an "Ok" button.
  • Yes/No dialog, asks for a confirmation from the user, works like message dialog.
  • Parameter form, asks the user to give some information, the information it asks, is based on a select or an array of strings.
  • List of values, based on a select statement, shows the result just like plsql developer would do.

Here is a screenshot of the last item (Parameter form), in the example, evey item is type Month, and the answer would be filled with its value.

As you can see, the frame is divided by 3 blocks (which I made as 3 classes TopPanel, MidPanel and BotPanel): Message dialog, User inputs and command buttons respectively.

TopPanel, extends from JScrollPane and creates a JEditorPane, cuz it may show html content

MidPanel, extends from JScrollPane (this one, is created only for the last two dialogs in the list) and creates fields based on an object that forms pass as parameters to be asked to the user, the input to this, need to be checked in java as it can be a date, a textField or a combo box based on a select statement (in the picture, there are the 12 months of the year based on a query to the database).

BotPanel has the controls for the answer that java would give to forms, say, the list of parameters or the answer to a Yes/No dialog. This panels, changes with every kind of dialog. e.g. For a yes/no dialog, it has "Yes" and "No" buttons that will make java, return true or false, but for a parameter form dialog, it would return an error message if ocurred and the Object that contains the information that the user choosed.

回答1:

Again, you can put any complex gui into a JOptionPane. The JOptionPane show method's second parameter takes an Object which can be any Swing component. For example:

import java.awt.*;
import java.util.HashMap;
import java.util.Map;

import javax.swing.*;

import com.roots.map.MapPanel.ControlPanel;

public class ComplexDialog extends JPanel {
   public static final String[] COMBO_LABELS = { "Nombre 1",
         "Identificacion 1", "Fecha 1", "Empresa 1", "Nombre 2",
         "Identificacion 2", "Fecha 2", "Empresa 2", "Nombre 3",
         "Identificacion 3", "Fecha 3", "Empresa 3", "Nombre 4",
         "Identificacion 4", "Fecha 4", "Empresa 4", "Nombre 5",
         "Identificacion 5", "Fecha 5", "Empresa 5", "Nombre 6",
         "Identificacion 6", "Fecha 6", "Empresa 6", "Nombre 7",
         "Identificacion 7", "Fecha 7", "Empresa 7" };
   public static final String[] COMBO_ITEMS = { "January", "February", "March",
         "April", "May", "June", "July", "August", "September", "October",
         "November", "December" };
   private JTextArea textarea = new JTextArea(15, 30);
   private Map<String, JComboBox> comboMap = new HashMap<String, JComboBox>();

   public ComplexDialog() {
      textarea.setLineWrap(true);
      textarea.setWrapStyleWord(true);
      for (int i = 0; i < 100; i++) {
         textarea.append("This is a really large text. ");
      }

      JPanel comboPanel = new JPanel(new GridBagLayout());
      for (int i = 0; i < COMBO_LABELS.length; i++) {
         addToComboPanel(comboPanel, COMBO_LABELS[i], i);
      }

      int eb = 5;
      setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      add(new JScrollPane(textarea));
      add(Box.createVerticalStrut(5));
      JScrollPane comboPanelScroll = new JScrollPane(comboPanel);
      add(comboPanelScroll);

      comboPanelScroll.getViewport().setPreferredSize(
            textarea.getPreferredSize());
   }

   private void addToComboPanel(JPanel comboPanel, String labelText, int index) {
      GridBagConstraints gbc = new GridBagConstraints(0, index, 1, 1, 0.2, 1.0,
            GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0,
                  0, 5), 0, 0);
      comboPanel.add(new JLabel(labelText, SwingConstants.RIGHT), gbc);

      gbc = new GridBagConstraints(1, index, 1, 1, 1.0, 1.0,
            GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL, new Insets(
                  0, 0, 0, 0), 0, 0);
      JComboBox combo = new JComboBox(COMBO_ITEMS);
      comboMap.put(labelText, combo);
      comboPanel.add(combo, gbc);

   }

   public String getComboChoice(String key) {
      JComboBox combo = comboMap.get(key);
      if (combo != null) {
         return combo.getSelectedItem().toString();
      } else {
         return "";
      }
   }

   public String getTextAreaText() {
      return textarea.getText();
   }

   public int showDialog() {
      return JOptionPane.showOptionDialog(null, this, "Sirena",
            JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null,
            new String[] { "Aceptar", "Cancelar" }, "Aceptar");
   }

   private static void createAndShowGui() {
      ComplexDialog dlg = new ComplexDialog();
      int response = dlg.showDialog();
      if (response == 0) {
         System.out.println("JTextArea's text is:");
         System.err.println(dlg.getTextAreaText());

         System.out.println("Combo box selections are: ");
         for (String comboLabel : COMBO_LABELS) {

            System.out.printf("%20s: %s%n", comboLabel, dlg.getComboChoice(comboLabel));
         }
      }
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}