2009-08-11 24 views
11

Tôi thực sự có thể sử dụng hộp kiểm tri-nêu trong Java. Nghe có vẻ đơn giản, nhưng tôi chỉ thấy thực sự ugly implementations [note: link now broken].Hộp kiểm tra Tristate trong Java

Ba nút radio chỉ chiếm quá nhiều bất động sản và có thể sẽ gây nhầm lẫn cho người dùng trong trường hợp của tôi. Về cơ bản, nó là một hộp thoại tìm kiếm. Tôi cần các tùy chọn đúng, sai hoặc "không quan tâm". Có một kỹ thuật khác mà mọi người sử dụng không?

Trả lời

5

Tôi tìm thấy một cách để làm cho một hộp kiểm tri-state bằng cách đơn giản thêm một người biết lắng nghe:


public class TriStateActionListener implements ActionListener{ 
    final protected Icon icon; 

    public TriStateActionListener(Icon icon){ 
     this.icon=icon; 
    } 

    public static Boolean getState(javax.swing.JCheckBox cb){ 
     if (cb.getIcon()==null) return null; 
     if (cb.isSelected()) return true; 
     else return false; 
    } 

    public void actionPerformed(ActionEvent e) { 
     javax.swing.JCheckBox cb=(javax.swing.JCheckBox)e.getSource(); 
     if (!cb.isSelected()){ 
      cb.setIcon(icon); 
     } 
     else if (cb.getIcon()!=null){ 
      cb.setIcon(null); 
      cb.setSelected(false); 
     } 
    } 
} 

Sau đó, trong mã ứng dụng, nó chỉ là một dòng duy nhất:


jCheckBox1.addActionListener(new TriStateActionListener(getResourceMap().getIcon("TriStateIcon"))); 

Sau khi tất cả các phản hồi, tôi nghĩ một trình đơn thả xuống có thể là một lựa chọn tốt hơn. Nhưng, tôi muốn chia sẻ mã của tôi ở đây cho mọi người khác.

14

Sử dụng menu thả xuống.

+1

1 ý tưởng tốt. nếu một thành phần giao diện người dùng khó mã hóa và không chuẩn, nó cũng sẽ cảm thấy như vậy đối với người dùng. Lần cuối cùng bạn sử dụng hộp kiểm tri-state theo cách đó là khi nào? Tôi không bao giờ có. –

+8

Mặc dù tôi đồng ý với @ byron's point, một hộp kiểm tri-state thực sự khá chuẩn từ quan điểm của người dùng. –

+5

Người dùng nào? Tôi là một nhà phát triển và người sử dụng năng lượng, và tôi coi thường các hộp kiểm tri-bang, thường là vì nó không rõ ràng những gì nhà nước thứ ba có nghĩa là; thông thường, nó có nghĩa là một số chi tiết đang được ẩn khỏi bạn. Đó là một cơn ác mộng khả năng sử dụng và khả năng tiếp cận. – Rob

0

Tôi chỉ sử dụng tài khoản bạn đã đăng.

Miễn là sự phức tạp của bạn ở một lớp khác (hoạt động) và nó hoạt động giống như bất kỳ kiểm soát nào khác, ai quan tâm? (Điều đó có vẻ là giả định đằng sau tất cả các swing, hầu hết các lớp học swing dường như về sự phức tạp này.)

2

Đó là "triển khai xấu xí" là một liên kết cũ. Một trong những đề xuất trên trang đó đã được cập nhật một vài năm trước. Tôi đã không thử nghiệm việc thực hiện cũ, vì vậy tôi không biết nếu mới là bất kỳ tốt hơn hoặc tồi tệ hơn.

TristateCheckBox Revisited

+0

Vâng, tôi nghĩ Heinz Kabutz, đã làm điều này rất tốt. Tôi cũng muốn giới thiệu điều đó! – codevour

0

Thay đổi giao diện người dùng. Tristate check-box là không bình thường và thực sự có thể gây nhầm lẫn cho người dùng. Các thả xuống là lựa chọn tốt nhưng đối với nhiều hơn sau đó một lần xuất hiện trong hộp thoại nó cũng sẽ mang lại rất nhiều sự nhầm lẫn cho người dùng.

2

Hộp kiểm tristate là thành ngữ giao diện người dùng chuẩn cho Số lần xem có nút con được kiểm tra một phần. Chúng được sử dụng rộng rãi trong quản lý lớp trong các chế độ xem phân cấp phức tạp như Google Earth.

3

Jide đã mở nguồn gốc một số chức năng rất thoải mái tại Common Layer của họ, một trong số đó sẽ xảy ra là một hộp kiểm tristate

Tristate checkboxes

tôi sẽ đề nghị bạn nên đi chạy webstart demo để xem nếu nó đáp ứng nhu cầu của bạn

4

enter image description here

thực hiện điều này ba trạng thái có thể được thiết lập thông qua chỉ lập trình. Để được nhìn và cảm nhận di động nó sử dụng hình ảnh, mà phải được đặt bên trong cùng một gói java.

enter image description here enter image description here enter image description here

public class TristateCheckBox extends JCheckBox { 

    private static final long serialVersionUID = 1L; 
    private boolean halfState; 
    private static Icon selected = new javax.swing.ImageIcon(TristateCheckBox.class.getResource("selected.png")); 
    private static Icon unselected = new javax.swing.ImageIcon(TristateCheckBox.class.getResource("unselected.png")); 
    private static Icon halfselected = new javax.swing.ImageIcon(TristateCheckBox.class.getResource("halfselected.png")); 

