2012-09-08 91 views
2

我有一個具有多個JCheckBox的Swing應用程序。每個JCheckBox對應於Foo類型的另一個對象在我的程序中的其他地方。對於Foo類型的每個對象,我將會有一個JCheckBoxes供用戶點擊(它告訴Foo對象是否應該在UI上顯示)。我應該擴展Swing JCheckBox嗎?

我目前所做的是使用JCheckBox的名稱屬性作爲對象Foo的字符串「名稱」的參考。我覺得更簡潔的解決方案是擴展JCheckBox來爲它添加一個額外的字段,以便JCheckBox可以通過簡單地存儲對它的引用來跟蹤它附加到哪個Foo對象。思考?人們是否定期擴展Swing組件,以便他們可以將控制器/視圖中的部件鏈接回模型?我會遇到一些可怕的陷阱嗎?

回答

4

這個特殊的例子很難得到完整的畫面,沒有額外的細節。您可以使用操作完成此任務。有關更多詳細信息,請參閱How to Use Actions。下面是一個例子:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.*; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.io.PrintStream; 
import java.util.ArrayList; 
import java.util.List; 

import javax.swing.*; 

public class CheckBoxDemo { 

    static class Foo { 
     private boolean visible; 
     private String name; 

     public Foo(String name) { 
      this.name = name; 
     } 

     public boolean isVisible() { 
      return visible; 
     } 

     public void setVisible(boolean visible) { 
      this.visible = visible; 
      System.out.println(getName() + ".setVisible:" + visible); 
     } 

     public String getName() { 
      return name; 
     } 
    } 

    static class FooAction extends AbstractAction { 
     private Foo foo; 

     public FooAction(Foo foo) { 
      super(foo.getName()); 
      this.foo = foo; 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      JCheckBox checkBox = (JCheckBox) e.getSource(); 
      foo.setVisible(checkBox.isSelected()); 
     } 
    } 

    private static void createAndShowGUI() { 
     List<Foo> fooList = new ArrayList<Foo>(); 
     fooList.add(new Foo("Foo1")); 
     fooList.add(new Foo("Foo2")); 
     fooList.add(new Foo("Foo3")); 

     JPanel content = new JPanel(new BorderLayout()); 

     JPanel fooPanel = new JPanel(); 
     for (Foo foo : fooList) { 
      fooPanel.add(new JCheckBox(new FooAction(foo))); 
     } 

     content.add(fooPanel, BorderLayout.NORTH); 

     final JTextArea textArea = new JTextArea(); 
     textArea.setEditable(false); 
     JScrollPane scrollPane = new JScrollPane(textArea); 
     scrollPane.setPreferredSize(new Dimension(200, 200)); 
     content.add(scrollPane, BorderLayout.CENTER); 

     JFrame frame = new JFrame("CheckBoxDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(content); 

     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 

     // just for brevity of example 
     System.setOut(new PrintStream(new OutputStream() { 
      @Override 
      public void write(int b) throws IOException { 
       textArea.append(String.valueOf((char) b)); 
      } 
     })); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 
+0

+1爲了指出正確的方向:-) – kleopatra

+0

好吧,你說我應該使用動作來跟蹤JCheckBox和Foo對象之間的連接。所以Action知道它所代表的JCheckBox和Foo對象,並且當JCheckBox的狀態改變時它可以相應地改變Foo對象的狀態。 – Jazzepi

0

這是一個常見的要求,你可以將JCheckbox延伸到一些JFooCheckBox其中有Foo對象,並且一個監聽器應該照顧Foo的顯示/隱藏。

+0

否,JSomethings被設計爲可以使用,因爲它們是 – kleopatra

3

的一般規則是不應用原因延伸JSomething:它們被設計爲可使用,因爲它們。

您的上下文聽起來像是一個綁定場景。 @Max建議(使用動作作爲綁定代理)指出了遵循的方向,對於更復雜的需求,您可能會考慮使用綁定框架(如JGoodies或BetterBeansBinding)

相關問題