0

I would like to put a JTree inside a JDialog so that the user can select an item on the tree hierarchy and confirm selection by clicking the OK button. The user can cancel the selection by clicking the CANCEL button.

What is the easiest way to get that dialog in a Java Swing app?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
The_Cute_Hedgehog
  • 1,280
  • 13
  • 22
  • 1
    Have you researched this already? Can you show us your code and explain where you are stuck? Google results like [this question](https://stackoverflow.com/questions/11260926/how-to-add-components-to-jdialog), [that question](https://stackoverflow.com/questions/789517/java-how-to-create-a-custom-dialog-box), or [this tutorial](http://www2.hawaii.edu/~takebaya/ics111/jdialog/jdialog.html) indicate that a dialog can be easily modified like a JFrame; and that JOptionPane can make it quicker to implement. – Malte Hartwig Dec 04 '17 at 16:39
  • Hi, I specifically searched for a JTree example. Sorry about that. The links you provided are perfectly fine to follow up. Thanks for that. – The_Cute_Hedgehog Dec 04 '17 at 16:47
  • @The_Cute_Hedgehog, `I specifically searched for a JTree example.` - did you read the JTree API? The API has a link to the Swing Tutorial, which contains working examples of all Swing components. – camickr Dec 04 '17 at 16:53

1 Answers1

0

Try this: first create a App like this:

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;

public class App {

    private JFrame frame;
    private JTextField textField;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    App window = new App();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public App() {
        initialize();
    }

    public void setValue(Object obj) {
        textField.setText(obj.toString());
    }

    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JButton btnOpen = new JButton("Open");
        btnOpen.setBounds(100, 57, 177, 43);
        btnOpen.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                new MyDialog(App.this).setVisible(true);
            }
        });
        frame.getContentPane().setLayout(null);
        frame.getContentPane().add(btnOpen);

        textField = new JTextField();
        textField.setBounds(100, 126, 177, 19);
        frame.getContentPane().add(textField);
        textField.setColumns(10);
    }
}

Then in the same package create MyDialog:

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.DefaultMutableTreeNode;

public class MyDialog extends JDialog {

    private final JPanel contentPanel = new JPanel();
    private JTree tree = null;


    public MyDialog(App ref) {
        setModalityType(ModalityType.APPLICATION_MODAL);
        setTitle("MyDialog");
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        getContentPane().setLayout(new BorderLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);
        contentPanel.setLayout(new BorderLayout(0, 0));

        {
            tree = new JTree();
            contentPanel.add(tree);
        }
        {
            JPanel buttonPane = new JPanel();
            buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
            getContentPane().add(buttonPane, BorderLayout.SOUTH);
            {
                JButton okButton = new JButton("OK");
                okButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {
                        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                        if (node == null)
                            return;
                        Object userObject = node.getUserObject();

                        ref.setValue(userObject);
                        MyDialog.this.dispose();
                    }
                });
                okButton.setActionCommand("OK");
                buttonPane.add(okButton);
                getRootPane().setDefaultButton(okButton);
            }
            {
                JButton cancelButton = new JButton("Cancel");
                cancelButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {
                        MyDialog.this.dispose();
                    }
                });
                cancelButton.setActionCommand("Cancel");
                buttonPane.add(cancelButton);
            }
        }
    }
}

App will deply a Dialog with a tree. If you select a tree node and hit "ok" it'll close the dialog and show the value in the App's textfield. "cancel" will abort the whole process. It works for me.

hope it helps

assembler
  • 3,098
  • 12
  • 43
  • 84
  • Wow, thanks for the code. However, the previous link given by @Malte Hartwig (https://stackoverflow.com/questions/789517/java-how-to-create-a-custom-dialog-box) seems a lot reasonable in terms of re-using JOptionPane. Thanks. – The_Cute_Hedgehog Dec 04 '17 at 16:54