Tôi đang gặp vấn đề và hy vọng, ai đó biết điều gì đang xảy ra và tại sao tôi có thể giải thích những gì tôi đang bỏ lỡ ngay bây giờ để làm việc đó đề nghị.Câu hỏi Swing/JTree/mô hình cây tùy chỉnh
Tôi có một JTree được xây dựng dựa trên TreeModel tùy chỉnh ("WRTreeModel", xem bên dưới). Cấu trúc dữ liệu mô hình này sẽ được sử dụng để xây dựng một đối tượng gốc chứa một số trường và hơn nữa danh sách được hỗ trợ bởi "ArrayListModel" được hiển thị bên dưới. Cây trông đẹp khi tôi xây dựng nó bằng WRTreeModel. Tôi có thể mở rộng và thu gọn các nút đại diện cho các danh sách và các trường chứa trong các đối tượng. Tôi có thể mở rộng và thu gọn các danh sách này cũng như xem nội dung của chúng và v.v.
Bây giờ tôi muốn xóa con của một trong các danh sách và - như tôi đã biết - hãy làm điều đó bằng cách xóa nó khỏi mô hình gọi phương thức remove của ArrayListModel. Để làm cho WRTreeModel nhận biết được điều đó, điều đầu tiên là gọi phương thức fireIntervalRemoved của nó được gọi, cho đến nay rất tốt.
Trong WRTreeModels lớp bên ArrayModelListener phương pháp intervalRemoved chuẩn bị tiếng gọi của fireTreeNodesRemoved mà sau đó xây dựng một TreeEvent được chuyển tiếp đến tất cả các đăng ký TreeModelListeners (và do đó JTree mà tự đăng kí automaticall khi nó được kết nối với mô hình).
Bây giờ tôi hy vọng rằng cây phản ánh thay đổi và cập nhật biểu diễn nội bộ và trực quan để hiển thị trạng thái mới. Thật không may điều này dường như không hoạt động theo cách đó. Có chuyện gì đó xảy ra. Nhưng khi tôi nhấp vào nút tôi vừa thay đổi một số EventHandler-Exceptions được ném. Rõ ràng là một cái gì đó đã thực sự bối rối.
Tôi biết việc trả lời câu hỏi như vậy không dễ dàng nhưng tôi thực sự đánh giá cao câu trả lời nhanh. Nó cũng sẽ giúp ích, nếu ai đó biết các trang web giải thích việc sử dụng các mô hình cây tùy chỉnh (không phải trên DefaultMutableTreeNode hoặc bất kỳ lớp dựa trên thực hiện nào) và cách xử lý sự kiện và cập nhật các tác phẩm JTree.
Với Trân,
Thomas Arts
public class ArrayListModel<E> extends ArrayList<E> implements ListModel {
...
public E remove(int index) {
fireIntervalRemoved(index, index);
E removedElement = super.remove(index);
return removedElement;
}
...
}
public class WRTreeModel extends LogAndMark implements TreeModel {
class ArrayModelListener implements ListDataListener {
...
@Override
public void intervalRemoved(ListDataEvent e) {
int[] indices = new int[e.getIndex1() - e.getIndex0() + 1];
for (int i = e.getIndex0(); i < e.getIndex1(); i++)
indices[i - e.getIndex0()] = i;
fireTreeNodesRemoved(e.getSource(), getPathToRoot(e.getSource()), indices, ((ArrayListModel<?>)e.getSource()).subList(e.getIndex0(), e.getIndex1()+1).toArray());
}
...
}
public Object[] getPathToRoot(Object child) {
ArrayList<Object> ret = new ArrayList<Object>();
if (child == null)
return ret.toArray();
ret.add(root);
if (child == root)
return ret.toArray();
int childType = 0;
if (child instanceof List<?> && ((List) child).get(0) instanceof Einleitungsstelle) {
childType = 1;
}
if (child instanceof Einleitungsstelle) {
childType = 2;
}
if (child instanceof List<?> && ((List) child).get(0) instanceof Messstelle) {
childType = 3;
}
if (child instanceof Messstelle) {
childType = 4;
}
if (child instanceof List<?> && ((List) child).get(0) instanceof Ueberwachungswert) {
childType = 5;
}
if (child instanceof Ueberwachungswert) {
childType = 6;
}
if (child instanceof List<?> && ((List) child).get(0) instanceof Selbstueberwachungswert) {
childType = 7;
}
if (child instanceof Selbstueberwachungswert) {
childType = 8;
}
switch (childType) {
// List of ESTs
case 1: {
ret.add(child);
break;
}
// EST
case 2: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
ret.add(child);
break;
}
// List of MSTs
case 3: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
if (child == einleitungsstelle.getListOfMST()) {
ret.add(einleitungsstelle);
break;
}
}
ret.add(child);
break;
}
// MST
case 4: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
if (child == einleitungsstelle.getListOfMST()) {
ret.add(einleitungsstelle.getListOfMST());
break;
}
}
ret.add(child);
break;
}
// List of UEWs
case 5: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST();
if (child == listOfMST) {
ret.add(listOfMST);
for (Messstelle messstelle : listOfMST) {
if (child == messstelle.getListOfUEW()) {
ret.add(messstelle.getListOfUEW());
break;
}
}
break;
}
}
break;
}
// UEW
case 6: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST();
if (child == listOfMST) {
ret.add(listOfMST);
for (Messstelle messstelle : listOfMST) {
if (child == messstelle.getListOfUEW()) {
ret.add(messstelle.getListOfUEW());
break;
}
}
break;
}
}
ret.add(child);
break;
}
// List of SUEWs
case 7: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST();
if (child == listOfMST) {
ret.add(listOfMST);
for (Messstelle messstelle : listOfMST) {
if (child == messstelle.getListOfSUEW()) {
ret.add(messstelle.getListOfSUEW());
break;
}
}
break;
}
}
break;
}
// SUEW
case 8: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST();
if (child == listOfMST) {
ret.add(listOfMST);
for (Messstelle messstelle : listOfMST) {
if (child == messstelle.getListOfSUEW()) {
ret.add(messstelle.getListOfSUEW());
break;
}
}
break;
}
}
ret.add(child);
break;
}
default:
ret = null;
}
return ret.toArray();
}
}
...
protected void fireTreeNodesRemoved(Object changed, Object path[], int childIndecies[], Object children[]) {
TreeModelEvent event = new TreeModelEvent(this, path, childIndecies, children);
synchronized (listeners) {
for (Enumeration e = listeners.elements(); e.hasMoreElements();) {
TreeModelListener tml = (TreeModelListener) e.nextElement();
tml.treeNodesRemoved(event);
}
}
}
...
}
Không biết nếu đó là trợ giúp thêm nhưng khi tôi cố gắng thu gọn và sau đó mở rộng nút cha của nút đã xóa, tôi nhận được ngoại lệ sau: Ngoại lệ trong chuỗi "AWT-EventQueue-0" java.lang. NullPointerException \t tại javax.swing.plaf.basic.BasicTreeUI.ensureRowsAreVisible (BasicTreeUI.java:1881) \t tại javax.swing.plaf.basic.BasicTreeUI.toggleExpandState (BasicTreeUI.java:2208) \t tại javax.swing. plaf.basic.BasicTreeUI.handleExpandControlClick (BasicTreeUI.java:2191) \t tại javax.swing.plaf.basic.BasicTreeUI.checkForClickInExpandControl (BasicTreeUI.java:2149) \t tại ... và cứ thế –
Tất cả các sự cố đều khẩn cấp theo định nghĩa :-) Tôi sẽ không đề cập đến "áp lực thời gian" trong một câu hỏi. Và câu hỏi của bạn có nghĩa là ở lại và giúp đỡ người khác khi bạn từ lâu quên nó. Làm cho nó kinh điển hơn. – raoulsson