2016-12-06 13 views
2

以下のコードでは、に含まれるJLabelの2つのJToggleButtonsを持つJTreeの例があります。編集中に予期しない値が返される

この葉はJTreeのようになります。

enter image description here

そしてJToggleButtonsの一つをクリックすると、クリックされたトグルボタンの色を変更する必要があります。しかし、出力は以下のように非常に異なっています。

enter image description here

なぜこれが起こっているとどのように私は問題を解決することができますか?

注:この戻り値はCheckBoxNodeEditor

import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.*; 
import java.io.*; 
import java.util.*; 

import javax.swing.*; 
import javax.swing.border.*; 
import javax.swing.event.*; 
import javax.swing.tree.*; 
import javax.swing.table.*; 
import javax.swing.plaf.basic.*; 
import javax.swing.plaf.metal.*; 

@SuppressWarnings("serial") 
public class DirectoryExplorer extends JFrame { 
    private DirectoryExplorer() { 
     super("Directory Explorer"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLayout(new GridLayout(1, 1)); 
     createPanel(); 
     setSize(800,600); 
     setVisible(true); 
    } 

    private void createPanel() { 
     DefaultMutableTreeNode colors = new DefaultMutableTreeNode("Colours"); 
     colors.add(new DefaultMutableTreeNode("Red")); 
     colors.add(new DefaultMutableTreeNode("Green")); 
     colors.add(new DefaultMutableTreeNode("Blue")); 

     DefaultMutableTreeNode falvors = new DefaultMutableTreeNode("Flavours"); 
     falvors.add(new DefaultMutableTreeNode("Toffee")); 
     falvors.add(new DefaultMutableTreeNode("Fudge")); 
     falvors.add(new DefaultMutableTreeNode("Chocolate")); 

     DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); 
     root.add(colors); 
     root.add(falvors); 
     root.add(new DefaultMutableTreeNode("Leafy")); 

     JPanel panel = new JPanel(new GridLayout(1, 1)); 
     JTree tree = new JTree(root); 

     FileNameRenderer fileRender = new FileNameRenderer(); 
     tree.setCellRenderer(fileRender); 

     tree.setCellEditor(new CheckBoxNodeEditor(tree)); 
     tree.setEditable(true); 

     tree.setShowsRootHandles(true); 

     panel.add(new JScrollPane(tree)); 
     getContentPane().add(panel); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() -> new DirectoryExplorer()); 
    } 

    private class FileNameRenderer extends DefaultTreeCellRenderer { 
     private DefaultChkBx def = new DefaultChkBx(); 
     private FavouriteChkBx fav = new FavouriteChkBx(); 

     protected DefaultChkBx getDefBut() { 
      return def; 
     } 

     protected FavouriteChkBx getFavBut() { 
      return fav; 
     } 

     @Override 
     public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { 
      JComponent c = (JComponent) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); 
      return new Holder((JLabel) c, def, fav); 
     } 

     public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus, boolean defSel, boolean favSel) { 
      JComponent c = (JComponent) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); 
      def.setSelected(defSel); 
      fav.setSelected(favSel); 
      return new Holder((JLabel) c, def, fav); 
     } 
    } 

    private class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor { 
     FileNameRenderer renderer = new FileNameRenderer(); 
     ChangeEvent changeEvent = null; 
     JTree t; 
     TreePath path; 
     DefaultChkBx def = renderer.getDefBut(); 
     FavouriteChkBx fav = renderer.getFavBut(); 

     public CheckBoxNodeEditor(JTree tree) { 
      t = tree; 
     } 

     public Object getCellEditorValue() { 
      def = renderer.getDefBut(); 
      fav = renderer.getFavBut(); 

      def.setSelected(def.isSelected()); 
      fav.setSelected(fav.isSelected()); 

      Holder checkBoxNode = new Holder(new JLabel((((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject().toString())), def, fav); 
      return checkBoxNode; 
     } 

     public boolean isCellEditable(EventObject event) { 
      if(event instanceof MouseEvent) { 
       MouseEvent mouseEvent = (MouseEvent) event; 
       path = t.getPathForLocation(mouseEvent.getX(), mouseEvent.getY()); 
       if (path != null) { 
        Object node = path.getLastPathComponent(); 
        if ((node != null) && (node instanceof DefaultMutableTreeNode)) { 
         DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node; 
         Object userObject = treeNode.getUserObject(); 
         return (userObject instanceof String); 
        } 
       } 
      } 
      return false; 
     } 

     public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) { 
      Component editor = renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, true); 
      ItemListener itemListener = new ItemListener() { 
       public void itemStateChanged(ItemEvent itemEvent) { 
        if (stopCellEditing()) 
         fireEditingStopped(); 
       } 
      }; 

      if (editor instanceof Holder) { 
       for(Component c : ((Holder) editor).getComponents()) { 
        if(c instanceof DefaultChkBx) 
         ((DefaultChkBx) c).addItemListener(itemListener); 
        else if(c instanceof FavouriteChkBx) 
         ((FavouriteChkBx) c).addItemListener(itemListener); 
       } 
      } 

      return editor; 
     } 
    } 

    private class Holder extends JPanel { 
     public Holder(Component c, DefaultChkBx def, FavouriteChkBx fav) { 
      setLayout(new GridBagLayout()); 
      setBackground(Color.BLACK); 
      setOpaque(false); 
      addComponents(c, def, fav); 
     } 

     private void addComponents(Component c, DefaultChkBx def, FavouriteChkBx fav) { 
      GridBagConstraints gBC = new GridBagConstraints(); 

      gBC.insets = new Insets(0, 0, 0, 5); 
      add(c, gBC); 

      gBC.insets = new Insets(0, 0, 0, 0); 
      add(def, gBC); 
      add(fav, gBC); 
     } 
    } 

    private class DefaultChkBx extends JToggleButton { 
     public DefaultChkBx() { 
      setUI(new MetalToggleButtonUI() { 
       @Override 
       protected Color getSelectColor() { 
        return new Color(242, 0, 255); 
       } 
      }); 
      setBorder(null); 
      setForeground(Color.GRAY); 
      setText("Default"); 
      setFocusPainted(false); 
     } 
    } 

    private class FavouriteChkBx extends JToggleButton { 
     public FavouriteChkBx() { 
      setUI(new MetalToggleButtonUI() { 
       @Override 
       protected Color getSelectColor() { 
        return Color.RED; 
       } 
      }); 
      setBorder(null); 
      setForeground(Color.GRAY); 
      setText("Favourite"); 
      setFocusPainted(false); 
     } 
    } 
} 

答えて

2

public component getTreeCellEditorComponent(...)で見つけることができ、あなたのgetCellEditorValue()編集されたオブジェクト(リーフに表示され、通常、Stringオブジェクト)の値を返す必要があります。

代わりに、メソッドはHolderのインスタンスを返します。 toString()メソッドがこのオブジェクトに対して呼び出され、ツリーによって表示されます(これは、表示している "DirectoryExplorer $ Holder [.....]ディスプレイです)。

最初に、このメソッド(「リーフィー」など)から単純なStringを返すことができます。

+0

ああ、そうです。では、 'String'を返す場合、どのように更新するためにブール値を取得するのですか? – Dan

+1

これはツリーモデルで行う必要があります。現在、各ノードのStringオブジェクトを格納するデフォルトモデルを使用します。しかし、ブール値を持つカスタムモデルを使うことができます。そして、編集が止まると、エディタは自動的にあなたのモデルで 'setValue()'メソッドを呼び出すはずです。 –

+0

よろしくお願いします – Dan

関連する問題