0

I have one JDialog in which there is one Main Jpanel called "dialogPane".

This JPanel "dialogPane" has below 2 JPanels

  1. ContentPanel which contains JTextArea
  2. buttonBar which contains progress bar and one toggle button.

Now my use case is

  1. On Click Of Toggle Button On/Off , TextArea should be made hidden(on)/displayed(off).
  2. When toggle button is clicked , JTextArea should be hidden and the Dialog size should be reduced (small)
  3. When toggle button is clicked again, JTextArea should be shown and Dialog Should be Resized (big)

Below is my actionListener for the Toggle Button. My code just removes the JTextArea but the size of the dialog is still big

private void ShowOrHideLogToggleButtonItemStateChanged(final ItemEvent e) {
        final int state = e.getStateChange();
        if (state == ItemEvent.SELECTED) {
            ShowOrHideLogToggleButton.setText("Show Log");
            dialogPane.remove(contentPanel);
            dialogPane.updateUI();
            dialogPane.revalidate();
            dialogPane.repaint();

        } else {
            ShowOrHideLogToggleButton.setText("Hide Log");
            dialogPane.add(contentPanel);
            dialogPane.updateUI();
            dialogPane.revalidate();
            dialogPane.repaint();
            this.pack();
        }
    }

Note : ContentPanel is the Jpanel which contains the JTextArea and dialogPane is the parent JPanel which contains ContentPanel

Below is my JDialog hierarchy

Minimal, Complete, and Verifiable example (Code To Reproduce The Problem)

package CollectionsPractice;

        import java.awt.BorderLayout;
        import java.awt.Container;
        import java.awt.Dialog;
        import java.awt.Dimension;
        import java.awt.Frame;
        import java.awt.GridBagConstraints;
        import java.awt.GridBagLayout;
        import java.awt.Insets;
        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.JProgressBar;
        import javax.swing.JScrollPane;
        import javax.swing.JTextArea;
        import javax.swing.JToggleButton;
        import javax.swing.WindowConstants;
        import javax.swing.border.EmptyBorder;

/**
 * @author User #2
 */
public class Main
{
    public static void main(String[] args) {
        JDialog myDialog=new JDialog();
        new UpdateDialog(myDialog);
    }
}
 class UpdateDialog extends JDialog {


    public UpdateDialog(final JDialog owner) {
        super(owner);
        initComponents();
        resultTextPane.setText("Sample Text In Result Text Area");
    }

    private void ShowOrHideLogToggleButtonActionPerformed(final ActionEvent e) {
        final JToggleButton btn = (JToggleButton) e.getSource();
        if (btn.isSelected()) {
            btn.setText("Hide Myy Log");
            contentPanel.setVisible(true);
        } else {
            btn.setText("Show Myy Log");
            contentPanel.setVisible(false);
        }
    pack();
    }

    private void initComponents() {
        // JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
        dialogPane = new JPanel();
        contentPanel = new JPanel();
        scrollPane1 = new JScrollPane();
        resultTextPane = new JTextArea();
        buttonBar = new JPanel();
        progressBar = new JProgressBar();
        ShowOrHideLogToggleButton = new JToggleButton();
        logoutButton = new JButton();

        //======== this ========
        setTitle("Updater");
        setAlwaysOnTop(true);
        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        setMinimumSize(new Dimension(1024, 800));
        setVisible(true);
        setName("this");
        final Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());

        //======== dialogPane ========
        {
            dialogPane.setBorder(new EmptyBorder(12, 12, 12, 12));
            dialogPane.setMinimumSize(new Dimension(640, 480));
            dialogPane.setName("dialogPane");
            dialogPane.setLayout(new BorderLayout());

            //======== contentPanel ========
            {
                contentPanel.setVisible(false);
                contentPanel.setName("contentPanel");
                contentPanel.setLayout(new BorderLayout());

                //======== scrollPane1 ========
                {
                    scrollPane1.setName("scrollPane1");

                    //---- resultTextPane ----
                    resultTextPane.setEditable(false);
                    resultTextPane.setName("resultTextPane");
                    scrollPane1.setViewportView(resultTextPane);
                }
                contentPanel.add(scrollPane1, BorderLayout.CENTER);
            }
            dialogPane.add(contentPanel, BorderLayout.CENTER);

            //======== buttonBar ========
            {
                buttonBar.setBorder(new EmptyBorder(12, 0, 0, 0));
                buttonBar.setName("buttonBar");
                buttonBar.setLayout(new GridBagLayout());
                ((GridBagLayout) buttonBar.getLayout()).columnWeights = new double[]{1.0, 0.0, 0.0};

                //---- progressBar ----
                progressBar.setStringPainted(true);
                progressBar.setName("progressBar");
                buttonBar.add(progressBar, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                        new Insets(0, 0, 0, 5), 0, 0));

                //---- ShowOrHideLogToggleButton ----
                ShowOrHideLogToggleButton.setText("Show Log");
                ShowOrHideLogToggleButton.setName("ShowOrHideLogToggleButton");
                ShowOrHideLogToggleButton.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(final ActionEvent e) {
                        ShowOrHideLogToggleButtonActionPerformed(e);
                    }
                });
                buttonBar.add(ShowOrHideLogToggleButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
                        GridBagConstraints.BOTH, new Insets(0, 0, 0, 5), 0, 0));

                //---- logoutButton ----
                logoutButton.setText("Logout");
                logoutButton.setEnabled(false);
                logoutButton.setName("logoutButton");
                buttonBar.add(logoutButton, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                        new Insets(0, 0, 0, 0), 0, 0));
            }
            dialogPane.add(buttonBar, BorderLayout.SOUTH);
        }
        contentPane.add(dialogPane, BorderLayout.CENTER);
        pack();
        setLocationRelativeTo(getOwner());
        // JFormDesigner - End of component initialization  //GEN-END:initComponents
    }

    // JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
    private JPanel dialogPane;
    private JPanel contentPanel;
    private JScrollPane scrollPane1;
    private JTextArea resultTextPane;
    private JPanel buttonBar;
    private JProgressBar progressBar;
    private JToggleButton ShowOrHideLogToggleButton;
    private JButton logoutButton;
    // JFormDesigner - End of variables declaration  //GEN-END:variables
}
LearnerForLife
  • 147
  • 1
  • 12

