2015-07-12 2 views
2

Я пытался получить графический интерфейс для приложения, над которым я работаю, и с тех пор он ничего не делал в Swing. Большая часть материала вернулась, но не это. Я не могу понять, почему, ни в одном из разных текстовых компонентов, если я что-то в них ввожу, getText() всегда будет возвращать «" независимо. Он вернется правильно, если я использую setText() в качестве теста, но это не очень полезно.Swing getText не будет читать ввод пользователя

Это остается согласованным по JTextArea/JTextField, различным способам ссылки на текстовое поле (прямая переменная vs потянув из HashMap) и независимо от того, какой поток выполняет доступ. Время от времени я использовал отладчик, чтобы попробовать и посмотреть на вещи, поскольку они происходят через другие тестовые фрагменты, и все равно ничего. Начиная с редактирования, вырезали многие из этих случаев, но все еще упорствует в этой проблеме.

Во всех случаях вход пользователя никогда не приобретается.

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 

public class LifePathUI2 { 

    final static boolean shouldWeightX = true; 
    private GridBagConstraints cons; 
    private BorderLayout windowLayout; 
    private GridBagLayout layout; 
    private JFrame mainWindow; 
    private JPanel mainPanel; 


    private JComponent currentComponent; 
    private JTextField characterName; 

    /** 
    * @throws HeadlessException 
    */ 
    public LifePathUI2() throws HeadlessException { 
     cons = new GridBagConstraints(); 
     windowLayout = new BorderLayout(); 
     layout = new GridBagLayout(); 
     mainWindow = new JFrame();  
     mainPanel = new JPanel(); 

     mainWindow.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     init(); 
    } 


    public void init() 
    { 
     mainWindow.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); 

     mainWindow.setLayout(windowLayout); 


     cons.ipadx = 5; 
     cons.ipady = 5; 
     cons.anchor = GridBagConstraints.NORTHWEST; 
     cons.fill = GridBagConstraints.NONE; 
     cons.weighty = 1.0; 
     cons.weightx = 1.0; 

     // to make everything work right we add a mainPanel under the mainWindow 
     cons.gridheight = 1; 
     cons.gridwidth = 1; 

     mainWindow.add(mainPanel); 
     // Readers keep in mind if you don't set this below, strange behavior happens 
     mainPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); 
     mainPanel.setLayout(layout); 

     currentComponent = mainPanel; 

     addLabel(0,0,"Character Name"); 
     characterName = addTextF(1,0,"",30,true); 
     endRow(2,0); 

     addButton(0,1,"Foo").addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent e) 
      { 
       System.out.println(characterName.getText()); 
      } 
     }); 

     endVertical(0,2); 

     mainWindow.setSize(1400, 900); 

     mainWindow.setVisible(true); 
    } 

    /** 
    * Inserts a spacer to signify the end of components for this row (effects layout so it doesn't center) 
    */ 
    private void endRow(int x, int y) 
    { 
     cons.weightx = 100.0; 
     addLabel(x,y,""); 
     cons.weightx = 1.0; 
    } 

    /** 
    * Inserts a spacer to signify the end of components vertically (effects layout so it doesn't center) 
    */ 
    private void endVertical(int x, int y) 
    { 
     cons.weighty = 100.0; 
     addLabel(x,y,""); 
     cons.weighty = 1.0; 
    } 

    /** 
    * Shorthand command to add label at coordinates with text 
    * @param x non-negative integer 
    * @param y non-negative integer 
    * @param text Display Text for label 
    */ 
    private JLabel addLabel(int x, int y, String text) 
    { 
     JLabel temp = new JLabel(text); 
     addC(temp,x,y); 
     return temp; 
    } 

    /** 
    * Shorthand command to add Button at coordinates with text 
    * @param x non-negative integer 
    * @param y non-negative integer 
    * @param text Display Text for Button 
    * @return The component created 
    */ 
    private JButton addButton(int x, int y, String text) 
    { 
     JButton temp = new JButton(text); 
     addC(temp,x,y); 
     return temp; 
    } 

    /** 
    * Shorthand command to add Text Field at coordinates with text 
    * @param x non-negative integer 
    * @param y non-negative integer 
    * @param value the default value for the text field 
    * @param cols Number of Columns 
    * @param updateListen If true will add listener that triggers UI updates when values change 
    * @return The component created 
    */ 
    private JTextField addTextF(int x, int y, String value, int cols, boolean updateListen) 
    { 
     JTextField temp = new JTextField(value, cols); 

     // this prevents the common issue of the text fields turning into slits 
     temp.setMinimumSize(temp.getPreferredSize()); 

     addC(temp,x,y); 
     return temp; 
    } 

    /** 
    * Shorthand to add new components to the UI tab at given coords 
    * @param comp Component to add to UI 
    * @param x non-negative integer 
    * @param y non-negative integer 
    * 
    */ 
    private void addC(JComponent comp, int x, int y) { 
     cons.gridx = x; 
     cons.gridy = y; 
     currentComponent.add(comp,cons); 
    } 


    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 

     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       LifePathUI2 ui = new LifePathUI2(); 
       ui.init(); 
      } 
     }); 

    } 

} 

