2013-08-21 2 views
2

Моя программа записывает текст в JProgressBar. Проблема в том, что текст шире ширины JProgressBar.Переполнение текста JProgressBar

Я уже изменил высоту JProgressBar, чтобы писать текст по двум строкам, но я не хочу менять ширину.

Как изменить переполнение JProgressBar, чтобы текст возвращался на следующую строку, если он слишком широк?

Я надеюсь, что это достаточно ясно :)

Вот что я хотел бы:

Overflow in JProgressBar

Благодаря


EDIT

После @mKorbel РЕПЛ у результат выглядит следующим образом:

enter image description here

Ярлык работает довольно хорошо, но почему эти полосы?

Мой код:

// 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); 
+0

Одно предложение привязать размер шрифта текста с шириной и сделать функцию таким образом, чтобы каждый раз, когда добавляется текст, который FontSize рассчитывается по ширине она должна отображаться в :) –

+1

Это может быть решением, но если слишком много символов, текст может быть очень маленьким и не читаемым. – Maxbester

+0

Да, это правда @MAxbester –

ответ

4

программа разработана с Java 6. Это кажется JLayer не доступны. Если я ошибаюсь, не могли бы вы предоставить какой-то код о том, как это сделать ?

  • Вы могли бы предоставить код, о том, как это сделать?--->JLayer & JProgressBar по @aterai, для больше идей увидеть его блог, для Java6 вы можете использовать JXLayer

  • или с очень similair логик с помощью GlassPane

enter image description hereenter image description hereenter image description here

некоторые примечания

  • следует использовать GBC вместо NullLayout

  • может быть лучше, с добавлением значка или прозрачным фоном

  • (по добавить LayoutManager к JLabel) может быть размещена куча JComponents с тем же эффектом, как и для JPanel

, например

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

  • комментарии

моя первая мысль была с помощью HTML, но удивительно (для меня) прогрессбара не поддерживает ... от @kleopatra

и

Я думаю, что мой вопрос может быть недостаточно ясным. Я не хочу, чтобы текст превышал границы JProgressBar. Кроме того, я не хочу вручную вставлять строки (т.е. нет
). Я добавил фотографию того, что хочу. по @Maxbester

  • результат заключается в использовании в качестве JProgressBarContainer, положить туда соответствующую LayoutManager, наложение JProgressBar на JLabel

enter image description here

  • усовершенствований, чтобы установить EmptyBorder для JLabel, напримерlabel.setBorder(new EmptyBorder(15, 15, 15, 15));

enter image description here

EDIT2 (икона, может быть semi_transparent тоже может накладывать JProgressBar)

enter image description here

код может быть что-то вроде как

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:

по умолчанию для зачистки WindowsClassicLookAndFeel (иконка не semi_transparent)

enter image description here

+0

Я думаю, что мой вопрос может быть недостаточно ясным. Я не хочу, чтобы текст превышал границы JProgressBar. Кроме того, я не хочу вставлять строки вручную (т.е. нет '
'). Я добавил фотографию того, что хочу. В любом случае спасибо за ваш ответ. – Maxbester

+0

см. Мое редактирование здесь – mKorbel

+0

Отличный код! Благодаря! Однако у меня есть некоторые полосы на JProgressBar. См. Мой вопрос. – Maxbester

0

Доступные ответы не удовлетворили меня. Таким образом, я реализовал следующее альтернативное решение для своих нужд.

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's 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's 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); 
    } 
} 
Смежные вопросы