Hallo,
Dies ist ein Repost eines Beitrags aus der Kategorie AWT, Swing, usw. Passt wohl besser hier rein. Moderator: den anderen Post könnte man löschen. (www.java-forum.org/de/topic60816_illegalstateexception-problem-gui-observer-pattern.html)
Ich habe versucht, ein Beobachtungsmuster zu implementieren. Dabei habe ich eine Klasse, die die Daten beherbergt, wenn diese geändert werden soll das GUI benachrichtigt werden und die Daten da eingetragen (z.T. an versch. Orten).
Mit meiner Implementation bekomme ich eine Ausnahme, die ich zwar zu deuten weiss, aber noch keine Möglichkeit gefunden habe, sie zu umgehen. Hier die Ausnahme:
Das ganze endet in:
Dies bedeutet (soviel hab ich beim googeln herausgefunden), dass der Aufruf von setText() ausgeführt werden soll, obwohl bereits ein setText läuft. Wie ich das aber verhindern kann, hab ich noch nicht gefunden.
Folgend die wichtigen Klassen, auf das wesentliche gekürzt.
Klasse WeatherStation Datenklasse (Subject), die das GUI informiert.
GUI-Klasse ProjectBottomWeatherStationTab beihaltet die observierten Textfelder.
GUI-Klasse ProjectBottomPanel. Hier wird der Observer hinzugefügt.
Was mache ich falsch? Hat jemand eine Idee? Ich probiere schon eine ganze Zeit, krieg aber nix gescheites raus.
Herzlichen Dank
mas
Dies ist ein Repost eines Beitrags aus der Kategorie AWT, Swing, usw. Passt wohl besser hier rein. Moderator: den anderen Post könnte man löschen. (www.java-forum.org/de/topic60816_illegalstateexception-problem-gui-observer-pattern.html)
Ich habe versucht, ein Beobachtungsmuster zu implementieren. Dabei habe ich eine Klasse, die die Daten beherbergt, wenn diese geändert werden soll das GUI benachrichtigt werden und die Daten da eingetragen (z.T. an versch. Orten).
Mit meiner Implementation bekomme ich eine Ausnahme, die ich zwar zu deuten weiss, aber noch keine Möglichkeit gefunden habe, sie zu umgehen. Hier die Ausnahme:
Code:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification
at javax.swing.text.AbstractDocument.writeLock(Unknown Source)
at javax.swing.text.AbstractDocument.replace(Unknown Source)
at javax.swing.text.JTextComponent.setText(Unknown Source)
at ch.arocom.arodimnt.create.gui.bottomPanels.ProjectBottomTab.setDeviceText(ProjectBottomTab.java:163)
at ch.arocom.arodimnt.create.gui.bottomPanels.ProjectBottomWeatherStationTab.update(ProjectBottomWeatherStationTab.java:67)
at java.util.Observable.notifyObservers(Unknown Source)
at java.util.Observable.notifyObservers(Unknown Source)
at ch.arocom.arodimnt.create.logic.saveableObjects.WeatherStation.setPort(WeatherStation.java:39)
at ch.arocom.arodimnt.create.gui.bottomPanels.ProjectBottomWeatherStationTab.performDeviceUpdate(ProjectBottomWeatherStationTab.java:38)
at ch.arocom.arodimnt.create.gui.bottomPanels.ProjectBottomTab$1.removeUpdate(ProjectBottomTab.java:83)
at javax.swing.text.AbstractDocument.fireRemoveUpdate(Unknown Source)
at javax.swing.text.AbstractDocument.handleRemove(Unknown Source)
at javax.swing.text.AbstractDocument.remove(Unknown Source)
at javax.swing.text.AbstractDocument.replace(Unknown Source)
at javax.swing.text.JTextComponent.setText(Unknown Source)
at ch.arocom.arodimnt.create.gui.bottomPanels.ProjectBottomTab.setDeviceText(ProjectBottomTab.java:163)
at ch.arocom.arodimnt.create.gui.bottomPanels.ProjectBottomWeatherStationTab.update(ProjectBottomWeatherStationTab.java:67)
at java.util.Observable.notifyObservers(Unknown Source)
at java.util.Observable.notifyObservers(Unknown Source)
at ch.arocom.arodimnt.create.logic.saveableObjects.WeatherStation.setPresent(WeatherStation.java:59)
at ch.arocom.arodimnt.create.gui.bottomPanels.ProjectBottomWeatherStationTab.itemStateChanged(ProjectBottomWeatherStationTab.java:25)
at javax.swing.AbstractButton.fireItemStateChanged(Unknown Source)
at javax.swing.AbstractButton$Handler.itemStateChanged(Unknown Source)
at javax.swing.DefaultButtonModel.fireItemStateChanged(Unknown Source)
at javax.swing.JToggleButton$ToggleButtonModel.setSelected(Unknown Source)
at javax.swing.JToggleButton$ToggleButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Das ganze endet in:
Code:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification
Dies bedeutet (soviel hab ich beim googeln herausgefunden), dass der Aufruf von setText() ausgeführt werden soll, obwohl bereits ein setText läuft. Wie ich das aber verhindern kann, hab ich noch nicht gefunden.
Folgend die wichtigen Klassen, auf das wesentliche gekürzt.
Klasse WeatherStation Datenklasse (Subject), die das GUI informiert.
Code:
public class WeatherStation extends Observable implements Serializable{
private int device, port, system;
private boolean isPresent;
public WeatherStation(int device, int port, int system){
this.device = device;
this.port = port;
this.system = system;
isPresent = true;
}
public WeatherStation(){
isPresent = false;
}
public int getDevice() {
return device;
}
public void setDevice(int device) {
this.device = device;
setChanged();
notifyObservers();
}
public void setPort(int port) {
this.port = port;
setChanged();
notifyObservers();
}
public void setSystem(int system) {
this.system = system;
setChanged();
notifyObservers();
}
public void setPresent(boolean isPresent) {
this.isPresent = isPresent;
setChanged();
notifyObservers();
}
}
GUI-Klasse ProjectBottomWeatherStationTab beihaltet die observierten Textfelder.
Code:
public class ProjectBottomWeatherStationTab extends ProjectBottomTab{
WeatherStation weatherStation;
public ProjectBottomWeatherStationTab(){
super();
weatherStation = new WeatherStation();
setTitleText("Wetterstation");
setPortText("2");
setCheckboxText("Dieses Projekt enthält eine Wetterstation.");
}
@Override
public void itemStateChanged(ItemEvent e) {
if(checkbox.isSelected()){
System.out.println("Set weather station present");
weatherStation.setPresent(true);
}
else{
System.out.println("UN-Set weather station present");
weatherStation.setPresent(false);
}
}
@Override
public void performDeviceUpdate(){
try{
weatherStation.setDevice( Integer.valueOf( device.getText() ));
} catch (NumberFormatException e){
weatherStation.setPort( 0 );
}
}
@Override
public void performPortUpdate(){
try{
weatherStation.setPort( Integer.valueOf( device.getText() ));
} catch (NumberFormatException e){
weatherStation.setPort( 0 );
}
}
@Override
public void performSystemUpdate(){
try{
weatherStation.setSystem( Integer.valueOf( device.getText() ));
} catch (NumberFormatException e){
weatherStation.setPort( 0 );
}
}
@Override
public void update(Observable o, Object arg) {
WeatherStation ws = (WeatherStation)o;
device.setEnabled(ws.isPresent());
port.setEnabled(ws.isPresent());
setDeviceText( String.valueOf(ws.getDevice()) );
setPortText( String.valueOf(ws.getPort()) );
setSystemText( String.valueOf(ws.getSystem() ));
}
}
GUI-Klasse ProjectBottomPanel. Hier wird der Observer hinzugefügt.
Code:
public class ProjectBottomPanel extends JPanel{
private MainWindow parent;
private WeatherStation weatherStation;
public ProjectBottomPanel(MainWindow parent){
this.parent = parent;
weatherStation = new WeatherStation(5001,2,1);
// WEATHER PANEL
JPanel weatherContainer = new JPanel();
weatherContainer.setLayout(new FlowLayout(FlowLayout.LEFT));
ProjectBottomWeatherStationTab wst = new ProjectBottomWeatherStationTab();
wst.weatherStation = weatherStation;
weatherStation.addObserver((Observer)wst);
weatherContainer.add(wst);
// ADD TO TABBED PANE
JTabbedPane jtp = new JTabbedPane();
jtp.add("Wetterstation",weatherContainer);
this.add(jtp, BorderLayout.CENTER);
}
}
Was mache ich falsch? Hat jemand eine Idee? Ich probiere schon eine ganze Zeit, krieg aber nix gescheites raus.
Herzlichen Dank
mas