2010-05-28 10 views
9

Dla JLabel z ikoną, jeśli jesteś setHorizontalTextPosition(SwingConstants.LEADING), ikona jest malowana tuż po tekście, bez względu na to, jak szeroka jest etykieta.Jak usprawnić prawo ikony w JLabel?

Jest to szczególnie szkodliwe dla listy, ponieważ ikony byłyby wszędzie, w zależności od tego, jak długi jest tekst dla każdego elementu.

Śledziłem kod i wygląda na to, że w SwingUtilities#layoutCompoundLabelImpl szerokość tekstu jest ustawiona po prostu na SwingUtilities2.stringWidth(c, fm, text), a ikona x jest ustawiona tak, aby śledzić tekst bez uwzględniania szerokości etykiety.

Oto najprostszy przypadek:

import java.awt.*; 
import javax.swing.*; 

public class TestJLabelIcon 
{ 
    public static void main(String args[]) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       JLabel c = new JLabel("abc"); 
       c.setHorizontalTextPosition(SwingConstants.LEADING); 
       c.setHorizontalAlignment(SwingConstants.LEADING); 
       c.setIcon(UIManager.getIcon("FileChooser.detailsViewIcon")); 
       c.setBorder(BorderFactory.createLineBorder(Color.RED)); 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.getContentPane().add(c);  
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 

Widać, że etykieta zawsze wypełnia ramkę ale ikona pozostaje na miejscu. Otrzymasz problem z lustrem, jeśli ustawisz oba argumenty na TRAILING.

Wiem, że mogę przesłonić interfejs użytkownika lub użyć JPanel itp. Zastanawiam się tylko, czy brakuje mi czegoś prostego w JLabel. Jeśli nie, wydaje się, że jest to błąd Javy.

FYI to jest jdk1.6.0_06 w systemie Windows XP.

Odpowiedz

12

Czy to pożądany efekt?

Dodatek: Myślę, że panel jest drogą do zrobienia.

image

import java.awt.*; 
import javax.swing.*; 

public class TestJLabelIcon { 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       frame.setLayout(new GridLayout(0, 1)); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(createPanel("abc")); 
       frame.add(createPanel("defghij")); 
       frame.add(createPanel("klmn")); 
       frame.add(createPanel("opq")); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 

      private JPanel createPanel(String s) { 
       JPanel p = new JPanel(new BorderLayout()); 
       p.add(new JLabel(s, JLabel.LEFT), BorderLayout.WEST); 
       Icon icon = UIManager.getIcon("FileChooser.detailsViewIcon"); 
       p.add(new JLabel(icon, JLabel.RIGHT), BorderLayout.EAST); 
       p.setBorder(BorderFactory.createLineBorder(Color.blue)); 
       return p; 
      } 
     }); 
    } 
} 
+0

Nop, muszę mieć tekst wyrównany do lewej i prawej ikona uzasadnione. –

+0

Ah, rozumiem, co masz na myśli. – trashgod

20

Należy użyć:

label1.setHorizontalTextPosition (SwingConstants.LEFT);

(Ustaw pozycję tekstu, w stosunku do ikony)

5

znalazłem wiele łatwiejszy sposób, aby to zrobić. Potrzebowałem tego rodzaju układu w JTable i zrobiłem właściwe uzasadnienie, uzyskując szerokość tekstu, a następnie ręcznie ustawiając szerokość między tekstem a ikoną. Podklasowałem DefaultTableCellRenderer dla mojego JTable

Działa świetnie!
I tak, dla prawdziwego kodu należy sprawdzić, czy szerokość tekstu nie jest większa niż WYMAGANO.


Dla automatycznego prawym wyrównania bez stałej szerokości, który współpracuje z kolumnami o zmiennej szerokości:

@Override 
    public void setBounds(int x, int y, int width, int height) { 
     super.setBounds(x, y, width, height); 
     if (getIcon() != null) { 
      int textWidth = getFontMetrics(getFont()).stringWidth(getText()); 
      Insets insets = getInsets(); 
      int iconTextGap = width - textWidth - getIcon().getIconWidth() - insets.left - insets.right - PADDING; 
      setIconTextGap(iconTextGap); 
     } else { 
      setIconTextGap(0); 
     } 
    } 
+0

Dobre rozwiązanie. Pozwoliłem sobie na dodanie metody, która działa ze zmiennymi szerokościami kolumn. –