Я искал каждый вопрос здесь для качания, и ни одна из них, похоже, не соответствует этой проблеме. Не ожидал этого.

Приносим извинения за большой фрагмент, но поскольку все части сразу создают текстовые поля, читая их, создавая сам графический интерфейс, все, кажется, соответствуют примерам, которые я видел в Интернете ... Я просто умный достаточно знать, что должно быть что-то странное, что я сделал здесь, и просто не вижу его.

EDIT: Упрощенный пример. Несмотря на то, что он разбился на гораздо более простой тестовый вариант, все еще нет кубиков EDIT2: Готовое сжатие вещей. Я действительно ожидал, что это сработает, потому что это уже на уровне рабочего кода, который я написал ранее. Но до сих пор ничего

+2

'Я не могу понять, почему, через ни один из различных текстовых компонентов, если я типа что-то в них, GetText() всегда будет возвращать «" - это, вероятно, потому, что вы создали два компонента, а ваш код ссылается на компонент, который НЕ отображается в кадре, поэтому вы получаете нуль. Начните с создания простого кадра с текстовым полем и кнопкой. Когда вы нажимаете кнопку, вы выводите текст. Докажите себе, что работает простой случай. Затем определите, почему у вас есть два компонента. Вы отправили слишком много кода для меня, чтобы посмотреть. – camickr

+0

Попробуйте temp.setText (getTextF (имя)); вам нужно будет убедиться, что вы передаете строку .. –

+1

В вашем коде слишком много цикломатической сложности, и именно это затрудняет вам отладку кода и для того, чтобы вы могли публиковать ** небольшой ** проверяемая управляемая программа. Вы должны реорганизовать свой код, чтобы упростить его, чтобы у вас были более мелкие классы, которые можно тестировать изолированно (с соответствующим издевательством), так как это поможет как вам, так и нам сейчас и в будущем. –

ответ

5

Грубое предположение, но ваш метод update() выглядит он может пытается извлечь текст из документа, что его слушать (не сказать), и если да, то использовать DocumentEvent чтобы получить документ, а затем извлечь текст. Что-то вроде:

private class TextChangeListener implements DocumentListener { 
    @Override 
    public void changedUpdate(DocumentEvent e) { 
    update(e); 
    } 

    @Override 
    public void insertUpdate(DocumentEvent e) { 
    update(e); 
    } 

    @Override 
    public void removeUpdate(DocumentEvent e) { 
    update(e); 
    } 
} 

и

private void update(DocumentEvent e) { 
    String text; 
    try { 
    Document doc = e.getDocument(); 
    text = e.getDocument().getText(0, doc.getLength()); 
    // do something with text here! ************ 
    System.out.println(text); 
    } catch (BadLocationException e1) { 
    e1.printStackTrace(); 
    } 
} 

Кроме того, я потерял в вашем коде. Упрощать. Рефакторинг. Упростите еще немного. Рефакторинг еще. Подумайте о небольших классах, которые могут быть полностью протестированы изолированно.


Редактировать

Вы называете init()ДВАЖДЫ, и это проблема, так как это означает, что вы создаете два всего, один на экране и не.

Вы сначала вызываем его здесь:

public LifePathUI2() throws HeadlessException { 
    // .... 
    init(); 
} 

, а затем вызвать его снова в ваш главный:

javax.swing.SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     LifePathUI2 ui = new LifePathUI2(); 
     ui.init(); 
    } 
    }); 

Зов это только раз.

Изменить это:

public LifePathUI2() throws HeadlessException { 
    cons = new GridBagConstraints(); 
    windowLayout = new BorderLayout(); 
    layout = new GridBagLayout(); 
    mainWindow = new JFrame(); 
    mainPanel = new JPanel(); 
    mainWindow.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
    init(); 
} 

к этому:

public LifePathUI2() throws HeadlessException { 
    cons = new GridBagConstraints(); 
    windowLayout = new BorderLayout(); 
    layout = new GridBagLayout(); 
    mainWindow = new JFrame(); 
    mainPanel = new JPanel(); 
    mainWindow.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
    // init(); 
} 
+0

Вот оно! Благодарю. Я знал, что покрыл большинство непредвиденных обстоятельств из комментариев, основанных на ответах других людей, но что-то вроде этого - это то, о чем я всегда пропустил ... – Vigilant

+0

@ Vigilant: еще раз спасибо за упрощение, так как это очень помогло **. –

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