JProgressBar text overflow

My program writes text to a JProgressBar. The problem is that the text is wider than the width of the JProgressBar.

I already changed the height of the JProgressBar to write text in two lines, but I do not want to change the width.

How to change the JProgressBar overflow so that the text returns to the next line if it is too wide?

Hope this is clear enough :)

Here is what I would like:

Overflow in JProgressBar

thanks


EDIT

After @mKorbel's answer, the result is as follows:

enter image description here

The shortcut works very well, but why these stripes?

My code is:

// 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 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); 
+2
source share
2 answers

The program is developed using Java 6. It seems that JLayer is not available. If I am mistaken, could you please provide some code on how to do this? this is?

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

  • or with very similar logics using GlassPane

enter image description hereenter image description hereenter image description here

some notes

  • should use GBC instead of NullLayout

  • may be nicer with an added icon or transparent background

  • (adding LayoutManager to JLabel) you can place a bunch of JComponents with the same effect as for JPanel

eg

 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 surprisingly (for me) progressbar doesn't support it ... by @kleopatra

and

I think my question may not be clear enough. I do not want the text to exceed the boundaries of the JProgressBar. Also, I don't want to embed manually (i.e. no). I added a photo of what I want. from @Maxbester

  • you should use the JProgressBar as a Container , put the LayoutManager there, put the JProgressBar on the JProgressBar

enter image description here

  • to install EmptyBorder for EmptyBorder , for example. label.setBorder(new EmptyBorder(15, 15, 15, 15));

enter image description here

EDIT2 (icon, also may be translucent, may overlap JProgressBar)

enter image description here

maybe something like

 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 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 for WindowsClassicLookAndFeel (icon is not translucent)

enter image description here

+4
source

Available answers did not satisfy me. Thus, I implemented the following alternative solution for my own needs.

 import javax.swing.JProgressBar; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.geom.Rectangle2D; public class MultilineProgressBar extends JProgressBar { private static final String FONT_NAME = "Dialog"; private static final int FONT_SIZE = 12; private static final int INTERLINE_COEFFICIENT = 2; private static final int NEWLINE_OFFSET = FONT_SIZE * INTERLINE_COEFFICIENT; private static final int CENTERING_DIVISOR = 2; @Override protected void paintComponent(final Graphics graphics) { super.paintComponent(graphics); final String componentString = getString(); int i = componentString.indexOf('\n'); if (i == -1) return; // Draw first line of the component string String currentString = componentString.substring(0, i); Rectangle2D stringBounds = getFontMetrics(getFont()).getStringBounds(currentString, graphics); graphics.setFont(new Font(FONT_NAME, Font.BOLD, FONT_SIZE)); graphics.setColor(Color.WHITE); graphics.drawString(currentString, (int) (getWidth() - stringBounds.getWidth()) / CENTERING_DIVISOR, (int) (getHeight() - stringBounds.getHeight()) / CENTERING_DIVISOR); ++i; if (i >= componentString.length()) return; // Draw second line of the component string currentString = componentString.substring(i); stringBounds = getFontMetrics(getFont()).getStringBounds(currentString, graphics); graphics.drawString(currentString, (int) (getWidth() - stringBounds.getWidth()) / CENTERING_DIVISOR, (int) ((getHeight() - stringBounds.getHeight()) / CENTERING_DIVISOR) + NEWLINE_OFFSET); } } 
0
source

Source: https://habr.com/ru/post/952199/


All Articles