1

For my current project I need a custom dialog that allows the user to select a value and get a custom preview of its details. I tried writing my own window class that extends JFrame but up until now I'm stuck at the most important part: how do I show the dialog's window, let the user do his input and then return the selected value?

I tried looking into the code of JOptionPane.showInputDialog but I got confused instead of understanding how that works.

Here's an sscce for my problem:

import java.util.Vector;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextArea;

public class MyCustomDialog extends JFrame {
    JComboBox<MyCustomObject> comboBox;
    JTextArea details;

    public MyCustomDialog(Vector<MyCustomObject> data) {
        comboBox = new JComboBox<>(data);
        comboBox.setSelectedIndex(-1);
        comboBox.setEditable(false);
        comboBox.addActionListener(ActionEvent -> updateDetails());
        getContentPane().add(comboBox);

        details = new JTextArea();
        details.setEditable(false);
        details.setOpaque(false);
        getContentPane().add(details);

        setVisible(true);
    }

    void updateDetails() {
        int selectedIndex = comboBox.getSelectedIndex();
        if(selectedIndex < 0) {
            details.setText("");
            return;
        }

        MyCustomObject selected = comboBox.getItemAt(selectedIndex);
        details.setText(selected.getDescription());
    }

    static MyCustomObject showDialog(Vector<MyCustomObject> vec) {
        // this is where I'm stuck

        // showDialog needs to:
        // 1. create the frame and show it to the user
        // 2. let the user choose a value and also change their selection multiple times
        // 3. let the user confirm the selection, for example with a button
        // 4. return the selected value

        return null;
    }

    public static void main(String... args) {
        Vector<MyCustomObject> vec = new Vector<>();
        vec.add(new MyCustomObject("Test Object 1", "Test Information 1"));
        vec.add(new MyCustomObject("Test Object 2", "Test Information 2"));
        System.out.println(showDialog(vec) + " was selected.");
    }

    public static class MyCustomObject {
        final String description;
        final String name;

        public MyCustomObject(String name, String description) {
            this.name = name;
            this.description = description;
        }

        String getDescription() { return description; }

        @Override
        public String toString() { return name; }
    }
}

Updated code thanks to trashgod's answer

import java.util.Vector;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class MyCustomDialog extends JPanel {
    JComboBox<MyCustomObject> comboBox;
    JTextArea details;

    MyCustomDialog(Vector<MyCustomObject> data) {
        comboBox = new JComboBox<>(data);
        comboBox.setSelectedIndex(-1);
        comboBox.setEditable(false);
        comboBox.addActionListener(ActionEvent -> updateDetails());
        add(comboBox);

        details = new JTextArea();
        details.setEditable(false);
        details.setOpaque(false);
        add(details);
    }

    void updateDetails() {
        int selectedIndex = comboBox.getSelectedIndex();
        if(selectedIndex < 0) {
            details.setText("");
            return;
        }

        MyCustomObject selected = comboBox.getItemAt(selectedIndex);
        details.setText(selected.getDescription());
    }

    static MyCustomObject showDialog(Vector<MyCustomObject> vec) {
        MyCustomDialog dialog = new MyCustomDialog(vec);

        int result = JOptionPane.showConfirmDialog(null, dialog, "Test Dialog", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
        if (result == JOptionPane.OK_OPTION) {
            int selectedIndex = comboBox.getSelectedIndex();
            if (selectedIndex >= 0) return comboBox.getItemAt(selectedIndex);
        }

        return null;
    }

    public static void main(String... args) {
        Vector<MyCustomObject> vec = new Vector<>();
        vec.add(new MyCustomObject("Test Object 1", "Test Information 1"));
        vec.add(new MyCustomObject("Test Object 2", "Test Information 2"));
        System.out.println(showDialog(vec) + " was selected.");
    }

    public static class MyCustomObject {
        final String description;
        final String name;

        public MyCustomObject(String name, String description) {
            this.name = name;
            this.description = description;
        }

        String getDescription() { return description; }

        @Override
        public String toString() { return name; }
    }
}
mezzodrinker
  • 998
  • 10
  • 28
  • 1) It's not an SSCCE of a run-time problem unless it runs and shows the code on-screen. That code would require (at least) a `main(String[])` method in order for others to see it on screen. 2) So to clarify, you mean a detail/edit dialog showing the `MyCustomObject`? – Andrew Thompson Oct 08 '15 at 16:48
  • @AndrewThompson concerning 2): Not a detail and _edit_ dialog but rather a detail and _select_ dialog. You're not supposed to edit any of the `MyCustomObject` instances. – mezzodrinker Oct 08 '15 at 16:52
  • See also [*Initial Threads*](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). – trashgod Oct 08 '15 at 17:01
  • @trashgod I'm sorry, but how is that supposed to help me with getting the user's input after and only after they did an action to submit their input (e.g. pressing a button)? – mezzodrinker Oct 08 '15 at 17:05
  • @flashdrive2049: Your program is incorrectly synchronized; it's behavior is in indeterminate; see also this [example](http://stackoverflow.com/a/3002830/230513) using `JOptionPane`. – trashgod Oct 08 '15 at 22:46
  • @trashgod So what you're trying to say is that there's no option other than using `JOptionPane`? – mezzodrinker Oct 08 '15 at 23:09
  • @trashgod Anyhow, that link you provided helped me a big deal. Thanks. – mezzodrinker Oct 08 '15 at 23:35
  • @flashdrive2049: You are welcome; I've elaborated below. – trashgod Oct 09 '15 at 01:13

1 Answers1

3

How do I show the dialog's window, let the user do his input and then return the selected value?

The usual approach is to use a modal dialog; JOptionPane, seen here, is a convenient way to handle this usage. More examples may be found here.

Is there's no option other than using JOptionPane?

You can use a JDialog, with or without a JOptionPane, as shown here and here, respectively.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045