2013-08-21 4 views
6
  • как придерживаться JLabel в GlassPane к rellative, плавучие координаты из JProgressBar без использования ComponentListener или другого слушателя,Layout Manager и позиционирование

  • находится там built_in оповещатели в стандартных LayoutManagers, которые могут уведомить о своем внутреннем состоянии, и может быть для перенастройки подъезд, а моя попытка с ComponentListener и NullLayout

enter image description here

.

enter image description here

SSCCE о ComponentListener и NullLayout

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; 
//http://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(), 
         progressSeven.getPreferredSize().width, 
         label.getPreferredSize().height); 
      } 
     }); 
     progressSeven.setValue(7); 
     frame.add(progressSeven); 
     label = new JLabel(); 
     label.setText("<html>Blablabla, Blablablabla<br>" 
       + "Blablabla, Blablablabla<br>" 
       + "Blablabla, Blablablabla</html>"); 
     label.setPreferredSize(new Dimension(
       progressSeven.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(); 
    } 
} 
+1

+1 для 'SSCCE' ... – Reimeus

+1

' layoutContainer() 'может быть перекрыт в огне события, которое может быть выслушанным менеджером пользовательских макета для оконного стекла. Я не уверен, что это то, чего ты хочешь. – kiheru

+0

_without использование ComponentListener или другого listener_ какое странное требование, домашнее задание? kleopatra

ответ

5

как придерживаться JLabel в GlassPane к rellative, плавучие координаты из JProgressBar без использования ComponentListener или другого слушателя

Моя идея состояла бы в том, чтобы обернуть t wo в контейнере с OverlayLayout и «играть» с AlignementX/AlignementY для относительных координат. Затем просто поместите контейнер для упаковки в исходную иерархию. (Смотрите мой SSCCE ниже)

есть built_in уведомителей в стандартных LayoutManagers, которые могут извещать о его внутреннем состоянии, и может быть подъездом для перенастройки, а моей попытки с ComponentListener и NullLayout

Там не является таким контрактом в API LayoutManager, поэтому вы не можете надежно полагаться на какой-либо такой механизм. Более того, вы столкнетесь с проблемами со стандартным LayoutManager, потому что они учтут ваш дополнительный JLabel во внимание в макете.

Представьте, что вы используете FlowLayout, и вы положили 1 компонент, а затем ваш дополнительный JLabel, а затем еще один компонент. Когда вы переместите дополнительный JLabel, последний компонент останется «прочь» от первого компонента, и вы увидите разрыв между этими двумя.

Если этот последний вопрос не является проблемой, вы могли бы просто расширить FlowLayout (или любой другой LayoutManager), переопределить layoutContainer и поместить дополнительный JLabel где вы хотели бы.

import java.awt.Container; 
import java.awt.FlowLayout; 
import java.awt.GridBagConstraints; 

import javax.swing.JButton; 
import javax.swing.JCheckBox; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JProgressBar; 
import javax.swing.JRadioButton; 
import javax.swing.OverlayLayout; 
import javax.swing.UIManager; 

//http://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); 
     JPanel wrappingPanel = new JPanel(); 
     OverlayLayout mgr = new OverlayLayout(wrappingPanel); 
     wrappingPanel.setLayout(mgr); 
     progressSeven = new JProgressBar(0, 100); 
     progressSeven.setAlignmentX(0.0f); 
     progressSeven.setAlignmentY(0.0f); 
     frame.add(wrappingPanel); 
     label = new JLabel(); 
     label.setText("<html>Blablabla, Blablablabla<br>" + "Blablabla, Blablablabla<br>" + "Blablabla, Blablablabla</html>"); 
     label.setAlignmentX(0.0f); 
     label.setAlignmentY(0.0f); 
     wrappingPanel.add(label); 
     wrappingPanel.add(progressSeven); 
     Container glassPane = (Container) frame.getRootPane().getGlassPane(); 
     glassPane.setVisible(true); 
     glassPane.setLayout(new FlowLayout()); 
     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(); 
    } 
} 
+0

+1 хммм согласен, возможно, отвечая на мой вопрос ....., то лучше, безопаснее можно использовать [JProgressBar как контейнер (как всегда для меня)] (http: // stackoverflow.com/a/18355235/714968), кстати, этот вопрос основан на моих знаниях, отсутствующих в коде, размещенном там в качестве моего ответа, – mKorbel

+0

@mKorbel. Существует один недостаток использования 'JProgressBar' в качестве контейнера: индикатор выполнения будет растянут на протяжении всего при условии, что это выглядит довольно странно. –

+0

- это побочный эффект, вызванный использованием LayoutManager, например. GBC вызвал ту же проблему для JPanel, вы правы, что это не стандарт в Swing, вполне требования к Htlm5/JavaFX – mKorbel

Смежные вопросы