2013-08-21 16 views
6
  • jak trzymać JLabel w GlassPane do rellative pływające współrzędnych z JProgressBar bez użycia ComponentListener lub innego słuchacza,Layout Manager i pozycjonowanie

  • jest tam built_in powiadamiający w standardowych LayoutManagers że może powiadomić o swoim stanie wewnętrznym, i mogą być dostepne dla ręcznego, zamiast moja próba z ComponentListener i NullLayout

enter image description here

.

enter image description here

SSCCE o ComponentListener iz 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 dla 'SSCCE' ... – Reimeus

+1

' layoutContainer() 'może być zmienione na ogień zdarzenie, które mogło być słuchane przez kierownika niestandardowy układ do szyby. Nie jestem pewien, czy tego właśnie chcesz. – kiheru

+0

_ bez użycia ComponentListener lub innego detektora, jakie dziwne wymaganie, praca domowa? kleopatra

Odpowiedz

5

jak trzymać JLabel w GlassPane do rellative pływające współrzędne z JProgressBar bez użycia ComponentListener lub innego słuchacza

Mój pomysł polegałby na owinięciu t wo składników w pojemniku z OverlayLayout i "odtwarzaj" z AlignementX/AlignementY dla względnych współrzędnych. Następnie po prostu umieść kontener zawijania w pierwotnej hierarchii. (Patrz mój SSCCE poniżej)

ma built_in zgłaszających w standardowych LayoutManagers że może powiadomić o jego stanu wewnętrznego i mogą być dostepne dla ręcznego, zamiast moja próba z ComponentListener i NullLayout

Nie nie ma takiej umowy w interfejsie API LayoutManager, dlatego nie można polegać bezpiecznie na żadnym takim mechanizmie. Co więcej, napotkasz problemy ze standardowym menedżerem LayoutManager, ponieważ uwzględnią one twój dodatkowy JLabel w układzie.

Wyobraź sobie, że używasz FlowLayout i umieszczasz 1 komponent, następnie dodatkowy JLabel, a następnie kolejny komponent. Kiedy przenosisz dodatkowy JLabel ostatni komponent pozostanie "oddalony" od pierwszego komponentu i zobaczysz przerwę między tymi dwoma elementami.

Jeśli ta ostatnia kwestia nie jest problem, można po prostu rozszerzyć FlowLayout (lub innego LayoutManager), zastępują layoutContainer i umieścić dodatkowy JLabel gdziekolwiek chcesz.

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 hmmm zgadzam się, prawdopodobnie odpowiadając na moje pytanie ....., wtedy lepiej, bezpieczniej może być użycie [JProgressBar jak Container (jak zawsze dla mnie)] (http: // stackoverflow.com/a/18355235/714968), przy czym to pytanie jest oparte na moich informacjach, których nie ma w kodzie wysłanym tam jako moja odpowiedź, – mKorbel

+0

@mKorbel Istnieje jedna wada, aby używać 'JProgressBar' jako kontenera: pasek postępu będzie rozciągał się na cały granice zapewnione, więc wygląda dość dziwnie. –

+0

ograniczenia są efektem ubocznym, spowodowanym przez LayoutManager, np. GBC spowodował ten sam problem dla JPanel, masz rację, to nie jest standard w Swing, dość wymagania w Htlm5/JavaFX – mKorbel