Swing自定義組件: JCheckTree

          今天有一美女..說想要帶JCheckBox的JTree.其實想一想..沒什么不好實現(xiàn)的.
          一個Renderer 一個Listener 應(yīng)該可以搞定.. 自定義組件..關(guān)鍵就在交互事件上..
          |----------------------------------------------------------------------------------------|
                               版權(quán)聲明  版權(quán)所有 @chensiyu
                      引用請注明來源 
          www.aygfsteel.com/chensiyu04

                      本文由  陳思羽 于 2011年8月24號 出品..
          |----------------------------------------------------------------------------------------|



          4個類.分別為:CheckTreeDemo,CheckTree,Node,CheckRenderer,CheckListener

          從類名可以看出來. CheckTreeDemo是JFrame類 CheckTree是組件,Node是數(shù)據(jù)模型,CheckRenderer是CheckTree得渲染,CheckListener是CheckTree的事件


          package tree;

          import java.awt.BorderLayout;
          import javax.swing.JFrame;
          import javax.swing.JPanel;
          import javax.swing.SwingUtilities;

          /**
           *
           * 
          @author chensiyu
           * @createDate 2011/8/24
           
          */
          public class CheckTreeDemo extends JPanel {

              
          private CheckTree checkTree;
              
              
          public CheckTreeDemo() {
                  init();
              }
              
              
          private void init(){
                  setLayout(
          new BorderLayout());
                  
                  Node rootNode 
          = new Node("Root");
                  Node []nodes 
          = new Node[10];
                  
          for(int i = 0;i <nodes.length;i++){
                      Node node 
          = new Node("Node-"+i);
                      rootNode.add(node);
                  }
                  checkTree 
          = new CheckTree(rootNode);
                  add(checkTree,BorderLayout.CENTER);
                  
              }

              
          public static void main(String[] args) {
                  
          final JFrame frame = new JFrame();
                  frame.setTitle(
          "CheckTree");
                  frame.setLayout(
          new BorderLayout());
                  frame.setSize(
          200400);
                  frame.getContentPane().add(
          new CheckTreeDemo());
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  SwingUtilities.invokeLater(
          new Runnable() {

                      @Override
                      
          public void run() {
                          frame.setVisible(
          true);
                      }
                  });
              }
          }


          package tree;

          import javax.swing.JTree;
          import javax.swing.tree.TreeNode;

          /**
           *
           * 
          @author chensiyu
           * @createDate 2011/8/24
           
          */
          public class CheckTree extends JTree {

              
          private CheckRenderer checkRenderer;
              
          private CheckListener checkListener;

              
          public CheckTree() {
                  init();
              }

              
          public CheckTree(TreeNode node) {
                  
          super(node);
                  init();
              }

              
          private void init() {
                  checkRenderer 
          = new CheckRenderer();
                  checkListener 
          = new CheckListener();
                  setCellRenderer(checkRenderer);
                  addMouseListener(checkListener);
              }
          }

          package tree;

          import javax.swing.tree.DefaultMutableTreeNode;

          /**
           *
           * 
          @author chensiyu
           * @createDate 2011/8/24
           
          */
          public class Node extends DefaultMutableTreeNode{

              
          private String name = "";
              
          private boolean selected = false;

              
          public Node(String name){
                  
          super(name);
                  setName(name);
              }
              
          public String getName() {
                  
          return name;
              }

              
          public void setName(String name) {
                  
          this.name = name;
              }

              
          public boolean isSelected() {
                  
          return selected;
              }

              
          public void setSelected(boolean selected) {
                  
          this.selected = selected;
              }
          }

          package tree;

          /**
           *
           * 
          @author chensiyu
           * @createDate 2011/8/24
           
          */
          import java.awt.*;
          import javax.swing.*;
          import javax.swing.tree.*;

          class CheckRenderer extends JPanel implements TreeCellRenderer {

              
          protected static JCheckBox check;
              
          protected JLabel label;
              
          private static Rectangle checkBounds;

              
          public CheckRenderer() {
                  setLayout(
          null);
                  add(check 
          = new JCheckBox());
                  add(label 
          = new JLabel(""));
                  check.setBackground(UIManager.getColor(
          "Tree.textBackground"));
                  label.setForeground(UIManager.getColor(
          "Tree.textForeground"));
              }

              @Override
              
          public Component getTreeCellRendererComponent(JTree tree, Object value,
                      
          boolean isSelected, boolean expanded, boolean leaf, int row,
                      
          boolean hasFocus) {
                  String stringValue 
          = tree.convertValueToText(value, isSelected,
                          expanded, leaf, row, hasFocus);
                  setEnabled(tree.isEnabled());
                  label.setFont(tree.getFont());
                  label.setText(stringValue);
                  setBackground(tree.getBackground());
                  setForeground(tree.getForeground());
                  
                  
          if(value instanceof Node){
                      Node node 
          = (Node)value;
                      check.setSelected(node.isSelected());
                  }
                  
          return this;
              }

              @Override
              
          public Dimension getPreferredSize() {
                  Dimension d_check 
          = check.getPreferredSize();
                  Dimension d_label 
          = label.getPreferredSize();
                  
          return new Dimension(d_check.width + d_label.width,
                          (d_check.height 
          < d_label.height ? d_label.height
                          : d_check.height));
              }

              @Override
              
          public void doLayout() {
                  Dimension d_check 
          = check.getPreferredSize();
                  Dimension d_label 
          = label.getPreferredSize();
                  
          int y_check = 0;
                  
          int y_label = 0;
                  
          if (d_check.height < d_label.height) {
                      y_check 
          = (d_label.height - d_check.height) / 2;
                  } 
          else {
                      y_label 
          = (d_check.height - d_label.height) / 2;
                  }
                  check.setLocation(
          0, y_check);
                  check.setBounds(
          0, y_check, d_check.width, d_check.height);
                  label.setLocation(d_check.width, y_label);
                  label.setBounds(d_check.width, y_label, d_label.width, d_label.height);
                  
          if (checkBounds == null){
                      checkBounds 
          = check.getBounds();
                  }
                          
              }
              
              
          public static Rectangle getCheckBoxRectangle() {
                  
          ifnull == checkBounds )
                      
          return new Rectangle(0,0,0,0);
                  
          return (Rectangle) checkBounds.clone();
              }
          }

          package tree;

          import java.awt.Point;
          import java.awt.Rectangle;
          import java.awt.event.MouseAdapter;
          import java.awt.event.MouseEvent;
          import javax.swing.JTree;
          import javax.swing.tree.TreePath;

          /**
           *
           * 
          @author chensiyu
           * @createDate 2011/8/24
           
          */
          class CheckListener extends MouseAdapter {

              
          public CheckListener() {
              }

              @Override
              
          public void mouseClicked(MouseEvent e) {
                  JTree tree 
          = (JTree) e.getSource();
                  Point p 
          = e.getPoint();
                  
          int x = e.getX();
                  
          int y = e.getY();
                  
          int row = tree.getRowForLocation(x, y);
                  TreePath path 
          = tree.getPathForRow(row);

                  
          if (null == path) {
                      
          return;
                  }

                  Object component 
          = path.getLastPathComponent();
                  
          if (null == component) {
                      
          return;
                  }

                  
          if (component instanceof Node) {
                      Rectangle chRect 
          = CheckRenderer.getCheckBoxRectangle();
                      Rectangle rowRect 
          = tree.getPathBounds(path);
                      chRect.setLocation(chRect.x 
          + rowRect.x, chRect.y + rowRect.y);
                      
          if (e.getClickCount() == 1 && chRect.contains(p)) {
                          Node node 
          = (Node)component;
                          node.setSelected(
          !node.isSelected());
                          tree.repaint();
                      }
                  }
              }
          }

          posted on 2011-08-24 18:08 相信 閱讀(2239) 評論(2)  編輯  收藏 所屬分類: Swing文章

          評論

          # re: Swing自定義組件: JCheckTree[未登錄] 2011-08-25 08:43 greatghoul

          請問為什么要這樣做,而不是直接frame.setVisible(true)呢?
          SwingUtilities.invokeLater(new Runnable() {

          @Override
          public void run() {
          frame.setVisible(true);
          }
          });  回復(fù)  更多評論   

          # re: Swing自定義組件: JCheckTree 2011-08-25 09:57 相信

          @greatghoul

          關(guān)于這個問題.你可以參考 JDK API 里 關(guān)于 Swing 的線程策略 .

          簡單的說.
          通常 Swing 不是線程安全的。除非另行說明,否則所有 Swing 組件及相關(guān)類都必須在事件調(diào)度線程上訪問。  回復(fù)  更多評論   

          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          統(tǒng)計

          公告

          不顯示applet

          常用鏈接

          留言簿(16)

          我參與的團隊

          隨筆檔案

          文章分類

          文章檔案

          新聞檔案

          相冊

          swingchina 專業(yè)搞Swing的網(wǎng)站

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 台北县| 应用必备| 马鞍山市| 达州市| 巴塘县| 新民市| 宁安市| 岢岚县| 河北区| 青海省| 淳安县| 长乐市| 汉沽区| 毕节市| 庆元县| 麟游县| 祁门县| 新竹市| 五莲县| 尚志市| 浪卡子县| 陆丰市| 沙雅县| 禹州市| 博湖县| 巢湖市| 枞阳县| 上蔡县| 定安县| 手机| 乌审旗| 南汇区| 灌云县| 沙河市| 法库县| 英吉沙县| 大埔区| 习水县| 英德市| 宿松县| 海兴县|