Search code examples
javaswingoverflowjprogressbar

JProgressBar text overflow


My program writes text in a JProgressBar. The problem is the text is wider than the JProgressBar's width.

I have already changed the JProgressBar's height to be able to write the text on two lines but I don't want to the change the width.

How to change the JProgressBar's overflow to make the text going back to the next line if it is too wide?

I hope this is clear enough :)

Here is what I would like:

Overflow in JProgressBar

Thanks


EDIT

After @mKorbel reply the result looks like this:

enter image description here

The label works quite fine but why those strips?

My code:

// Construct progress bar
JProgressBar progressBar = new JProgressBar(0, 100);
// Set progressBar color
progressBar.setForeground(new Color(0,176,80));

// Edit progress bar height
Dimension prefSize = progressBar.getPreferredSize();
prefSize.height = 50;
progressBar.setPreferredSize(prefSize);

// Set the layout
progressBar.setLayout(new BorderLayout(5, 5));

// Set progress bar value
progressBar.setValue(38);

// Construct the label
JLabel progressLabel = new JLabel("<html>I have already changed the JProgressBar's height to be able to write the text on two lines but I don't want to the change the width.</html>");
// Set alignment
progressLabel.setHorizontalAlignment(JLabel.CENTER);
progressLabel.setVerticalAlignment(JLabel.CENTER);

// Set the borders
progressLabel.setBorder(new EmptyBorder(15, 15, 15, 15));

// Change the font
font = progressLabel.getFont();
font = font.deriveFont(Font.BOLD, 12);
progressLabel.setFont(font);

// Add label to the progress bar
progressBar.add(progressLabel, BorderLayout.CENTER);

// Add progress bar to the frame
frame.add(progressBar);

Solution

  • the program is developed with Java 6. It seems JLayer is not available. If I'm wrong, could you provide some code on how to do this?

    • could you provide some code on how to do this? --- > JLayer & JProgressBar by @aterai, for more ideas see his blog, for Java6 you can to use JXLayer

    • or with very similair logics by using GlassPane

    enter image description hereenter image description hereenter image description here

    some notes

    • should be used GBC instead of NullLayout

    • can be nicer with added Icon or transparent background

    • (by add LayoutManager to JLabel) there can be placed bunch of JComponents with the same effect as for JPanel

    for example

    import java.awt.Container;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.GridBagConstraints;
    import java.awt.event.ComponentAdapter;
    import java.awt.event.ComponentEvent;
    import javax.swing.JButton;
    import javax.swing.JCheckBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JProgressBar;
    import javax.swing.JRadioButton;
    import javax.swing.UIManager;
    //https://stackoverflow.com/questions/14560680/jprogressbar-low-values-will-not-be-displayed
    public class ProgressSample {
    
        private JFrame frame = new JFrame("GlassPane instead of JLayer");
        private JLabel label;
        private GridBagConstraints gbc = new GridBagConstraints();
        private JProgressBar progressSeven;
    
        public ProgressSample() {
            frame.setLayout(new FlowLayout());
            frame.add(new JButton("test"));
            frame.add(new JCheckBox("test"));
            frame.add(new JRadioButton("test"));
            // Nothing is displayed if value is lover that 6
            JProgressBar progressSix = new JProgressBar(0, 100);
            progressSix.setValue(2);
            frame.add(progressSix);
            // but this works value is higher that 6
            progressSeven = new JProgressBar(0, 100);
            progressSeven.addComponentListener(new ComponentAdapter() {
                @Override
                public void componentMoved(ComponentEvent e) {
                    label.setBounds(
                            (int) progressSeven.getBounds().getX(),
                            (int) progressSeven.getBounds().getY(),
                            label.getPreferredSize().width,
                            label.getPreferredSize().height);
                }
            });
            progressSeven.setValue(7);
            frame.add(progressSeven);
            label = new JLabel();
            label.setText("<html> Concurency Issues in Swing<br>"
                    + " never to use Thread.sleep(int) <br>"
                    + " durring EDT, simple to freeze GUI </html>");
            label.setPreferredSize(new Dimension(label.getPreferredSize().width, label.getPreferredSize().height));
            Container glassPane = (Container) frame.getRootPane().getGlassPane();
            glassPane.setVisible(true);
            glassPane.setLayout(null);
            glassPane.add(label, gbc);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                e.printStackTrace();
            }
            ProgressSample dialogTest = new ProgressSample();
        }
    }
    

    EDIT

    • comments

    my first thought was using html, but astonishingly (for me) the progressbar doesn't support it ... by @kleopatra

    and

    I think my question may not be clear enough. I don't want the text to exceed the JProgressBar borders. Plus, I don't want to insert manually line returns (ie no
    ). I added a picture of what I want. by @Maxbester

    • result is to use JProgressBar as Container, put there proper LayoutManager, overlay JProgressBar by JLabel

    enter image description here

    • enhancements, to set EmptyBorder for JLabel, e.g. label.setBorder(new EmptyBorder(15, 15, 15, 15));

    enter image description here

    EDIT2 (Icon is, can be semi_transparent too, can overlay JProgressBar)

    enter image description here

    code could be something like as

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JProgressBar;
    import javax.swing.UIManager;
    import javax.swing.border.EmptyBorder;
    
    public class JProgressBarWithJLabel {
    
        private JFrame frame = new JFrame("JLabel in JProgressBar");
        private JLabel label;
        private JProgressBar progressSeven;
    
        public JProgressBarWithJLabel() {
            progressSeven = new JProgressBar(0, 100){
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(300, 60);
                }
            };
            progressSeven.setValue(38);
            progressSeven.setLayout(new BorderLayout(5, 5));
            label = new JLabel();
            label.setHorizontalTextPosition(JLabel.CENTER);
            label.setVerticalTextPosition(JLabel.CENTER);
            label.setBorder(new EmptyBorder(15, 15, 15, 15));
            label.setText("<html>I have already changed the JProgressBar's height "
                    + "to be able to write the text on two lines but I don't want "
                    + "to the change the width.</html>");
            progressSeven.add(label, BorderLayout.CENTER);
            frame.add(progressSeven);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            try {
                for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(laf.getName())) {
                        UIManager.setLookAndFeel(laf.getClassName());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new JProgressBarWithJLabel();
                }
            });
        }
    }
    

    EDIT3:

    default stripping for WindowsClassicLookAndFeel (Icon isn't semi_transparent)

    enter image description here