2010-05-28 66 views
9

Đối với biểu tượng JLabel có biểu tượng, nếu bạn setHorizontalTextPosition(SwingConstants.LEADING), biểu tượng sẽ được vẽ ngay sau văn bản, cho dù nhãn có rộng đến mức nào không.Làm cách nào để căn chỉnh biểu tượng trong nhãn JLabel?

Điều này đặc biệt xấu đối với danh sách, vì các biểu tượng sẽ ở khắp mọi nơi tùy thuộc vào thời lượng văn bản cho mỗi mục.

Tôi đã truy tìm mã và có vẻ như trong SwingUtilities#layoutCompoundLabelImpl, chiều rộng văn bản chỉ được đặt thành SwingUtilities2.stringWidth(c, fm, text) và biểu tượng x được đặt để theo dõi văn bản mà không xem xét chiều rộng nhãn.

Đây là trường hợp đơn giản:

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); 
      } 
     }); 
    } 
} 

Bạn có thể thấy nhãn mà luôn lấp đầy khung nhưng biểu tượng vẫn đặt. Bạn sẽ gặp vấn đề về gương nếu bạn đặt cả hai đối số thành TRAILING.

Tôi biết tôi có thể ghi đè giao diện người dùng hoặc sử dụng JPanel, v.v. Tôi tự hỏi tôi có thiếu thứ gì đó đơn giản trong JLabel không. Nếu không, nó có vẻ giống như một lỗi Java.

FYI đây là jdk1.6.0_06 trên Windows XP.

Trả lời

12

Đây có phải là hiệu ứng mong muốn không?

Phụ lục: Tôi nghĩ bảng điều khiển là cách để thực hiện.

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, tôi cần phải có văn bản trái lý và biểu tượng đúng lý. –

+0

Ah, tôi hiểu ý của bạn là gì. – trashgod

20

Bạn nên sử dụng:

label1.setHorizontalTextPosition (SwingConstants.LEFT);

(Đặt vị trí của văn bản, liên quan đến biểu tượng)

5

Tôi đã tìm thấy cách dễ dàng hơn để thực hiện việc này. Tôi cần phải có loại bố trí này trong một JTable, và đã làm đúng đắn bằng cách lấy chiều rộng văn bản và sau đó tự thiết lập chiều rộng giữa văn bản và biểu tượng. Tôi đã phân loại một DefaultTableCellRenderer cho JTable của tôi

public class FixedWidthRenderer extends DefaultTableCellRenderer 
{ 
    ... 
    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, 
     boolean isSelected, boolean hasFocus, int row, int column) 
    { 
     ... 
     FontMetrics met = super.getFontMetrics(super.getFont()); 
     int width = met.stringWidth(super.getText());     
     super.setIconTextGap(DESIREDWIDTH - width); 
     ... 
    } 
} 

Hoạt động tuyệt vời!
Và có, đối với mã thực, bạn nên kiểm tra xem chiều rộng văn bản có lớn hơn DESIREDWIDTH không.


Đối với tự động phải liên kết mà không có một chiều rộng cố định mà làm việc với các cột có chiều rộng biến:

@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

Giải pháp tốt. Tôi đã tự do thêm một phương thức hoạt động với độ rộng cột biến. –

Các vấn đề liên quan