簡體   English   中英

JTree中的JTextField-使其可編輯

[英]JTextField in JTree - make it editable

有人有帶有復選框和文本字段的樹的示例代碼嗎? 因為現在我有一個代碼用於基於復選框的樹(僅)。 我還嘗試在樹中實現文本字段(使用Jlabels )。 但是我被困住了,我真的很困惑。 我再無所求,希望您能幫助我。

問題是。 我無法修改JTextFields的文本。 修改不會保存。 而且我不知道如何在JTextField的同一行中添加JLabel

Root
|
|- Node 1
    | - [-] Activate simulation
    | - [100] Iterations
|- Node 2
    | - [x] Activate simulation
    | - [2000] Iterations

package view;
import javax.swing.BoxLayout;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JTextField;
import org.jdesktop.swingx.JXTreeTable;
import org.jdesktop.swingx.treetable.AbstractTreeTableModel;
import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.event.DocumentListener;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.EventObject;
import java.util.Vector;

import javax.swing.AbstractCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.DocumentEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

public class test {

  private Document dom;

  private void parseXmlFile(String xmlpath){
        //get the factory
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

        try {

            //Using factory get an instance of document builder
            DocumentBuilder db = dbf.newDocumentBuilder();

            //parse using builder to get DOM representation of the XML file
            dom = db.parse(xmlpath);


        }catch(ParserConfigurationException pce) {
            pce.printStackTrace();
        }catch(SAXException se) {
            se.printStackTrace();
        }catch(IOException ioe) {
            ioe.printStackTrace();
        }
  } 

  public static void main(String args[]) {
    JFrame frame = new JFrame("CheckBox Tree");

    CheckBoxNode accessibilityOptions[] = {
        new CheckBoxNode(
            "Move system caret with focus/selection changes", false),
        new CheckBoxNode("Always expand alt text for images", true) };
    CheckBoxNode browsingOptions[] = {
        new CheckBoxNode("Notify when downloads complete", true),
        new CheckBoxNode("Disable script debugging", true),
        new CheckBoxNode("Use AutoComplete", true),
        new CheckBoxNode("Browse in a new process", false) 
        };
    TextBoxNode loloptions[] =
        {
                new TextBoxNode("oha", "lol"),
                new TextBoxNode("oha1", "lol"),
                new TextBoxNode("oha2", "lol")
        };

    Vector accessVector = new NamedVector("Accessibility",
        accessibilityOptions);
    Vector browseVector = new NamedVector("Browsing", browsingOptions);
    Vector browse1Vector = new NamedVector("Browsing", browsingOptions);
    Vector browse2Vector = new NamedVector("textboxnodes", loloptions);
    Object lolNodes[] = {browse1Vector, browseVector, browse2Vector};
    Vector lolvec = new NamedVector("Overking", lolNodes);
    Object rootNodes[] = { accessVector, lolvec};
    lolvec.add(new CheckBoxNode("oh",false));
    Vector rootVector = new NamedVector("Root", rootNodes);
    JTree tree = new JTree(rootVector);


    CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
    tree.setCellRenderer(renderer);

    tree.setCellEditor(new CheckBoxNodeEditor(tree));
    tree.setEditable(true);
    for (int i = 0; i < tree.getRowCount(); i++) {
        tree.expandRow(i);
    }

    JScrollPane scrollPane = new JScrollPane(tree);
    frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}

class CheckBoxNodeRenderer implements TreeCellRenderer {
      private JCheckBox leafRenderer = new JCheckBox();
      private JTextField leafRendererAlt = new JTextField();
      private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();

      Color selectionBorderColor, selectionForeground, selectionBackground,
          textForeground, textBackground;

      protected Object getLeafRenderer() {
        if(leafRenderer.getText().length() > 0)
            return leafRenderer;
        else
            return leafRendererAlt;
      }

      public CheckBoxNodeRenderer() {
        Font fontValue;
        fontValue = UIManager.getFont("Tree.font");
        if (fontValue != null) {
          leafRenderer.setFont(fontValue);
        }
        Boolean booleanValue = (Boolean) UIManager
            .get("Tree.drawsFocusBorderAroundIcon");
        leafRenderer.setFocusPainted((booleanValue != null)
            && (booleanValue.booleanValue()));

        selectionBorderColor = UIManager.getColor("Tree.selectionBorderColor");
        selectionForeground = UIManager.getColor("Tree.selectionForeground");
        selectionBackground = UIManager.getColor("Tree.selectionBackground");
        textForeground = UIManager.getColor("Tree.textForeground");
        textBackground = UIManager.getColor("Tree.textBackground");
      }

      public Component getTreeCellRendererComponent(JTree tree, Object value,
          boolean selected, boolean expanded, boolean leaf, int row,
          boolean hasFocus) {

        Component returnValue;
        if (leaf) {

          String stringValue = tree.convertValueToText(value, selected,
              expanded, leaf, row, false);

          if(stringValue.contains("TextBoxNode"))
          {
              leafRenderer = new JCheckBox();
              leafRendererAlt.setText(stringValue);
              //leafRendererAlt.setValue(value);

              leafRendererAlt.setEnabled(tree.isEnabled());

              if (selected) {
                  leafRendererAlt.setForeground(selectionForeground);
                  leafRendererAlt.setBackground(selectionBackground);
              } else {
                  leafRendererAlt.setForeground(textForeground);
                  leafRendererAlt.setBackground(textBackground);
              }

              if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
                Object userObject = ((DefaultMutableTreeNode) value)
                    .getUserObject();
                if (userObject instanceof TextBoxNode) {
                  TextBoxNode node = (TextBoxNode) userObject;
                  leafRendererAlt.setText(node.getText());
                }
              }
              returnValue = leafRendererAlt;
          }
          else
          {
              leafRendererAlt = new JTextField();
              leafRenderer.setText(stringValue);
              leafRenderer.setSelected(false);

              leafRenderer.setEnabled(tree.isEnabled());

              if (selected) {
                leafRenderer.setForeground(selectionForeground);
                leafRenderer.setBackground(selectionBackground);
              } else {
                leafRenderer.setForeground(textForeground);
                leafRenderer.setBackground(textBackground);
              }

              if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
                Object userObject = ((DefaultMutableTreeNode) value)
                    .getUserObject();
                if (userObject instanceof CheckBoxNode) {
                  CheckBoxNode node = (CheckBoxNode) userObject;
                  leafRenderer.setText(node.getText());
                  leafRenderer.setSelected(node.isSelected());
                }
              }
              returnValue = leafRenderer;
          }
        } else {
          returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree,
              value, selected, expanded, leaf, row, hasFocus);
        }
        return returnValue;
      }
}

