2016-02-13 2 views
0

Pour mon programme d'arborescence binaire, j'ai utilisé JTextFields comme nœuds et je suis parvenu à le faire lorsque je clique sur le bouton gauche et sélectionne deux des JTextFields, il va tracer une ligne entre eux. Le problème est que si je veux faire glisser le JtextField, je veux que la ligne suive également entre deux des points centraux du JTextField. Je ne sais pas si c'est possible en utilisant uniquement paintComponent ou non. Je l'ai essayé, mais c'est comme une chose unique et il va laisser une trace de toutes les lignes précédemment dessinées. Ici, est le code jusqu'à présent, il existe d'autres classes de sorte que certains des bits ne fonctionneront pas. Le code a été bidouillé un peu aussi pour les tests.Dessiner et faire glisser des lignes en utilisant paintComponent sans infliger d'autres composants GUI dans un JPanel

BinaryTreeMainPnl public class étend JPanel {

public static Graphics g1; 
public int Width = 75; 
public int Height = 45; 
public String tempNode1 = ""; 
public int tempNode1Pos = 0; 
public int tempNode2Pos = 0; 
public String tempNode2 = ""; 
public static boolean leftBtnSelected; 
public static boolean rightBtnSelected; 
private static int x1, y1 = 50; 
private static int x2, y2 = 500; 

JToggleButton leftBtn = new JToggleButton("Left"); 
JToggleButton rightBtn = new JToggleButton("Right"); 
JTextField[] myArray = new JTextField[60]; 
ArrayList<String> nodeNames = new ArrayList<String>(); 
JFrame MainFrame; 
JTextField txtFld1 = new JTextField("Enter Questions here"); 
JButton btn1 = new JButton("Submit"); 

public BinaryTreeMainPnl(JFrame frame) { 
    super(); 

    setSize(800, 700); 
    MainFrame = frame; 
    readInput(); 
    leftBtn.setFont(new Font("Arial", Font.BOLD, 15)); 
    leftBtn.setForeground(Color.blue); 
    leftBtn.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent evt) { 
      rightBtn.setSelected(false); 
      leftBtnSelected = leftBtn.getModel().isSelected(); 
      rightBtnSelected = false; 

      System.out.println(leftBtnSelected); 
      System.out.println(rightBtnSelected); 
     } 
    }); 
    add(leftBtn); 

    rightBtn.setFont(new Font("Arial", Font.BOLD, 15)); 
    rightBtn.setForeground(Color.green); 
    rightBtn.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent evt) { 
      leftBtn.setSelected(false); 
      rightBtnSelected = rightBtn.getModel().isSelected(); 
      leftBtnSelected = false; 
      System.out.println(leftBtnSelected); 
      System.out.println(rightBtnSelected); 
     } 
    }); 
    add(rightBtn); 

} 

@Override 
public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    updateLine(g); 

} 

public void readInput() { 
    btn1.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent evt) { 
      identifyNodeNames(txtFld1.getText()); 
      displayNodes(nodeNames); 
      new TreeSorting().treeSort(nodeNames); 
     } 
    }); 
    this.add(txtFld1); 
    this.add(btn1); 

} 

public void displayNodes(ArrayList<String> nodeNames) { 

    for (int i = 0; i < nodeNames.size(); i++) { 
     String currentSetText = nodeNames.get(i); 
     myArray[i] = new JTextField(currentSetText); 
     myArray[i].setEditable(false); 
    } 

    for (int i = 0; i < nodeNames.size(); i++) { 
     int I = i; 
     myArray[I].addMouseMotionListener(new MouseAdapter() { 

      @Override 
      public void mouseDragged(MouseEvent evt) { 

       int x = evt.getX() + myArray[I].getX(); 
       int y = evt.getY() + myArray[I].getY(); 
       myArray[I].setBounds(x, y, myArray[I].getWidth(), myArray[I].getWidth()); 
       System.out.println(myArray[I] + "dragged"); 

      } 

     }); 
     myArray[I].addMouseListener(new MouseAdapter() { 

      @Override 

      public void mouseClicked(MouseEvent evt) { 
       if (leftBtnSelected) { 
        if (tempNode1.equals("")) { 
         tempNode1 = myArray[I].getText(); 
         System.out.println(tempNode1 + "clicked"); 
        } else { 
         tempNode2 = myArray[I].getText(); 
         System.out.println(tempNode2 + "Clicked as well"); 
         leftBtn.setSelected(false); 
         leftBtnSelected = false; 
         x1 = 40; 
         y1 = 40; 
         x2 = 400; 
         y2 = 400; 
         updateLine(g1); 
         System.out.println("asdasd"); 

        } 
       } 
       if (rightBtnSelected) { 

       } 
      } 

      public void moveComponent(MouseEvent evt) { 

      } 
     }); 
     System.out.println("I " + I); 
     System.out.println(myArray[I].getText()); 

     add(myArray[I]); 
    } 
    MainFrame.revalidate(); 

} 

