2017-01-25 5 views
0

У меня есть JFrame с JTree на нем (созданный в функции «get_Classification()»). Эта функция должна возвращать имя выбранного узла (щелкнув двойным) как String.Как подождать ввода выбора

Как только я запустил приложение, метод возвращает значение null, если я затем дважды щелкните узел, значение будет напечатано на консоль, как ожидалось.

Я предполагаю, что метод закончен, прежде чем пользователь сможет выбрать значение (на самом деле 3-4 уровня, занимая около 5 секунд). Если у меня был «Thread.sleep (1000)», JTree не показывается до тех пор, пока второй не пройдет ...

Как подождать ввода пользователя до того, как метод вернет значение, а также увидит дерево заранее?

Некоторые функции ниже:

public String ret = null; 
private DefaultTreeModel model = new DefaultTreeModel(top); 
private JTree baum = null; 

MouseListener ml = new MouseAdapter() { 
    public void mousePressed(MouseEvent e) { 
     TreePath selPath = baum.getPathForLocation(e.getX(), e.getY()); 
     if (selPath != null) { 
      DefaultMutableTreeNode node = (DefaultMutableTreeNode) selPath.getLastPathComponent(); 
      if (e.getClickCount() == 2 && model.isLeaf(node)) { 
       ret = node.toString(); 
       System.out.println(ret); 
      } 
     } 
    } 
}; 

public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       Frame window = new Frame(); 
       window.frame.setVisible(true); 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

public Frame() { 
    initialize(); 
} 


private void initialize() { 
    frame = new JFrame(); 
    frame.setBounds(100, 100, 500, 500); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


    Map<String, String> tree = new HashMap<String, String>(); 
    tree.put("Klebebänder", "Hilfsstoffe und Beschichtungsstoffe"); 
    tree.put("Lacke", "Hilfsstoffe und Beschichtungsstoffe"); 
    tree.put("Pulver", "Hilfsstoffe und Beschichtungsstoffe"); 

    String k = get_Klassifizierung(tree); 
    System.out.println(k); 

} 

private String get_Klassifizierung(Map<String, String> tree) { 
    setupTree(tree); // creates the tree 
    waitForInput(); 

    return ret; 

} 

private void waitForInput() { 
    try { 
     Thread.sleep(10000); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

Спасибо за вашу помощь

+0

Подробнее о [деревьях в Swing] (https://docs.oracle.com/javase/tutorial/uiswing/components/tree.html) –

+0

Дерево и выбор работают, проблема в том, что функция закончена раньше, чем пользователь может отреагируйте .. – IVIike

+1

Вам нужно провести некоторое исследование «шаблона наблюдателя», в частности «TreeSelectionListener». Я предлагаю вам взглянуть на [Как использовать деревья] (http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html), эта концепция является фундаментальной для Swing (и большинства графических интерфейсов) – MadProgrammer

ответ

0

На вопрос лидера развития в моей компании, и он имел кодирование в течение 2-х минут ...

Вот решение:

Файл "Main.java":

public class Main { 

public static void main(String[] args) throws InterruptedException { 

    Map<String, String> tree = new HashMap<String, String>(); 
    tree.put("Klebebänder", "Hilfsstoffe und Beschichtungsstoffe"); 
    tree.put("Lacke", "Hilfsstoffe und Beschichtungsstoffe"); 
    tree.put("Pulver", "Hilfsstoffe und Beschichtungsstoffe"); 

    String k = get_Klassifizierung(tree); 

    System.out.println(k); 

    } 

public static String get_Klassifizierung(Map<String, String> tree) throws InterruptedException { 
    MyFrame m = new MyFrame(tree); 
    while (m.myReturnValue == null) { 
     Thread.sleep(1000); 
    } 

    m.dispose(); 
    return m.myReturnValue; 
    } 

} 

файла "MyFrame.java":

public class MyFrame extends JFrame implements MouseListener { 
private static final long serialVersionUID = 1L; 
String myReturnValue = null; 

private static String firstn = "Kategorien"; 
private static String del = "\\|"; 
private DefaultMutableTreeNode top = new DefaultMutableTreeNode(firstn); 
private DefaultTreeModel model = new DefaultTreeModel(top); 
private JTree baum = null; 
public String ret = null; 

public MyFrame(Map<String, String> tree) { 

    this.setBounds(100, 100, 500, 500); 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    setupTree(tree); 

    baum.addMouseListener(this); 
    this.setVisible(true); 
} 

private void setupTree(Map<String, String> tree) { 
    baum = new JTree(createNodes(tree)); 
    baum.setEditable(false); 
    baum.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 
    baum.setToggleClickCount(2); 
    baum.setRootVisible(true); 
    JScrollPane treeView = new JScrollPane(baum); 
    this.getContentPane().add(treeView); 
    this.setVisible(true); 
} 
private DefaultMutableTreeNode createNodes(Map<String, String> file) { 
    /* 
    * Iterate over the Map 
    */ 
    for (Map.Entry<String, String> entry : file.entrySet()) { 
     String key = entry.getKey(); 
     String values[] = entry.getValue().split(del); 

     DefaultMutableTreeNode parent = top; 

     /* 
     * Iterate over the values (Path) 
     */ 
     for (String k : values) { 
      DefaultMutableTreeNode n = null; 

      /* 
      * Check if Node already exists 
      */ 
      Enumeration<?> e = parent.children(); 
      while (e.hasMoreElements()) { 
       n = (DefaultMutableTreeNode) e.nextElement(); 
       if (k.equals(n.getUserObject())) { 
        // Existing node matches; use that one. 
        break; 
       } 
       n = null; 
      } 
      if (n == null) { 
       // No existing node matches; add it. 
       n = new DefaultMutableTreeNode(k); 
       parent.add(n); 
      } 
      parent = n; 
     } 
     parent.add(new DefaultMutableTreeNode(key)); 
    } 
    return top; 
} 
// ... other @Overrides 
@Override 
    public void mousePressed(MouseEvent e) { 
    TreePath selPath = baum.getPathForLocation(e.getX(), e.getY()); 
    if (selPath != null) { 
     DefaultMutableTreeNode node = (DefaultMutableTreeNode) selPath.getLastPathComponent(); 
     if (e.getClickCount() == 2 && model.isLeaf(node)) { 
      this.myReturnValue = node.toString(); 
     } 
    } 

} 

Спасибо за вашу помощь

0

Ваш рабочий процесс что-то вроде: Поднимают UI -> вызвать метод -> Когда метод возвращает сделать что-то

В приложениях с графическим интерфейсом рабочий процесс должен быть другим: Приобретите UI -> приложить прослушиватель, чтобы получить обратный вызов, когда пользователь что-то делает -> сделайте что-нибудь, когда вы получите обратный вызов

Если вам по-прежнему необходимо следовать предыдущему пути, вам нужно будет добавить какой-то флаг, флаг будет установлен, когда пользовательский интерфейс получил обратный вызов, ожидание ввода будет спящим в течение небольшого времени и проверьте, установлен ли флаг установить в цикле. Однако этот подход плохой, потому что вы будете получать доступ к пользовательскому интерфейсу из другого потока.

+0

Я пробовал его с логическим значением, чтобы получить значение true, если узел двойной щелкнули, но, с одной стороны, GUI не показывал (потому что при запуске логическое значение не является истинным), а с другой - запускается программа, но не показывает дерева ... – IVIike

Смежные вопросы