2010-09-18 38 views
7

Có cách nhìn độc lập để sắp xếp thành phần (ví dụ: JLabel) theo chiều ngang với văn bản của một JCheckBox không?Căn chỉnh JLabel bằng văn bản của JCheckBox

Tôi đang cố gắng sử dụng các giá trị từ UIDefaults để dự đoán vị trí của văn bản có liên quan đến góc trên cùng bên trái của JCheckBox. Tôi đã tìm thấy một sự kết hợp mang lại cho kết quả phù hợp với các kim loại, Windows, Motif và Aqua Look-and-Cảm thấy:
Example: Metal (correctly-aligned)

Nhưng không phải trong Nimbus:
Example: Nimbus (incorrectly-aligned)

Có một phương pháp hữu ích ở đâu đó điều đó sẽ cung cấp độ lệch X, Y đáng tin cậy cho văn bản trong tất cả các Giao diện?


Mã (lưu ý: để tránh bất kỳ bố trí tác dụng phụ tôi đã sử dụng một cách bố trí null cho thử nghiệm này):

import java.awt.Insets; 

import javax.swing.JApplet; 
import javax.swing.JCheckBox; 
import javax.swing.JLabel; 
import javax.swing.UIManager; 
import javax.swing.border.Border; 

public class AlignCheckBoxText extends JApplet { 

    public AlignCheckBoxText() { 
     setLayout(null); 
     checkBox = new JCheckBox("Hello, World!"); 
     label = new JLabel("Hello, World!"); 
     add(checkBox); 
     add(label); 
    } 

    @Override 
    protected void validateTree() { 
     checkBox.setLocation(0, 0); 
     checkBox.setSize(checkBox.getPreferredSize()); 
     int labelX = UIManager.getIcon("CheckBox.icon").getIconWidth(); 
     Insets cbInsets = UIManager.getInsets("CheckBox.margin"); 
     if (cbInsets != null) labelX += cbInsets.left + cbInsets.right; 
     Border cbBorder = UIManager.getBorder("CheckBox.border"); 
     if (cbBorder != null) { 
      Insets borderInsets = cbBorder.getBorderInsets(checkBox); 
      if (borderInsets != null) { 
       labelX += borderInsets.left; 
      } 
     } 
     label.setLocation(labelX, checkBox.getHeight()); 
     label.setSize(label.getPreferredSize()); 
     super.validateTree(); 
    } 

    private JCheckBox checkBox; 
    private JLabel label; 

} 
+1

Trong trường hợp này, sẽ dễ dàng hơn khi tạo hộp kiểm không có văn bản và nhãn JL riêng biệt chứa văn bản hộp kiểm gốc. – barjak

+0

@barjak, điều đó sẽ gây rối với màn hình lấy nét. Thông thường có một đường viền xung quanh hộp kiểm (biểu tượng và văn bản) để hiển thị khi nó được lấy nét. Ngoài ra, nhấp vào văn bản sẽ không còn chuyển đổi lựa chọn hộp kiểm nữa. – finnw

Trả lời

3

(Để OP: xin vui lòng unaccept câu trả lời sai trước đây của tôi, và tôi sẽ xóa nó Xin lỗi.!)

Bạn có thể sử dụng hộp kiểm không vẽ hộp kiểm cho nhãn của bạn. Điều này làm việc cho tất cả các LAF trong Windows JDK6, bao gồm cả Nimbus. Tôi không có mac nên không thể kiểm tra Aqua.

class CheckBoxLabel extends JCheckBox 
{ 
    public CheckBoxLabel(String string) 
    { 
     super(string); 
    } 

    public void updateUI() 
    { 
     setUI(new CheckBoxLabelUI()); 
    } 
} 

class CheckBoxLabelUI extends BasicCheckBoxUI 
{ 
    public void installUI(JComponent c) 
    { 
     super.installUI(c); 
     Icon i = super.getDefaultIcon(); 
     icon_ = new EmptyIcon(i.getIconWidth(), i.getIconHeight()); 
    } 

    public Icon getDefaultIcon() 
    { 
     return icon_; 
    } 

    private Icon icon_; 
} 

class EmptyIcon implements Icon 
{ 
    public EmptyIcon() 
    { 
     this(0, 0); 
    } 

    public EmptyIcon(int width, int height) 
    { 
     width_ = width; 
     height_ = height; 
    } 

    public int getIconHeight() 
    { 
     return height_; 
    } 

    public int getIconWidth() 
    { 
     return width_; 
    } 

    public void paintIcon(Component c, Graphics g, int x, int y) 
    { 
    } 

    private int width_; 
    private int height_; 
} 
1

Đây không phải là một câu trả lời hoàn chỉnh, nhưng nó có thể giúp bạn:

Nếu bạn thêm checkBox.getIconTextGap() vào giá trị của labelX, căn chỉnh có vẻ là OK với Nimbus, nhưng không OK với kim loại hoặc GTK.

+0

Thú vị. 'checkBox.getIconTextGap' cho kết quả hữu ích (có thể là trùng hợp ngẫu nhiên) trong Nimbus nhưng kết quả không hữu ích trong các L & F khác. 'UIManager.getInt (" CheckBox.textIconGap ")' luôn trả về 0. – finnw

+0

Đây là giải pháp tôi cũng sẽ đề xuất, mặc dù bạn nên lưu ý rằng LAF không bị buộc phải sử dụng bất kỳ giá trị mặc định UIManager nào. Ngoài ra tôi nhận được một giá trị khác không cho LAF mặc định của. Kiểm tra chương trình mặc định UIManager (http://tips4java.wordpress.com/2008/10/09/uimanager-defaults/). Tất cả các ví dụ mà tôi từng thấy trong hướng dẫn Swing đều ghi đè phương thức init() để tạo GUI. Có lẽ vấn đề là với phương pháp bạn đang ghi đè và LAF chưa được cài đặt? Hãy thử cách bình thường hoặc thử tạo một JFrame cho bạn bản demo để xem có sự khác biệt nào không. – camickr

1

Nếu bạn sử dụng GroupLayout, trình xây dựng GUI Netbeans có thể căn chỉnh văn bản của hộp kiểm và nhãn trên dòng tiếp theo .... sắp xếp.

Dường như nó hoạt động tốt cho Nimbus, nhưng trong LAF kia, văn bản nhãn là một pixel quá xa bên phải. Nhìn vào mã được tạo ra cho GroupLayout trong trình xây dựng GUI, nó tạo ra khoảng cách 22x22 ở phía trước nhãn. Đối với Nimbus, 22 có vẻ đúng, nhưng đối với các LAF khác, nó có vẻ là 21.

Mã được tạo ra trông như thế này.

GroupLayout layout = new GroupLayout(getContentPane()); 
getContentPane().setLayout(layout); 
layout.setHortizontalGroup(
    layout.createParallelGroup(Alignment.LEADING) 
    .addGroup(layout.createSequentialGroup() 
     .addContainerGap() 
     .addGroup(layout.createParallelGroup(Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addGap(22,22,22) 
      .addComponent(label) 
     ) 
     .addComponent(checkBox) 
    ) 
    ) 
); 

layout.setVerticalGroup(
    layout.createParallelGroup(Alignment.LEADING) 
    .addGroup(layout.createSequentialGroup() 
     .addContainerGap() 
     .addComponent(checkBox) 
     .addPreferredGap(ComponentPlacement.RELATED) 
     .addComponent(label) 
    ) 
); 

Mã này sẽ nằm trong hàm tạo của lớp mẫu sau khi gán nhãn và hộp kiểm. Ngoài ra, loại bỏ các setLayout (null);

Tất cả điều này được cho biết, dựa trên những gì tôi đã nhìn thấy bằng cách sử dụng GUI builder, tôi khuyên bạn nên sau thật:

  1. loại bỏ các bit Border cbBorder từ mẫu
  2. thêm checkBox.getIconTextGap() với nhãnX.
  3. Nếu LAF là nimbus, sau đó thêm 4 vào labelX. :)
2

Bạn có thể căn chỉnh nhãn và đặt chiều rộng thành chiều rộng của hộp kiểm trừ đường viền phải. Nó hoạt động cho tất cả các LAF với Windows JDK1.6.0_21, bao gồm cả Nimbus. Tôi không có máy Mac nên không thể kiểm tra Aqua.

Dưới đây là mã của bạn rất chút thay đổi:

class AlignCheckBoxText extends JApplet { 

    public AlignCheckBoxText() { 
     setLayout(null); 
     checkBox = new JCheckBox("Hello, World!"); 
     label = new JLabel("Hello, World!"); 
     add(checkBox); 
     add(label);   
     label.setHorizontalAlignment(JLabel.TRAILING); 
    } 

    @Override 
    protected void validateTree() { 
     checkBox.setLocation(0, 0); 
     checkBox.setSize(checkBox.getPreferredSize()); 
     int x = 0; 
     Border cbBorder = UIManager.getBorder("CheckBox.border"); 
     if (cbBorder != null) { 
      Insets borderInsets = cbBorder.getBorderInsets(checkBox); 
      if (borderInsets != null) { 
       x += borderInsets.right; 
      } 
     } 
     label.setLocation(0, checkBox.getHeight()); 
     label.setSize(new Dimension(checkBox.getPreferredSize().width - x, label.getPreferredSize().height)); 
     super.validateTree(); 
    } 

    private JCheckBox checkBox; 
    private JLabel label; 

} 
+1

Tôi ước tôi có thể xóa bỏ hoặc bỏ phiếu cho câu trả lời của mình. Nó thực sự là não chết (không có vi phạm để OP, đó là tất cả lỗi của tôi). Nó chỉ hoạt động khi hộp kiểm và nhãn có văn bản giống nhau. Bạn có thể hack nó bằng cách thiết lập các văn bản hộp kiểm thực sau khi thiết lập kích thước nhãn, nhưng sau đó bạn sẽ phải làm điều đó bất cứ khi nào văn bản nhãn thay đổi. Ngoài ra nó không cho ngôn ngữ từ phải sang trái. Một câu trả lời thực sự có lẽ sẽ cần phải đi sâu vào giao diện người dùng hộp kiểm tra, mà tôi không quen thuộc với. Lấy làm tiếc. –

+0

Mặc dù câu trả lời này có nhược điểm, tôi nghĩ rằng điều này nên ở lại. Đừng xóa nó. Mặc dù có thể OP không thể chấp nhận nó. –

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