public int findMidPoint(JTextField temp) { 
    Point p = temp.getLocation(); 
    Dimension d = temp.getSize(); 
    return p.x + (d.width)/2; 

} 
int coun = 0; 

public void updateLine(Graphics g) { 
    g.drawLine(x1, x2, y1, y2); 
    x1 = x1 + 10; 
    y1 = y1 + 10; 
    y2 = y2 + 10; 
    x2 = x2 + 10; 
    System.out.println("Line Updated" + coun); 
    coun++; 
} 

public void identifyNodeNames(String answer) { 
    int arrayCounter = 0; 
    int lastNodePosition = 0; 
    for (int i = 0; i < answer.length(); i++) { 
     char c = answer.charAt(i); 
     if (c == ',') { 
      nodeNames.add(arrayCounter, answer.substring(lastNodePosition, i + 1).replaceAll(",", "").replaceAll(" ", "")); 
      lastNodePosition = i + 1; 
      arrayCounter++; 
     } 

     if (i == answer.length() - 1) { 
      nodeNames.add(arrayCounter, answer.substring(lastNodePosition, answer.length()).replaceAll(" ", "")); 
     } 

    } 

} 

}

importation java.util.ArrayList;

public class TreeSorting {

public static int arrayLength; 
String[][] Child; 
String root = ""; 
boolean nodeSorted = false; 
int parentCounter = 1; 

public void treeSort(ArrayList<String> passedQuestions) { 
    // declaring nodes 
    arrayLength = passedQuestions.size(); 
    System.out.println(arrayLength + "ARRAY LENGTH"); 
    Child = new String[arrayLength][3]; 
    for (int i = 0; i < arrayLength; i++) { 
     Child[i][0] = passedQuestions.get(i); 
    } 
    //initially calling the mainprocess with parentCounter 1; 
    root = Child[0][0]; 
    mainProcess(1); 

} 

public void mainProcess(int parentCounter) { 

    if (parentCounter < Child.length) { 
     System.out.println(parentCounter); 
     sortingTree(Child[parentCounter][0], root, 0); //where the next node is passed on the tree is sorted recursively 
     for (int i = 0; i < Child.length; i++) { 
      System.out.println(Child[i][0]); 
      System.out.println(Child[i][1] + "," + Child[i][2]); 
     } 

    } 
} 

public void sortingTree(String CurrentNode, String PreviousNode, int PreviousPosition) { 
    nodeSorted = false;// node is not sorted in the beginning 
    if (isAfter(CurrentNode.toLowerCase(), PreviousNode.toLowerCase())) { 
     System.out.println(Child[PreviousPosition][2]); 
     if (Child[PreviousPosition][2] == null) { //checks if the right of the node is empty, if found empty the node is placed there. 
      Child[PreviousPosition][2] = CurrentNode; 
      nodeSorted = true; // if the node finds a position in the array node is sorted. 
     } else { 
      sortingTree(CurrentNode, Child[PreviousPosition][2], getPositionInArray(Child[PreviousPosition][2])); 
      //if the array position was not empty, the loop will process again this time with the item found in the filled position. 
     } 
    } else if (Child[PreviousPosition][1] == null) { // if the left of the node is empty, the item will be placed there 
     Child[PreviousPosition][1] = CurrentNode; 
     nodeSorted = true; 
    } else { 
     sortingTree(CurrentNode, Child[PreviousPosition][1], getPositionInArray(Child[PreviousPosition][1])); 
     //if the array position was not empty, the loop will process again this time with the item found in the filled position. 
    } 

    if (nodeSorted) { // if the node finds a position in the array, the nodeCounter increments and the next node in the question is processed. 
     parentCounter++; 
     mainProcess(parentCounter); 
    } 
} 

public int getPositionInArray(String node) { 
    int position = 0; 
    loop: 
    for (int i = 0; i < Child.length; i++) { 
     if (Child[i][0].equals(node)) { 
      position = i; 
      break loop; 

     } 
    } 
    return position; 
} 

public boolean isAfter(String CurrentNode, String PreviousNode) { 
    int loopLength = determineLoopLength(CurrentNode, PreviousNode); 
    boolean result = false; 
    String tempCheck = ""; 
    loop: 
    for (int i = 0; i < loopLength; i++) { 
     if ((int) CurrentNode.charAt(i) > (int) PreviousNode.charAt(i)) { 
      result = true; 
      break loop; 
     } 
     if ((int) CurrentNode.charAt(i) < (int) PreviousNode.charAt(i)) { 
      result = false; 
      break loop; 
     } else if (CurrentNode.charAt(i) == PreviousNode.charAt(i) && CurrentNode.length() > PreviousNode.length()) { 
      System.out.println("I'm here"); 
      tempCheck = tempCheck + CurrentNode.charAt(i) + ""; 
      if (i == loopLength - 1 && tempCheck.equals(PreviousNode)) { 
       result = true; 
       break loop; 
      } 
     } 
    } 
    return result; 
} 

public int determineLoopLength(String CurrentNode, String PreviousNode) { 
    int loopLength = 0; 
    if (CurrentNode.length() < PreviousNode.length()) { 
     loopLength = CurrentNode.length(); 
    } 
    if (PreviousNode.length() < CurrentNode.length()) { 
     loopLength = PreviousNode.length(); 
    } else { 
     loopLength = CurrentNode.length(); 
    } 
    return loopLength; 
} 

}

