Je dois créer plusieurs boutons et télécharger des fichiers. Donc, je veux créer une fonction pour définir ces boutons. Cependant, je reçois une erreur de compilation à l'intérieur de mon setNewButton
.Java - accès à une variable dans la classe interne ou attribution d'une valeur à la variable finale
Mon code se présente comme suit:
public class Solution extends JFrame {
private static final String FILE_NAME_1 = "my file1";
private File file1;
private void setNewButton(Container contentPane, final String fileName, String format, File file) {
contentPane.add(Box.createVerticalStrut(5));
final Label label = new Label("Select " + fileName + " in ." + format +" format");
contentPane.add(label);
contentPane.add(Box.createVerticalStrut(10));
Button selection = new Button("Select " + fileName);
contentPane.add(selection);
selection.addActionListener(new FileSelectionListener("Only " + format + " is allowed", format) {
@Override
protected void setSelection(File selectedFile) {
file = selectedFile; // compilation error here
label.setText("Selected" + fileName + selectedFile.getAbsolutePath());
}
});
}
public uploadFiles() {
Container contentPane = this.getContentPane();
setNewButton(contentPane, FILE_NAME_1, "xls", file1);
}
}
L'erreur est: Variable file is accessed from within inner class, needs to be declared final
J'ai vérifié quelques questions similaires à stackoverflow. Je sais file
doit être final comme label
et fileName
ici.
Cependant file
ici pourrait être final
puisque je voudrais lui assigner selectedFile
.
Je voudrais savoir s'il existe une solution de contournement pour ce problème.
Toute aide serait appréciée. :)
Grâce à @M. Prokhorov et @Chang Liu. Selon JLS 8.1.3. Inner Classes and Enclosing Instances
Toute variable locale, paramètre formel, ou exception paramètre utilisé, mais non déclarée dans une classe interne doit soit être déclarée finale ou effectivement finale, ou une erreur de compilation se produit lorsque l'utilisation est tentée .
Alors, quand j'ai essayé d'envoyer un paramètre file
intérieur FileSlectionListener
, il y aura une erreur de compilation. Cependant, le membre file1
à l'intérieur Solution n'est pas une variable locale, donc si je supprime le file
de ma méthode, il n'y aura pas d'erreur. Donc, la réponse de @talex est juste dans ce cas.
Cependant, comme mon problème est de trouver une méthode pour passer un File
à la classe interne et affecter la variable avec selectedFile
, je ne pouvais pas trouver un moyen pour cela. Ma solution de contournement est basée sur la réponse de @Chang Liu.
Mon code révisé est comme ci-dessous:
public class Solution extends JFrame {
private static final String FILE_NAME_1 = "my file1";
private File file1;
private void setNewButton(Container contentPane, final String fileName, String format) {
contentPane.add(Box.createVerticalStrut(5));
final Label label = new Label("Select " + fileName + " in ." + format +" format");
contentPane.add(label);
contentPane.add(Box.createVerticalStrut(10));
Button selection = new Button("Select " + fileName);
contentPane.add(selection);
selection.addActionListener(new FileSelectionListener("Only " + format + " is allowed", format) {
@Override
protected void setSelection(File selectedFile) {
setFile(selectedFile, fileName); // no compilation error here
label.setText("Selected" + fileName + selectedFile.getAbsolutePath());
}
});
}
public uploadFiles() {
Container contentPane = this.getContentPane();
setNewButton(contentPane, FILE_NAME_1, "xls", file1);
}
private void setFile(File file, String fileName) {
switch (fileName) {
case FILE_NAME_1:
sollFile = file;
break;
default:
throw new AssertionError("Unknown File");
}
}
}
encore, bienvenue pour me donner des conseils si vous avez une meilleure réponse. :)
Je cherche où 'selectedFile' est déclaré. Où est-ce? – markspace
@markspace C'est un paramètre de la méthode setSelection. – pacifier21
Voir [cette JLS] (http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3) à propos de votre erreur. Ce dont il s'agit essentiellement - java interdit fortement (via l'erreur de compilation) les classes internes anonymes (y compris lambdas) de "capturer" des variables qui pourraient être réaffectées pendant que l'instance de classe interne est active. –