1

I want to attached the progress bar to the Frame and not the test start button that I have currently. The progress bar works but I want it run when the window is opened for the time being and then I can attach it to whatever I want later on.

Code:

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.JProgressBar;
import javax.swing.JButton;

public class ProgressBarWindow extends JFrame {
    private static final long serialVersionUID = 1L;
    private JPanel contentPane;

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

    public ProgressBarWindow() {
        try {
             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
        } catch(Exception e) { }

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 183);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JProgressBar progressBar = new JProgressBar();
        progressBar.setBounds(22, 77, 386, 27);
        contentPane.add(progressBar);

        JButton btnNewButton = new JButton("Cancel");
        btnNewButton.setBounds(319, 111, 89, 23);
        btnNewButton.addMouseListener(new myMouseListener2());
        contentPane.add(btnNewButton);

        JButton btnStart = new JButton("Start");
        btnStart.addActionListener(new btnDoAction(progressBar));
        btnStart.setBounds(220, 111, 89, 23);
        contentPane.add(btnStart);
    }
}

class myClose implements MouseListener {
    myClose() { }

    @Override
    public void mouseClicked(MouseEvent e) {
         final Component source = e.getComponent();
         final JFrame frame = (JFrame) SwingUtilities.getRoot(source);
         frame.dispose();
    }

    @Override
    public void mousePressed(MouseEvent e) {
         final Component source = e.getComponent();
         final JFrame frame = (JFrame) SwingUtilities.getRoot(source);
         frame.dispose();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }
}

class btnDoAction implements ActionListener{
    JProgressBar temp = new JProgressBar();

    btnDoAction(JProgressBar p) {
        this.temp = p;
    }

    public void actionPerformed (ActionEvent e){
        new Thread(new thread1(temp)).start(); //Start the thread
    }
}

class thread1 implements Runnable{
    JProgressBar pBar = new JProgressBar();

    thread1(JProgressBar u) {
        this.pBar = u;
    }

    public void run(){
        for (int i=0; i<=100; i++){ //Progressively increment variable i
            pBar.setValue(i); //Set value
            pBar.repaint(); //Refresh graphics
            try{Thread.sleep(50);} //Sleep 50 milliseconds
            catch (InterruptedException err){}
        }
    }
}

enter image description here

Doug Hauf
  • 3,025
  • 8
  • 46
  • 70
  • 1
    Don't use null layouts, don't use mouse listeners on buttons, don't update the UI from any thread other then the Event Dipatching Thread, see [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for more details – MadProgrammer May 19 '14 at 20:38
  • 1
    What should be used on a button (ActionListener). The null layout is the Absolute Layout. That is normally what the boss tells use to use. Which layout is the best for this type of situation. – Doug Hauf May 19 '14 at 20:41
  • 1
    How would this be better done if I didn't update the UI from the thread1. – Doug Hauf May 19 '14 at 20:42
  • Tell your boss that he needs to learn how to use layout managers in order to be able to develop professional cross platform applications. And yes, an ActionListener is what you should be using, it will take into account users clicking it and pressing enter/space on it – MadProgrammer May 19 '14 at 20:43
  • 1
    See the link provided in the first comment for more ideas – MadProgrammer May 19 '14 at 20:49
  • what would be the best layout manager for this application? – Doug Hauf May 19 '14 at 20:50
  • 1
    See also the `SplashScreen` class as discussed [here](http://stackoverflow.com/a/5360889/418556). It is possible to gain control of the window that shows the splash and draw components on top. – Andrew Thompson May 19 '14 at 21:12
  • Personally, I'd use a GridBagLayout – MadProgrammer May 19 '14 at 21:13
  • Which are the best layouts to use, and which ones should be used. I wonder why people always use the Absolute Layout Manager. – user3491862 May 20 '14 at 15:24

1 Answers1

3

If I understand correctly, instead of using a JFrame as you base component, extend your class from a JPanel, this way you can add it to anything you want.

You could then provide setter and getter methods to adjust the progress bar, but I'd do this via some kind of interface contract .

  • Don't use null layouts. You don't control aspects like fonts, font metrics, rendering pipelines and other properties which effect the amount of space components need in order to be rendered properly across multiple systems (even those running the same OS)
  • Don't use MouseListeners on buttons, use ActionListeners instead. To takes into account when the use clicks on the button and presses space/Zener
  • Don't update the UI from any thread other then the a Event Dispatching Thread. See Concurrency in Swing for more details. Consider using a SwingWorker instead, it has functionality to sync the background thread with the EDT and in built progress support

Updated

enter image description here

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class LayoutExample {

    public static void main(String[] args) {
        new LayoutExample();
    }

    public LayoutExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new ProgressPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ProgressPane extends JPanel {

        private JProgressBar pb;
        private JButton start;
        private JButton cancel;

        public ProgressPane() {

            pb = new JProgressBar();
            start = new JButton("Start");
            cancel = new JButton("Cacnel");

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();

            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(50, 10, 5, 10);
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;
            gbc.gridwidth = 2;
            add(pb, gbc);

            gbc.gridx = 0;
            gbc.gridy = 1;
            gbc.insets = new Insets(0, 0, 0, 5);
            gbc.fill = GridBagConstraints.NONE;
            gbc.weightx = 1;
            gbc.gridwidth = 1;
            gbc.anchor = GridBagConstraints.EAST;
            add(start, gbc);

            gbc.weightx = 0;
            gbc.gridx = 1;
            gbc.insets = new Insets(0, 0, 0, 10);
            gbc.anchor = GridBagConstraints.WEST;
            add(cancel, gbc);

        }


    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Would the border layout or flowlayout work better? I will have to say that I am new to this. I find it difficult to position that components exactly were I want them to be using these different layout managers? – Doug Hauf May 19 '14 at 20:59
  • 1
    Personally, I'd use GridBagLayout. Pixel perfect layouts are an illusion in modern GUI design, to many factors can cause these kind of layouts to fall apart – MadProgrammer May 19 '14 at 21:16
  • If you can could you paste up an example of the GridBagLayout() with a progress bar and a button on it so that they are right aligned. I will add an image to the question above. – Doug Hauf May 19 '14 at 21:21
  • 1
    I love your post that is more descriptive and clear. – Braj May 19 '14 at 22:41
  • How do you stop this progress bar and delete panel from within main()? – tale852150 Apr 28 '17 at 19:58
  • 1
    @tale852150 You wouldn't, you remove from the SwingWorker's done method on in response to the PropertyChange event – MadProgrammer Apr 28 '17 at 21:12
  • @MadProgrammer I like this code and I'd like to build off it. I have a button that starts my process (and so starts the progress bar). But when the process ends I'd like to remove/stop the progress bar. Any way I can use this code base to do that? Thanks... – tale852150 Apr 28 '17 at 21:49
  • 1
    @tale852150 This example only shows the layout, something like [this](http://stackoverflow.com/questions/24835638/issues-with-swingworker-and-jprogressbar/24835935#24835935) shows how you can use a `SwingWorker`. I'd personally investigate using a `CardLayout` to switch the views – MadProgrammer Apr 28 '17 at 22:15
  • @MadProgrammer Oh, ok. I see where I made the wrong assumptions. Thanks very much for helping me out. – tale852150 Apr 28 '17 at 23:28