+3

'« Je ne sais pas s'il est possible avec l'utilisation de seulement paintComponent ou pas. "- oui c'est possible. "" J'ai essayé mais c'est comme une chose unique et ça va laisser une trace de toutes les lignes précédemment dessinées. "- Et si nous pouvons voir votre meilleure tentative actuelle de code, de préférence posté ici avec votre question comme valide [mcve] et pas dans un lien, nous serons beaucoup mieux en mesure de vous aider à comprendre ce que vous faites de mal et ainsi vous aider à le corriger. Jusque-là, cette question ne sera pas facile à répondre. –

+0

Une estimation cependant - vous voudrez appeler la méthode 'super.paintComponent (g);' dans votre propre override, habituellement comme le premier appel de cette méthode. Cela aidera à nettoyer tous les pixels «sales», y compris les vieilles lignes tracées. –

+1

En plus de ce que dit Hovercraft, vous pouvez fournir un tel [MCVE] (https://stackoverflow.com/help/mcve) en cliquant sur le lien 'edit' ci-dessous votre question. Collez un exemple minimal complet et vérifiable dans votre question, sélectionnez le code et appuyez sur le bouton {}} pour formater le code correctement. –

Répondre

3

WTF, travaille sur ce point, .....

import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.RenderingHints; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class DragMyFields extends JPanel { 
    private static final int PREF_W = 1000; 
    private static final int PREF_H = 800; 
    private static final int COLS = 8; 
    private static final int DELTA_Y = 120; 
    private static final int MAX_DEPTH = 3; 
    private MySimpleTreeNode<JTextField> treeRoot = new MySimpleTreeNode<>(); 
    private MyMouse myMouse = new MyMouse(); 

    public DragMyFields() { 
     setLayout(null); // this is *** BAD *** 
       // much better would be to create a custom layout 

     JTextField field = new JTextField(COLS); 
     field.addMouseListener(myMouse); 
     field.addMouseMotionListener(myMouse); 
     field.setSize(field.getPreferredSize()); 
     int x = (PREF_W - field.getPreferredSize().width)/2; 
     int y = DELTA_Y; 
     field.setLocation(x, y); 
     add(field); 
     treeRoot.setNode(field); 

     recursiveCreateTree(treeRoot, MAX_DEPTH, x, y); 
    } 

    private void recursiveCreateTree(MySimpleTreeNode<JTextField> node, int depth, int x, int y) { 
     if (depth == 0) { 
      return; 
     } 

     JTextField leftField = new JTextField(COLS); 
     JTextField rightField = new JTextField(COLS); 

     MySimpleTreeNode<JTextField> leftNode = new MySimpleTreeNode<>(leftField); 
     MySimpleTreeNode<JTextField> rightNode = new MySimpleTreeNode<>(rightField); 
     node.setLeft(leftNode); 
     node.setRight(rightNode); 

     int multiplier = 4; 
     for (int i = 0; i < MAX_DEPTH - depth; i++) { 
      multiplier *= 2; 
     } 

     int xL = x - getPreferredSize().width/multiplier; 
     int xR = x + getPreferredSize().width/multiplier; 
     y += DELTA_Y; 

     leftField.setSize(leftField.getPreferredSize()); 
     rightField.setSize(rightField.getPreferredSize()); 
     leftField.setLocation(xL, y); 
     rightField.setLocation(xR, y); 
     leftField.addMouseListener(myMouse); 
     leftField.addMouseMotionListener(myMouse); 
     rightField.addMouseListener(myMouse); 
     rightField.addMouseMotionListener(myMouse); 
     add(leftField); 
     add(rightField); 

     recursiveCreateTree(leftNode, depth - 1, xL, y); 
     recursiveCreateTree(rightNode, depth - 1, xR, y); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     recursiveDraw(g, treeRoot); 
    } 

    private void recursiveDraw(Graphics g, MySimpleTreeNode<JTextField> node) { 
     MySimpleTreeNode<JTextField> left = node.getLeft(); 
     MySimpleTreeNode<JTextField> right = node.getRight(); 

     Point p = getNodeCenter(node); 

     if (left != null) { 
      Point p2 = getNodeCenter(left); 
      g.drawLine(p.x, p.y, p2.x, p2.y); 
      recursiveDraw(g, left); 
     } 
     if (right != null) { 
      Point p2 = getNodeCenter(right); 
      g.drawLine(p.x, p.y, p2.x, p2.y); 
      recursiveDraw(g, right); 
     } 

    } 

    private Point getNodeCenter(MySimpleTreeNode<JTextField> node) { 
     JTextField field = node.getNode(); 
     Point location = field.getLocation(); 
     Dimension size = field.getSize(); 
     return new Point(location.x + size.width/2, location.y + size.height/2); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private class MyMouse extends MouseAdapter { 
     Component source = null; 
     private Point pressedP; 
     private Point pressedLoc; 
     private Point parentP; 

     @Override 
     public void mousePressed(MouseEvent e) { 
      if (e.getButton() != MouseEvent.BUTTON1) { 
       return; 
      } 

      source = e.getComponent(); 
      parentP = source.getParent().getLocationOnScreen(); 
      pressedLoc = source.getLocationOnScreen(); 
      pressedP = e.getLocationOnScreen(); 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      moveComponent(e); 
      source = null; 
      pressedP = null; 
      pressedLoc = null; 
     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      if (source == null) { 
       return; 
      } 
      moveComponent(e); 
     } 

     private void moveComponent(MouseEvent e) { 
      Point p = e.getLocationOnScreen(); 
      int x = pressedLoc.x + p.x - pressedP.x - parentP.x; 
      int y = pressedLoc.y + p.y - pressedP.y - parentP.y; 

      Point newP = new Point(x, y); 
      source.setLocation(newP); 
      repaint(); 
     } 
    } 

    private static void createAndShowGui() { 
     DragMyFields mainPanel = new DragMyFields(); 

     JFrame frame = new JFrame("DragMyFields"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> { 
      createAndShowGui(); 
     }); 
    } 
} 

class MySimpleTreeNode<T> { 
    private T node; 
    private MySimpleTreeNode<T> left; 
    private MySimpleTreeNode<T> right; 

    public MySimpleTreeNode() { 
     // default constructor 
    } 

    public MySimpleTreeNode(T node) { 
     this.node = node; 
    } 

    public void setNode(T node) { 
     this.node = node; 
    } 

    public T getNode() { 
     return node; 
    } 

    public MySimpleTreeNode<T> getLeft() { 
     return left; 
    } 

    public void setLeft(MySimpleTreeNode<T> left) { 
     this.left = left; 
    } 

    public MySimpleTreeNode<T> getRight() { 
     return right; 
    } 

    public void setRight(MySimpleTreeNode<T> right) { 
     this.right = right; 
    } 

} 
+0

Je peux voir où vous avez votre méthode moveComponent qui met à jour l'emplacement des noeuds (JTextFields) mais je n'arrive toujours pas à savoir où vous mettez à jour l'emplacement de la ligne, je peux seulement voir où il est dessiné. Pouvez-vous m'aider avec ça. Mais comment diable essayiez-vous de faire exactement la même chose? –

+0

@CuriousOne: les lignes sont dessinées dans une méthode récursive appelée par paintComponent et sont basées sur le point central calculé de chaque JTextField. La récursivité est à travers mon arbre simple. Quant à savoir comment diable essayais-je de faire la même chose? J'ai été intrigué par votre question et j'ai créé ceci sur place pour la question. –

+0

En d'autres termes, les lignes sont créées uniquement lorsqu'elles sont dessinées. C'est la seule fois qu'ils sont nécessaires, non? –