Domanda

Sto impostando una GUI in cui devo prendere le informazioni immesse dagli elementi del modulo e manipolarle. Ciò richiede che io usi alcuni elementi per accedere ad altri.

Ad esempio, ho una casella di input ( JTextField ) e un pulsante ( JButton ) accanto ad essa. Quando il pulsante viene premuto, devo essere in grado di manipolare il testo inserito nella casella di input. Tutto ciò che ho cercato di fare finora per farlo è fallito.

Ecco come appare il mio codice in questo momento (ho incorporato le mie domande nei commenti):

public class MyClass
{
    public static void main(String args[])
    {
        // Form elements are in here
        JTextField myTextField = new JTextField(10);
        JButton myTextFieldSubmit = new JButton("Submit");
        myTextFieldSubmit.addActionListener(new ListenerClass());
    }
}

class ListenerClass implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        // This is what happens when these elements are used
        // I need to be able to access the form elements from MyClass in here, but this doesn't seem possible with my current setup
        // For example, when the Submit button is pressed, I need to be able to myTextField.getText() and edit MyClass members
        // How should my setup be changed to accommodate these needs?
    }
}

Grazie per l'aiuto!

È stato utile?

Soluzione

Questo è molto un problema di portata variabile.

Attualmente, il campo di testo e il pulsante rientrano nell'ambito del metodo main , quindi avere una classe separata per ActionListener significa che non avrà accesso a quelle variabili.

Ci sono alcuni modi per raggiungere questo obiettivo:

(1) Crea una classe interna ListenerClass in MyClass e trasforma myTextField e myTextFieldSubmit in istanza campi di MyClass .

public class MyClass
{
  final static JTextField myTextField = new JTextField(10);
  final static JButton myTextFieldSubmit = new JButton("Submit");

  public static void main(String args[])
  {
    myTextFieldSubmit.addActionListener(new ListenerClass());
  }

  static class ListenerClass implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {
      myTextField.setText("");
    }
  }
}

(2) Crea una classe interna anonima nel metodo main e ciò consentirà a myTextField e myTextFieldSubmit di rimanere nello stesso posto , purché siano dichiarati final .

public class MyClass
{
  public static void main(String args[])
  {
    final JTextField myTextField = new JTextField(10);
    final JButton myTextFieldSubmit = new JButton("Submit");

    myTextFieldSubmit.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {
            myTextField.setText("");
        }
    });
  }
}

(3) Crea una classe locale locale al metodo main . Ancora una volta, ciò richiederà che il campo di testo e il pulsante siano dichiarati final per consentire l'accesso dalla classe interna.

public class MyClass
{
  public static void main(String args[])
  {
    final JTextField myTextField = new JTextField(10);
    final JButton myTextFieldSubmit = new JButton("Submit");

    class ListenerClass implements ActionListener
    {
      public void actionPerformed(ActionEvent e)
      {
        myTextField.setText("");
      }
    }

    myTextFieldSubmit.addActionListener(new ListenerClass());
  }
}

(4) Consegna di un riferimento a ListenerClass , ad esempio nel costruttore, e anche myTextField e myTextFieldSubmit una variabile di istanza.

public class MyClass
{
  JTextField myTextField = new JTextField(10);
  JButton myTextFieldSubmit = new JButton("Submit");

  public MyClass()
  {
    myTextFieldSubmit.addActionListener(new ListenerClass(this));
  }

  public static void main(String args[])
  {
    new MyClass();
  }
}

class ListenerClass implements ActionListener
{
  MyClass myClass;

  public ListenerClass(MyClass myClass)
  {
    this.myClass = myClass;
  }

  public void actionPerformed(ActionEvent e)
  {
    myClass.myTextField.setText("");
  }
}

(5) Rendi myTextField e myTextFieldSubmit nei campi statici e consenti l'accesso diretto dal ListerClass .

public class MyClass
{
  static JTextField myTextField = new JTextField(10);
  static JButton myTextFieldSubmit = new JButton("Submit");

  public static void main(String args[])
  {
    myTextFieldSubmit.addActionListener(new ListenerClass());
  }
}

class ListenerClass implements ActionListener
{
  public void actionPerformed(ActionEvent e)
  {
    MyClass.myTextField.setText("");
  }
}

Probabilmente ci sono ancora altri modi per raggiungere questo obiettivo e potrebbero esserci modi migliori per implementarlo. La scelta dell'approccio che segui dipende davvero dal design desiderato dell'applicazione.

Altri suggerimenti

Puoi passare un riferimento a MyClass nel costruttore a ListenerClass .

Il tuo problema è comune all'uso degli ascoltatori per qualsiasi scopo in Java: come consentire al gestore di accedere all'oggetto che ha notificato gli ascoltatori o i suoi colleghi.

Esistono generalmente due convenzioni.

Uno è quello di ottenere l'oggetto direttamente dall'oggetto evento. Puoi farlo con getSource (). Ma poi otterrai solo il widget che lo ha fatto.

Un'altra opzione è quella di consentire alla classe listener di accedere ai widget. Un modo è usare una classe interna non statica (dipende da come la dichiari), nel qual caso è permesso accedere ai membri della classe contenente.

Tuttavia, in questo caso i tuoi widget sono variabili, non membri (sei sicuro di volerlo fare?). Quindi la tua unica soluzione sarebbe quella di avere membri che li trattengono nella classe Listner e quindi invece di creare il listener nella chiamata addListener, creare un listener, passare i widget pertinenti e aggiungere il listener. L'ascoltatore ora può accedere a quei widget attraverso i propri riferimenti a loro che sono memorizzati nei membri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top