Hallo,
ich brauche wieder Eure Hilfe
Im Rahmen eines Projektes muss ich einen Baumstruktur realisieren. Dies geht ganz gut mit TreeView.
Das Problem: ich möchte das TreeView als ein Dropdown-Fenster darstellen.
Das Dropdown soll sich öffnen, wenn man auf einem Jcombobox klickt. Es muss nicht unbedingt ein JComboBox Objekt mit einem TreeView eerweiteret werden. Es muss nur ein TextFeld und daneben ein "Pfeil nach unten" sichtbar sein. Wenn der Pfeil angeklickt wird, soll sich das Dropdown mit dem TreeView erscheinen.
Ich konnte bisher das TreeView nur in einem eigenem JFrame anzeigen. Wenn ich es zum Jcombobox (mitttels setEditor(); siehe Code) hinzufüge, dann erscheint es im TextFeld-Bereich, und nicht als dropdown.
Das Code kann man mit main() starten: TreeView erscheint im JFrame.
Ich möchte, dass durch createCBox() ein Jcombobox (oder ein ähnliches Objekt mit dropdown Menü) erstellt wird.
(Das Tree schaut aus, wie in Anhang.)
Kann mir jemand weiterhelfen?
Vielen Dank,
Daniel
ich brauche wieder Eure Hilfe
Das Problem: ich möchte das TreeView als ein Dropdown-Fenster darstellen.
Das Dropdown soll sich öffnen, wenn man auf einem Jcombobox klickt. Es muss nicht unbedingt ein JComboBox Objekt mit einem TreeView eerweiteret werden. Es muss nur ein TextFeld und daneben ein "Pfeil nach unten" sichtbar sein. Wenn der Pfeil angeklickt wird, soll sich das Dropdown mit dem TreeView erscheinen.
Ich konnte bisher das TreeView nur in einem eigenem JFrame anzeigen. Wenn ich es zum Jcombobox (mitttels setEditor(); siehe Code) hinzufüge, dann erscheint es im TextFeld-Bereich, und nicht als dropdown.
Das Code kann man mit main() starten: TreeView erscheint im JFrame.
Ich möchte, dass durch createCBox() ein Jcombobox (oder ein ähnliches Objekt mit dropdown Menü) erstellt wird.
(Das Tree schaut aus, wie in Anhang.)
Kann mir jemand weiterhelfen?
Vielen Dank,
Daniel
Java:
import java.awt.Component;
import java.util.Vector;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.CheckBoxTreeItem;
import javafx.scene.control.CheckBoxTreeItem.TreeModificationEvent;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.CheckBoxTreeCell;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
public class MyTreeView extends BasicComboBoxEditor {
private Vector<String[]> nodelist;
private boolean initted = false;
/*
* Gibt ein JComboBox mit einem custom dropdown zurück???
*/
public JComboBox<String> createCBox() {
JComboBox<String> kst = new JComboBox<String>();
kst.setEditable(true);
kst.setEditor( new MyTreeView( getTestData() ) );
return kst;
}
//Create custom dropdown for JComboBox: http://www.codejava.net/java-se/swing/create-custom-gui-for-jcombobox
//Interface - BasicComboBoxEditor - BEGIN
public Component getEditorComponent() {
final JFrame frame = new JFrame("Data");
final JFXPanel fxPanel = new JFXPanel();
frame.setSize(250, 350);
Platform.runLater(new Runnable() {
@Override
public void run() {
initFX(fxPanel, frame);
initted = true;
}
});
while(initted == false) {
System.out.format("Waiting for init...\n");
}
return fxPanel;
}
public Object getItem() {
System.out.println("\ngetItem() called...");
return (String)"[SELECTED ITEM]";
}
public void setItem(Object item) {
System.out.println("\nsetItem() called: " + item);
}
//Interface - BasicComboBoxEditor - END
public MyTreeView(Vector<String[]> nodes) {
nodelist = nodes;
}
public void initAndShowGUI() {
// This method should be invoked on the Swing-Event-Dispatch thread
final JFrame frame = new JFrame("MyTreeView");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setSize(250, 350);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Platform.runLater(new Runnable() {
@Override
public void run() {
initFX(fxPanel, frame);
}
});
}
protected void initFX(JFXPanel fxPanel, JFrame container) {
// This method is invoked on the JavaFX thread
Scene scene = createScene(container.getWidth(), container.getHeight());
fxPanel.setScene(scene);
}
/**
* Füllt den Baum root mit Knoten spezifiziert in den Parameter nodeStruct auf. Wenn ein Knoten
* im Baum bereits enthalten ist, wird dieser nicht überschrieben!
* @param root Ist der Wurzelknoten vom Baum.
* @param level Muss immer -1 sein!
* @param nodeStruct Muss diesen Format haben: Node1/ oder Node1/Node2 oder Node1/Node2/Node3 ...
* @param leafName Die Name vom Blattknoten. ZB wenn nodeStruct=Node1/Node2, dann wird der Knoten Node2
* die Name leafName haben, alle anderen die Name null.
*/
protected void populateTree(MyCheckBoxTreeItem<String> root, int level, String nodeStruct, String leafName) {
String parts[] = nodeStruct.split("/");
//System.out.println("\nparts.length: " + parts.length);
if(level == -1) {level = 0;}
boolean found=false;
TreeItem<String> newRoot = null;
for(TreeItem<String> elem: root.getChildren()) {
//System.out.format("\n[%s]'s direkt children: %s\n\n", root.getValue(), elem.getValue());
if(elem.getValue().equals(parts[level])) {
found = true;
newRoot = elem;
}
}
if(found) {
root = (MyCheckBoxTreeItem<String>) newRoot;
if(level == parts.length - 1) {
// do nothing
} else {
level++;
populateTree(root, level, nodeStruct, leafName);
}
} else {
MyCheckBoxTreeItem<String> node;
if(level == parts.length - 1) {
node = new MyCheckBoxTreeItem<String>(parts[level], leafName);
root.getChildren().add(node);
} else {
node = new MyCheckBoxTreeItem<String>(parts[level], null);
root.getChildren().add(node);
root = node;
level++;
populateTree(root, level, nodeStruct, leafName);
}
}
}
protected Scene createScene(int width, int height) {
MyCheckBoxTreeItem<String> rootItem = new MyCheckBoxTreeItem<String>("Root", null);
rootItem.setExpanded(false); //expands the root node
final TreeView tree = new TreeView(rootItem);
tree.setEditable(false); //+++ true
tree.setRoot(rootItem);
tree.setShowRoot(true);
//populate the tree
tree.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
for(String node[]: nodelist) {
populateTree(rootItem, -1, node[0], node[1]);
}
/*MyCheckBoxTreeItem<String> l2 = new MyCheckBoxTreeItem<String>("FIRST", "FIRST/2500/2500");
rootItem.getChildren().add(l2);*/
//[URL]https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/CheckBoxTreeItem.html#checkBoxSelectionChangedEvent--[/URL]
//Für jedes Element im Baum wird dieses Event generieret, wenn das Root-Element aus/abgewählt wird.
rootItem.addEventHandler(CheckBoxTreeItem.<String>checkBoxSelectionChangedEvent(), new EventHandler<TreeModificationEvent<String>>() {
public void handle(TreeModificationEvent<String> event) {
if(event.isConsumed()) {
return;
}
MyCheckBoxTreeItem<String> cbi = (MyCheckBoxTreeItem<String>) event.getTreeItem();
event.consume();
System.out.println("Node: " + cbi.getName());
}
});
StackPane root = new StackPane();
root.getChildren().add(tree);
Scene scene = new Scene(root, width, height);
return (scene);
}
/*
* Zum testen ...
*/
public static Vector<String[]> getTestData() {
Vector<String[]> data = new Vector<String[]>();
String tdat[][] = new String[][] {
{"FIRST/2500/2500", "FIRST/2500/2500"},
{"SECOND/2800/2800", "SECOND/2800/2800"}
};
for(String node[]: tdat) {
data.add(node);
}
return data;
}
/*
* Zum testen...
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MyTreeView mtree = new MyTreeView( getTestData() );
mtree.initAndShowGUI();
}
});
}
}
/**
* In dieser Klasse wird zusätzlich eine Name zu den jeweiligen CheckBoxTreeItem gespeichert.
*/
class MyCheckBoxTreeItem<T> extends CheckBoxTreeItem<T> {
String name;
public MyCheckBoxTreeItem(T arg0, String name) {
super(arg0);
this.name = name;
}
public String getName() {
return this.name;
}
}
Anhänge
Zuletzt bearbeitet von einem Moderator: