使用 paintComponent 绘制和拖动线条,而无需在 JPanel 中使用任何其他 GUI 组件



对于我的二叉树程序,我一直在使用JTextFields作为节点,并且我已经设法做到了这一点,因此当我单击左键并选择两个JTextFields时,它将在它们之间画一条线。问题是,如果我想拖动 JtextField,我希望这条线也跟随 JTextField 的两个中点之间。 我不知道是否可能仅使用paintComponent。我确实尝试过,但它就像一次性的东西,它会留下所有以前绘制的线条的痕迹。这是到目前为止的代码,还有其他类,所以有些位不起作用。代码也经过了一些修改以进行测试。

public class BinaryTreeMainPnl extensions 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(" ", ""));
        }
    }
}

}

import java.util.ArrayList;

公共类树排序 {

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

}

WTF一直在研究这个问题,.....

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

最新更新