2 Answers2

1

What you need to do is to repack your window. Here is my example:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;


public class WindowRepack implements Runnable {

    private static final String TEXT =
            "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod "
                    + "tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
                    + "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd "
                    + "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem "
                    + "ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod "
                    + "tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
                    + "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd "
                    + "gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";

    private final JTextArea area = new JTextArea(5, 40);

    private final JScrollPane scroller = new JScrollPane(area);

    private final JPanel mainPanel = new JPanel(new BorderLayout());

    @Override
    public void run() {
        area.setText(TEXT);
        area.setLineWrap(true);
        area.setWrapStyleWord(true);
        JToggleButton tb = new JToggleButton("Show text");
        tb.addActionListener(this::updateUI);
        JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
        buttonsPanel.add(tb);

        // provide fix width for the buttons panel to avoid horizontal scaling of window.
        Dimension defSize = buttonsPanel.getPreferredSize();
        // temporary make the scroll bar visible to compute the correct width
        scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        buttonsPanel.setPreferredSize(new Dimension(scroller.getPreferredSize().width, defSize.height));
        scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        // done

        mainPanel.add(buttonsPanel, BorderLayout.NORTH);
        JFrame frm = new JFrame("Dynamic frame");
        frm.add(mainPanel);
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.pack();
        frm.setLocationRelativeTo(null);
        frm.setVisible(true);
    }

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

    private void updateUI(ActionEvent evt) {
        JToggleButton btn = (JToggleButton) evt.getSource();
        if (btn.isSelected()) {
            btn.setText("Hide text");
            mainPanel.add(scroller);
        } else {
            btn.setText("Show text");
            mainPanel.remove(scroller);
        }
        Window w = SwingUtilities.windowForComponent(mainPanel);
        w.pack();
    }
}

I've made it using JFrame, but the same approach will also work for a JDialog.

Important: this way will only work, when you use correct layout manager to fill your dialog.

Sergiy Medvynskyy
  • 11,160
  • 1
  • 32
  • 48
1

First of all, updateUI method, most of the times it is not required to be called. repaint() and revalidate() methods in the proper containers is a better practice.

Secondly, i would not take the add/remove container approach (depends on how many components and what layout manager your container - JDialog uses). I would take the visible/not visible approach.

I have made a SSCCE in order to make it more clear. It is just the way i personally prefer for such things. Take a look if you want. Some extra comments inside the code.

Also, as @Sergiy Medvynskyy metioned, things that work on a JFrame, works on a JDialog too.

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;

public class TestFrame extends JFrame {
    private static final long serialVersionUID = 1965751967944243251L;

    public TestFrame() {
        super("A Frame");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        getContentPane().setLayout(new BorderLayout());
        JToggleButton toggleButton = new JToggleButton("Show log");
        JTextArea textArea = new JTextArea();
        for (int i = 0; i < 144; i++) {
            textArea.append("This is the text area log!\n");
        }
        JPanel panelWithTextArea = new JPanel(new BorderLayout());
        JScrollPane sp = new JScrollPane(textArea);
        sp.setPreferredSize(new Dimension(sp.getPreferredSize().width, 300)); //Max height for textarea
        panelWithTextArea.add(sp);
        panelWithTextArea.setVisible(false); //Initially invisible
        //Add the item listener to toggleButton
        toggleButton.addItemListener(e -> {
            if (toggleButton.isSelected()) {
                panelWithTextArea.setVisible(true); //Make it visible
                toggleButton.setText("Hide Log");
            } else {
                panelWithTextArea.setVisible(false); //Back to invisible
                toggleButton.setText("Show Log");
            }
            pack(); //Repack the frame after component is visible
        });
        getContentPane().add(toggleButton, BorderLayout.PAGE_START);
        getContentPane().add(panelWithTextArea, BorderLayout.CENTER);
        setLocationRelativeTo(null);
        pack();

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            TestFrame f = new TestFrame();
            f.setVisible(true);
        });
    }
}

Tiny preview:

Preview

George Z.
  • 6,643
  • 4
  • 27
  • 47