Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
ich habe eine Hauptklasse und eine innere Klasse. In der Hauptklasse wird ein Objekt der inneren Klasse erzeugt und die macht ja irgendetwas. Jetzt kommt das Problem: Wenn ein Knopf gedrückt wird(das wird in der inneren Klasse überprüft), dann soll sich das Objekt selbst löschen.Hierbei geht es um einen Applet.
Wie kann man es realisieren, dass ein Objekt sich selbst löschet?
Ein Objekt, dass sich selbst löscht??? - das klingt sehr nach einem Destruktor, den es vielleicht bei C++ gibt, der jedoch bei Java überflüssig ist, da es hier den Carbage Collector gibt!
und ich würde System.crashthewholemotherfuckingvm() benutzen?
zum Thema: grundsätzlich kann ich mir in den seltensten Fällen eine zwingende Verwendung eines Destruktors vorstellen in java... bei bestimmten Ressourcen kann das Sinn machen... und mit der ursprünglichen Frage von wegen innere und äußere klasse kann ich erst recht nix anfangen - das Problem sollte nochmal genauer evtl. mit Code beschrieben werden. Sonst wird das hier nix
Hm, ich weiß jetzt nicht, ob mein Vorschlag in der konkreten Implementierung einen Sinn ergibt, aber was mir dazu einfällt, trägt den Namen WeakHashtable.
Ich werde am Besten doch ein Teil des Codes mitschicken, damit nicht alle hier raten müssen. Das ist also mein Problem:
Code:
public class Test extends Applet
{
HauptPanel p= new HauptPanel(this);
public void init()
{
add(p);
setBackground(p.bgCo);
}
}
Dann:
Code:
class HauptPanel extends Panel
{
Color bgCo = new Color(158,158,158);
Button buttonL = new Button("Los");
TextField t = new TextField(8);
Panel panel [] = new Panel[12];
String items [] = {"NOP", "ADD", "LOAD"};
Choice choices [] = new Choice [11];
Choice c1 [] = new Choice [11];
Choice c2 [] = new Choice [11];
Choice cerg [] = new Choice [11];
Label labels [] = new Label[11];
Label gleich [] = new Label[11];
Label plus [] = new Label[11];
String g = "=";
String p = "+";
Test te = new Test();
HauptPanel(Test p)
{
setLayout(new GridLayout(0,1));
setBackground(bgCo);
panelsEinfuegen();
labelsEinfuegen();
choicesEinfuegen();
panel[11].add(buttonL);
panel[11].add(t);
rufItem();
undAction();
// Hier kommen die Methoden.............
}
public void undAction()
{
buttonL.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
drueck(e);
}
});
}
public void drueck(ActionEvent action)
{
String command=action.getActionCommand();
if(command.equals("Los"))
{
te.p.remove(this); //// Hier ist das Problem! Diese Zeile sollte das Objekt löschen!
validate();
}
}
}
Wie oben beschrieben, soll die Zeile
Code:
te.p.remove(this);
das Objekt "p" löschen, aber sicherlich habe ich einen Fehler gemacht, denn es wird nicht gelöscht. Hat jemand eine Idee, wie ich es realisieren kann?
Vielen Dank
Ja, das habe ich auch gemacht, aber es klappt halt nicht. Ich weiss nicht woran es liegen kann. Wahrscheinlich, weil das Objekt sich selbst nicht unsichtbar machen kann!?!?
Wenn Du Elmente aus der "GUI" entfernst und neue einfügst, mußt noch speziell mitteilen, das sisch was geändert hat. Ich hab das immer mit pack(); gemacht, Hab hier im Forum aber dazu immer das validate(); gehört. also einfach mal ausprobieren.
Ich habe vorher diese ganzen Sachen in einer Klasse gehabt und es hat dann alles geklappt. Jetzt habe ich übersichtshalber alles in mehreren Klassen aufgeteilt und seit dem gibt es nämlich das Problem.
Leider klappt es so einfach nicht. Mit dem Befehl
Code:
remove(p);
validate();
kommt folgende Fehlermeldung
Code:
D:\.......\Test.java:274: cannot find symbol
symbol : method remove(java.lang.String)
location: class HauptPanel
remove(p);
Naja, ist ja auch kein Wunder, weil das Objekt sich in der anderen Klasse befindet.
Mach ich es so:
Code:
Test te = new Test();
.
.
.
.
.
remove(te.p);
Kommt folgende Fehlermeldung:
Code:
java.lang.StackOverflowError
.
.
.
.
.
Also es kommt überhaupt nicht zu dem Aufruf von validate oder repiant....
Ich verstehe nicht, warum das eine Objekte auf das andere Objekt nicht zugreifen kann.
Also ohne den neuen Quelltext wird das schwierig.
*orakel* am betsen hat die Klasse in der das Objekt entfernt werden soll, eine funktion removeMeinObject(). Die kann dann von einer anderen Klasse aus ausgerufen werden. Wenn die Klasse in der was enteferntwerden soll, selber merkt das was entfernt werden soll brauchst Du die Funktion nicht. */orkale*
Für den Zugriff innerhalb von Klassen suche mal public protected und private. Da wird das dann schön erklärt.
public class Test extends Applet
{
HauptPanel p= new HauptPanel(this);
public void init()
{
add(p); // <--- hier
...
Dann musst du eine Referenz in die andere Richtung machen:
Code:
class HauptPanel extends Panel
{
// Es gibt nur ein Applet, ein "new Test()" wird immer falsch sein, es
// generiert eine neue Instanz, welche mit anderen Applets nichts zu tun hat.
// Test te = new Test();
Test te
HauptPanel(Test p)
{
...
// Die Referenz auf das richtige Applet speichern
te = p;
...
public void drueck(ActionEvent action)
{
// Jetzt stimmt schonmal die Referenz zum Test. Da das HauptPanel
// dem Applet hinzugefügt wurde, muss es auch vom Applet entfernt
// werden. Ein "te.p.remove( this )" bedeutet: dass HauptPanel von sich
// selbst entfernen. So sinnvoll wie "Der Mann mit dem Hut stieg aus sich selbst aus"
// anstelle von "Der Mann mit dem Hut stieg aus dem Auto aus".
te.remove( this );
validate();
}
....
:cry: :cry:
Also, ich habe es jetzt so gemacht, wie Benny es gesagt hatte :cry: :cry: :cry: . Es klappt leider immer noch nicht.
Es kommt folgende Fehlermeldung:
Code:
java.lang.StackOverflowError
.
.
.
.
.
.
at HauptPanel.<init>(Test.java:33)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
at HauptPanel.<init>(Test.java:45)
at Test.<init>(Test.java:13)
Ich teile Euch mal mit, was in den Zeilen 13 und 45 stehen:
Code:
13: HauptPanel p= new HauptPanel(this);
45: Test te = new Test();
Der Code ist schon bischen lang, aber ich schicke mal den neuen Code mit.
Code:
public class Test extends Applet
{
HauptPanel p= new HauptPanel(this);
public void init()
{
add(p);
setBackground(p.bgCo);
}
}
class HauptPanel extends Panel
{
Color bgCo = new Color(158,158,158);
Button buttonL = new Button("Los");
TextField t = new TextField(8);
Panel panel [] = new Panel[12];
String items [] = {"NOP", "ADD", "LOAD"};
Choice choices [] = new Choice [11];
Choice c1 [] = new Choice [11];
Choice c2 [] = new Choice [11];
Choice cerg [] = new Choice [11];
Label labels [] = new Label[11];
Label gleich [] = new Label[11];
Label plus [] = new Label[11];
String g = "=";
String p = "+";
Test te = new Test();
HauptPanel(Test p)
{
te=p;
setLayout(new GridLayout(0,1));
setBackground(bgCo);
panelsEinfuegen();
labelsEinfuegen();
choicesEinfuegen();
panel[11].add(buttonL);
panel[11].add(t);
rufItem();
undAction();
}
public void panelsEinfuegen()
{
for (int i=0; i<panel.length; i++)
{
panel[i]=new Panel();
add(panel[i]);
}
}
public void choicesEinfuegen()
{
for (int i=0; i<choices.length; i++)
{
choices[i] = new Choice();
choices[i].addItem(items [0]);
choices[i].addItem(items [1]);
choices[i].addItem(items [2]);
panel[i].add(choices[i]);
}
}
public void labelsEinfuegen()
{
for (int i=0; i<labels.length; i++)
{
labels[i]=new Label(String.valueOf(i));
gleich[i] =new Label(g);
plus[i] =new Label(p);
panel[i].add(labels[i]);
}
}
public void rufItem()
{
for ( int i=0; i<choices.length; i++)
{
final int index = i;
choices[i].addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if ( ItemEvent.SELECTED == 1)
{
aendere( index, e.getItem() );
}
}
});
}
}
public void aendere( int index, Object item )
{
if(item.equals("ADD"))
{
if (cerg[index]!=null)
{
panel[index].remove(cerg[index]);
panel[index].remove(gleich[index]);
panel[index].remove(plus[index]);
panel[index].remove(c1[index]);
panel[index].remove(c2[index]);
}
c1[index] = new Choice();
c2[index] = new Choice();
cerg[index]= new Choice();
gleich[index] = new Label("=");
plus[index]= new Label("+");
c1[index].add("R 0");
c1[index].add("R 1");
c2[index].add("R 0");
c2[index].add("R 1");
cerg[index].add("R 1");
cerg[index].add("R 2");
panel[index].add(cerg[index]);
panel[index].add(gleich[index]);
panel[index].add(c1[index]);
panel[index].add(plus[index]);
panel[index].add(c2[index]);
}
repaint();
getParent().validate();
}
public void undAction()
{
buttonL.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
drueck(e);
}
});
}
public void drueck(ActionEvent action)
{
String command=action.getActionCommand();
if(command.equals("Los"))
{
te.remove(this);
validate();
}
}
}
Integriere doch ein Objekt, das du dann z.B. mit meinObjekt.setVisible(false); unsichtbar,
bzw mit meinObjekt.setVisible(true); sichtbar machen kannst. Dann hast du es nicht so
umständlich mit den Löschvorgängen.
In der StackOverflowException steht Linie 13 und 45, also hab ich nachgeschaut was in diesen Linien passiert.
Und da der "eine Instanz zuviel"-Fehler schon öfters auftratt, war nicht mehr viel kombinatorisches Geschick notwendig...