    @Override 
    public void paint(Graphics g) { 
     if (isSelected()) { 
      halfState = false; 
     } 
     setIcon(halfState ? halfselected : isSelected() ? selected : unselected); 
     super.paint(g); 
    } 

    public boolean isHalfSelected() { 
     return halfState; 
    } 

    public void setHalfSelected(boolean halfState) { 
     this.halfState = halfState; 
     if (halfState) { 
      setSelected(false); 
      repaint(); 
     } 
    } 
} 

khung mẫu:

public class NewJFrame19 extends javax.swing.JFrame { 

    private final TristateCheckBox myCheckBox; 

    public NewJFrame19() { 
     myCheckBox = new TristateCheckBox(); 
     myCheckBox.setText("123123"); 
     add(myCheckBox); 

     jButton1 = new javax.swing.JButton(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     getContentPane().setLayout(new java.awt.FlowLayout()); 

     jButton1.setText("jButton1"); 
     jButton1.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       jButton1ActionPerformed(evt); 
      } 
     }); 
     getContentPane().add(jButton1); 

     pack(); 
    } 

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           
     myCheckBox.setHalfSelected(true); 
    }           

    public static void main(String args[]) { 

     try { 
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
       if ("Windows".equals(info.getName())) { 
        javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (ClassNotFoundException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame19.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (InstantiationException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame19.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (IllegalAccessException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame19.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame19.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } 
     /* Create and display the form */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new NewJFrame19().setVisible(true); 
      } 
     }); 
    } 
    private javax.swing.JButton jButton1; 
} 
+1

Chúng tôi sử dụng phương pháp này cho một hộp kiểm biểu thị tổng hợp các trạng thái bật/tắt. Tương tác bật/tắt tất cả bật/tắt, trạng thái trung gian chỉ có thể truy cập thông qua tương tác với các phần tử riêng lẻ. Hoạt động khá độc đáo và tôi nghĩ rằng đó là âm thanh nhiều hơn về thiết kế giao diện người dùng. –

3

Tôi không biết tại sao mọi người sẽ cung cấp những giải pháp với các tập tin thêm icon png trong khi java api cho funcionality tuyệt vời cho ghi đè phương thức paintIcon (..).

Giải pháp gọn nhẹ nhất để nhớ trạng thái CheckBox là IMO Thuộc tính ClientProperty.

enter image description here

/* 
* Tri-state checkbox example 
* @s1w_ 
*/ 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 


class TCheckBox extends JCheckBox implements Icon, ActionListener { 

    final static boolean MIDasSELECTED = true; //consider mid-state as selected ? 


    public TCheckBox() { this(""); } 

    public TCheckBox(String text) { 
     super(text); 
     putClientProperty("SelectionState", 0); 
     setIcon(this); 
     addActionListener(this); 
    } 

    public TCheckBox(String text, int sel) { 
     /* tri-state checkbox has 3 selection states: 
     * 0 unselected 
     * 1 mid-state selection 
     * 2 fully selected 
     */ 
     super(text, sel > 1 ? true : false); 

     switch (sel) { 
      case 2: setSelected(true); 
      case 1: 
      case 0: 
       putClientProperty("SelectionState", sel); 
       break; 
      default: 
       throw new IllegalArgumentException(); 
     } 
     addActionListener(this); 
     setIcon(this); 
    } 

    @Override 
    public boolean isSelected() { 
     if (MIDasSELECTED && (getSelectionState() > 0)) return true; 
     else return super.isSelected(); 
    } 

    public int getSelectionState() { 
     return (getClientProperty("SelectionState") != null ? (int)getClientProperty("SelectionState") : 
             super.isSelected() ? 2 : 
             0); 
    } 

    public void setSelectionState(int sel) { 
     switch (sel) { 
      case 2: setSelected(true); 
        break; 
      case 1: 
      case 0: setSelected(false); 
        break; 
      default: throw new IllegalArgumentException(); 
     } 
     putClientProperty("SelectionState", sel); 
    } 


    final static Icon icon = UIManager.getIcon("CheckBox.icon"); 

    @Override 
    public void paintIcon(Component c, Graphics g, int x, int y) { 
     icon.paintIcon(c, g, x, y); 
     if (getSelectionState() != 1) return; 

     int w = getIconWidth(); 
     int h = getIconHeight(); 
     g.setColor(c.isEnabled() ? new Color(51, 51, 51) : new Color(122, 138, 153)); 
     g.fillRect(x+4, y+4, w-8, h-8); 

     if (!c.isEnabled()) return; 
     g.setColor(new Color(81, 81, 81)); 
     g.drawRect(x+4, y+4, w-9, h-9); 
    } 

    @Override 
    public int getIconWidth() { 
     return icon.getIconWidth(); 
    } 

    @Override 
    public int getIconHeight() { 
     return icon.getIconHeight(); 
    } 

    public void actionPerformed(ActionEvent e) { 
     TCheckBox tcb = (TCheckBox)e.getSource(); 
     if (tcb.getSelectionState() == 0) 
      tcb.setSelected(false); 

     tcb.putClientProperty("SelectionState", tcb.getSelectionState() == 2 ? 0 : 
                tcb.getSelectionState() + 1); 

     // test 
     System.out.println(">>>>IS SELECTED: "+tcb.isSelected()); 
     System.out.println(">>>>IN MID STATE: "+(tcb.getSelectionState()==1)); 
    } 
} 

sử dụng: TCheckBox tcb = new TCheckBox("My CheckBox");

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