class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {

      CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();

      ChangeEvent changeEvent = null;

      JTree tree;

      public CheckBoxNodeEditor(JTree tree) {
        this.tree = tree;
      }

      public Object getCellEditorValue() {
        JCheckBox checkbox;
        JTextField textfield;
        CheckBoxNode checkBoxNode;
        TextBoxNode txtBoxNode;
        if(renderer.getLeafRenderer() instanceof JCheckBox)
        {
            checkbox = (JCheckBox) renderer.getLeafRenderer();
            checkBoxNode = new CheckBoxNode(checkbox.getText(),
            checkbox.isSelected());
            return checkBoxNode;
        }
        else
        {
            textfield = (JTextField) renderer.getLeafRenderer();
            String txt = textfield.getText();
            txtBoxNode = new TextBoxNode(txt, txt);
            return txtBoxNode;  
        }


      }

      public boolean isCellEditable(EventObject event) {
        boolean returnValue = false;
        if (event instanceof MouseEvent) {
          MouseEvent mouseEvent = (MouseEvent) event;
          TreePath path = tree.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();
              if((userObject instanceof TextBoxNode) || (userObject instanceof CheckBoxNode))
                  returnValue = treeNode.isLeaf();
            }
          }
        }
        return returnValue;
      }

      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);

        // editor always selected / focused
        ItemListener itemListener = new ItemListener() {
          public void itemStateChanged(ItemEvent itemEvent) {
            if (stopCellEditing()) {
              fireEditingStopped();
            }
          }
        };

        DocumentListener doclistener = new DocumentListener(){
              public void changedUpdate(DocumentEvent e) {
                    System.out.print(e);
                  }

            @Override
            public void insertUpdate(DocumentEvent arg0) {
                // TODO Auto-generated method stub
                javax.swing.text.Document test = arg0.getDocument();
                System.out.print(arg0);
                fireEditingStopped();


            }

            @Override
            public void removeUpdate(DocumentEvent arg0) {
                // TODO Auto-generated method stub
                System.out.print(arg0);
            }
        };
        if (editor instanceof JCheckBox) {
          ((JCheckBox) editor).addItemListener(itemListener);
        }
        else if (editor instanceof JTextField) 
        {
            ((JTextField) editor).getDocument().addDocumentListener(doclistener);
        }
        return editor;
      }
}

class CheckBoxNode {
      String text;

      boolean selected;

      public CheckBoxNode(String text, boolean selected) {
        this.text = text;
        this.selected = selected;
      }

      public boolean isSelected() {
        return selected;
      }

      public void setSelected(boolean newValue) {
        selected = newValue;
      }

      public String getText() {
        return text;
      }

      public void setText(String newValue) {
        text = newValue;
      }

      public String toString() {
        return getClass().getName() + "[" + text + "/" + selected + "]";
      }
}
class TextBoxNode{
      String text;

      String value;

      public TextBoxNode(String text, String value) {
        this.text = text;
        this.value = value;
      }

      public String getValue() {
        return value;
      }

      public void setValue(String newvalue) {
          value = newvalue;
      }

      public String getText() {
        return text;
      }

      public void setText(String newValue) {
        text = newValue;
      }

      public String toString() {
        return getClass().getName() + "[" + text + "/" + value + "]";
      }
}

class NamedVector extends Vector {
      String name;

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

      public NamedVector(String name, Object elements[]) {
        this.name = name;
        for (int i = 0, n = elements.length; i < n; i++) {
          add(elements[i]);
        }
      }

      public String toString() {
        return "[" + name + "]";
      }
}

問題是。 我無法修改JTextFields的文本。 而且我不知道如何在JTextField的同一行中添加JLabel

我希望你能幫助我。

原則上,您應該徹底分離渲染器和編輯器。 在您的情況下,它們緊密地聯系在一起(實際上,編輯器返回渲染器的JTextField實例)...渲染器不應被編輯。 在您的情況下,我懷疑是否曾召集過編輯。

我看到兩種可能的解決方案:

  • 大量重構代碼,以分離渲染和編輯(例如,使用JLabel渲染和使用JTextField編輯-或僅使用DefaultTreeCellEditor示例在此處 )。 讓樹確定何時開始編輯,何時調用編輯器,何時取消編輯等...
  • 或者,您可以繞過標准的編輯機制(因為您已經或多或少地做了一些工作):從代碼中完全刪除TreeCellEditor ,然后讓渲染器完成所有工作。 將適當的偵聽器添加到渲染器內的JTextFieldJCheckBox ,並在進行更改時更新模型。 (請注意,一個缺點是您將擁有原始的編輯機制:例如,如果用戶按下ESC,則不會取消編輯)。

關於:

而且我不知道如何在JTextField的同一行中添加JLabel

只需讓您的渲染器返回一個JPanel即可,並在其中添加JTextFieldJLabel

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM