0

I have uploaded a specific portion of my code and i hope that this will suffice to understand my problem. I'm using the p6 panel in a frame which has multiple buttons and one of the buttons display this panel.

This panel p6 has two buttons. One clicking check_api, the program requires some time to execute and to the user, it would seem as if the application has hung. Therefore I tried adding a method which would show a waiting message while the button is busy. But on doing that, my panels lose their user defined size.

Is there a way to display a wait message without compromising on my panel size?

public static void prepare_url(JPanel p6, JPanel content, int count) {
    InnerOperations.removeexcept(6, content);
    if (count != 1) {
        p6.removeAll();
        p6.revalidate();
        System.out.println("Count is greater than 1");
    }
    JPanel p_back = new JPanel();
    JTextField field = new JTextField(" Enter url(s) with delimiter ';'");
    JButton check_list = new JButton(" CHECK URL LIST STATUS");
    JButton check_api = new JButton(" CHECK  PREDEFINED API LIST");
    p_back.add(check_list);
    p_back.add(field);
    p_back.add(l_check);
    p_back.add(check_api);
    check_api.setBounds(200, 130, 400, 30);
    l_check.setBounds(50, 300, 600, 20);
    field.setBounds(200, 50, 400, 30);
    check_list.setBounds(200, 90, 400, 30);
    p6.add(p_back);
    p_back.setBounds(0, 0, 800, 600);
    check_list.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {

            String url_pref 
            String list[] = url_pref.split(";");
            int i = 0;
            while (i < list.length) {
                try {
                    // thread1.start();
                    prepareurl(p6, p_back, list, list.length);
                    // thread1.stop();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                i++;

            }
        }
    });
    check_api.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            // thread2.start();
            // p_back.removeAll();
            //check_api.setText("Will load in a while");
            prepare_api(p6, content, p_back);
            // thread2.stop();

        }
    });

}
public static void userwait(JPanel ppanel)
{
    JLabel waiting = new JLabel();
    ppanel.add(waiting);
    waiting.setText("Please Wait......");
    waiting.setBounds(200, 200, 400, 30);
}   
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Arvind Sudheer
  • 113
  • 1
  • 1
  • 14
  • You can show the text on top of your components. To do it you need to use [GlassPane](https://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html). [Here](http://www.java2s.com/Code/Java/Swing-JFC/DemonstrateuseofGlassPane.htm) is another example. – Sergiy Medvynskyy Jun 20 '18 at 07:36
  • 1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Jun 20 '18 at 11:51
  • Thank you guys ! Will make sure to use your suggestions . – Arvind Sudheer Jun 21 '18 at 04:49

2 Answers2

0

Executing long running task in the EDT is generally a bad idea - use SwingWorker instead ,see example Improve Application Performance With SwingWorker. You could just display some text before starting the worker thread and disable the buttons to prevent the user to click again:

public class SwingworkerExample extends JFrame {

    private JButton startBtn = new JButton("Start");
    private JProgressBar progressBar = new JProgressBar(0, 100);
    private JLabel progressLbl = new JLabel("");
    private JLabel statusLbl = new JLabel("");

    public static void main(String... args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                SwingworkerExample swe = new SwingworkerExample("SwingWorker: progress");
                swe.setVisible(true);
            }
        });
    }

    public SwingworkerExample(String title) {
        super(title);
        setupUI();
        startBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                startWorkerThread();
            }
        });
    }

    private void startWorkerThread() {
        // Disable JButton:
        startBtn.setEnabled(false);
        // Show info
        statusLbl.setText("running...");
        progressLbl.setText("...");

        /*
         * Create SwingWorker<Boolean, Integer> where
         * Boolean : type for thread result, use "Void" if no return value
         * Integer : type for published values
         */
        SwingWorker<Boolean, Integer> swingWorker = new SwingWorker<Boolean, Integer>() {

            @Override
            protected Boolean doInBackground() throws Exception {
                // WARN: do not update the GUI from within doInBackground(), use process() / done()!

                // Do something ... 
                // prepareurl(p6, p_back, list, list.length);
                // 
                for (int i = 0; i <= 100; i++) {
                    Thread.sleep((int) (Math.random() * 60));
                    // Use publish to send progress information to this.process() [optional]
                    publish(i);
                }
                return true;
            }

            @Override
            protected void process(List<Integer> chunks) {
                // handle published progress informations / update UI
                StringBuilder sb = new StringBuilder();
                chunks.forEach(val -> sb.append(" ").append(val));
                progressLbl.setText(String.format("processing: %s%n", sb));
                int progress = chunks.get(chunks.size() - 1);
                progressBar.setValue(progress);
            }

            @Override
            protected void done() {
                // Swingworker finished - update UI / handle result
                try {
                    Boolean result = get();
                    statusLbl.setText("DONE. Result= " + result);
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                    statusLbl.setText("Error: " + e.getMessage());
                }
                // Enable JButton
                startBtn.setEnabled(true);
            }
        };
        swingWorker.execute();
    } // end: startWorkerThread

    private void setupUI() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(240, 160);
        setLayout(new GridBagLayout());
        GridBagConstraints gc = new GridBagConstraints();
        gc.fill = GridBagConstraints.BOTH;
        gc.weightx = 1;
        gc.weighty = 1;
        gc.gridx = 0;
        gc.weighty = 1;

        gc.gridy = 0;
        add(startBtn, gc);

        gc.gridy = 1;
        add(progressBar, gc);

        gc.gridy = 2;
        add(statusLbl, gc);

        gc.gridy = 3;
        add(progressLbl, gc);
    }
}
Lones NB
  • 49
  • 1
  • 4
  • Thank you , i've already fixed the issue by spawning a new thread which creates a new frame and then closes it once the button is free. Thanks for the help tho :) – Arvind Sudheer Jun 21 '18 at 04:50
0

A couple of options:

  1. You could use an indeterminate JProgressBar. See the section from the Swing tutorial on How to Use Progress Bars for more information and working examples.

  2. You could use a GlassPane to display the message on top of the panel. See Disabled Glass Pane for an example of this approach.

camickr
  • 321,443
  • 19
  • 166
  • 288