2 Observers (JInternalFrames) 1 Observable не работает
У меня есть 3 класса. Один класс - это мой мэйнфрейм, другой - мой JInternalFrame, а также мой наблюдатель, а третий класс выполняет симуляцию с кнопками поля ob, и этот класс также является моим наблюдаемым классом.
В основном я сделал кнопку в моем обозревателе, которая копирует себя. Это включает в себя add к desktoppane и функцию addObserver моего наблюдаемого класса.
Клон моего наблюдателя должен также наблюдать за тем же самым наблюдаемым. Поэтому, если я взаимодействую с одним JInternalFrame, он также меняет материал для другого InternalFrame. Это должно действовать как зеркало. (На самом деле копия должна иметь разные цветные кнопки и различную ориентацию, но я думаю, что это не должно быть проблемой для реализации, как только я успешно смогу отразить мой Observer)
Так как я использую шаблон Observable, я также должен реализовать функцию "update" в своем классе Observer. Я сделал это, и я работаю как шарм. Но когда я копирую свой JInternalFrame, новый InternalFrame наблюдает Observable(Simulation), а мой оригинальный JInternalFrame теряет наблюдаемое соединение. Больше не отображаются кнопки и т. Д.
Что я пробовал: я создал второй класс Observer/JInternalFrame, который расширяет мой первый класс Observer. Это не сработало. Я не знаю, есть ли возможность достичь того, чего я хочу.
Извините за мой не идеальный английский. Извините за некоторые немецкие слова, которые вы можете найти в коде, и извините, что я публикую так много кода. Но сейчас я действительно не уверен, где моя ошибка, поскольку я до сих пор пытался найти ошибку для наших.
Итак, вот вам две картинки: Первая картинка показывает, как выглядит мой JInternalFrame, когда я его создаю. Здесь все работает отлично.
Второе изображение показывает, как это выглядит, когда я нажимаю на кнопку New View. Как уже описано. Оригинальный JInternalFrame больше не показывает симуляцию. Хотя они оба наблюдают одну и ту же наблюдаемую.
И вот мои 3 важных класса:
MainFrame:
public class LangtonsAmeise extends JFrame implements ActionListener {
JDesktopPane desk;
JPanel panelButtons;
JMenuBar jmb;
JMenu file, modus;
JMenuItem load, save, exit, mSetzen, mMalen, mLaufen;
JSlider slider;
static int xInt, yInt, xKindFrame = 450, yKindFrame = 450, xLocation,
yLocation, xMainFrame = 1000, yMainFrame = 900;
static boolean bSetzen = false, bMalen = false, running = true;
static JFileChooser fc;
Random randomGenerator = new Random();
JLabel xLabel, yLabel, speed, statusText, status;
JButton start, stop, addAnt;
JTextField xField, yField;
public LangtonsAmeise() {
// Desktop
desk = new JDesktopPane();
getContentPane().add(desk, BorderLayout.CENTER);
// File Chooser
fc = new JFileChooser(System.getProperty("user.dir"));
speed = new JLabel("Geschwindigkeit");
xLabel = new JLabel("x:");
yLabel = new JLabel("y:");
xLabel.setHorizontalAlignment(JLabel.RIGHT);
yLabel.setHorizontalAlignment(JLabel.RIGHT);
xLabel.setOpaque(true);
yLabel.setOpaque(true);
xField = new JTextField();
yField = new JTextField();
start = new JButton("Fenster erstellen");
stop = new JButton("Pause/Fortsetzen");
start.setMargin(new Insets(0, 0, 0, 0));
stop.setMargin(new Insets(0, 0, 0, 0));
// Buttons
panelButtons = new JPanel();
panelButtons.setLayout(new GridLayout());
panelButtons.add(start);
panelButtons.add(xLabel);
panelButtons.add(xField);
panelButtons.add(yLabel);
panelButtons.add(yField);
panelButtons.add(speed);
panelButtons.add(new Panel());
panelButtons.add(stop);
start.addActionListener(this);
stop.addActionListener(this);
add(panelButtons, BorderLayout.NORTH);
statusText = new JLabel("Status:");
status = new JLabel("Stopp");
// JMenuBar
jmb = new JMenuBar();
setJMenuBar(jmb);
file = new JMenu("File");
modus = new JMenu("Mode");
mLaufen = new JMenuItem("Laufen");
mMalen = new JMenuItem("Malen");
mSetzen = new JMenuItem("Setzen");
load = new JMenuItem("Simulation laden");
//save = new JMenuItem("Simulation speichern");
mSetzen.addActionListener(this);
mMalen.addActionListener(this);
mLaufen.addActionListener(this);
exit = new JMenuItem("Exit");
file.add(load);
file.addSeparator();
file.add(exit);
load.addActionListener(this);
modus.add(mLaufen);
modus.add(mSetzen);
modus.add(mMalen);
jmb.add(file);
jmb.add(modus);
for (int i = 0; i < 20; i++) {
jmb.add(new JLabel(" "));
}
jmb.add(statusText);
jmb.add(status);
setSize(new Dimension(xMainFrame, yMainFrame));
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation(dim.width / 2 - this.getSize().width / 2, dim.height
/ 2 - this.getSize().height / 2);
xField.setText("5");
yField.setText("5");
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Fenster erstellen")) {
if (xField.getText().equals("") || yField.getText().equals("")) {
} else {
xInt = Integer.parseInt(xField.getText());
yInt = Integer.parseInt(yField.getText());
state s = new state();
kindFenster k = new kindFenster(s, this);
s.addObserver(k);
addChild(k);
s.startSimulation();
}
}
if (e.getActionCommand().equals("Pause/Fortsetzen")) {
running = !running;
System.out.println(running);
status.setText("Stopp");
}
if (e.getActionCommand().equals("Setzen")) {
status.setText("Setzen");
running = false;
bSetzen = true;
bMalen = false;
}
if (e.getActionCommand().equals("Laufen")) {
status.setText("Laufen");
running = true;
bSetzen = false;
bMalen = false;
}
if (e.getActionCommand().equals("Malen")) {
status.setText("Malen");
running = false;
bSetzen = false;
bMalen = true;
}
if (e.getActionCommand().equals("Simulation laden")) {
LangtonsAmeise.running = false;
InputStream fis = null;
try {
fc.showOpenDialog(null);
fis = new FileInputStream(fc.getSelectedFile().getPath());
ObjectInputStream ois = new ObjectInputStream(fis);
state s = (state) ois.readObject();
kindFenster k = new kindFenster(s, this);
s.addObserver(k);
addChild(k);
s.startSimulation();
} catch (IOException | ClassNotFoundException
| NullPointerException e1) {
LangtonsAmeise.running = true;
} finally {
try {
fis.close();
} catch (NullPointerException | IOException e1) {
LangtonsAmeise.running = true;
}
}
LangtonsAmeise.running = true;
}
}
public void addChild(JInternalFrame kind) {
xLocation = randomGenerator.nextInt(xMainFrame - xKindFrame);
yLocation = randomGenerator.nextInt(yMainFrame - yKindFrame - 100);
kind.setSize(370, 370);
kind.setLocation(xLocation, yLocation);
desk.add(kind);
kind.setVisible(true);
}
public static void main(String[] args) {
LangtonsAmeise hauptFenster = new LangtonsAmeise();
}
}
JInternalFrame:
public class kindFenster extends JInternalFrame implements ActionListener,
Serializable,Observer,Cloneable {
/**
*
*/
private static final long serialVersionUID = 8939449766068226519L;
static int nr = 0;
static int x,y,xScale,yScale,xFrame,yFrame;
state s;
ArrayList<ImageIcon> ameisen = new ArrayList<ImageIcon>();
JFileChooser fc;
LangtonsAmeise la;
Color alteFarbe, neueFarbe;
JButton save, addAnt, newView;
JPanel panelButtonsKind;
JSlider sliderKind;
public JPanel panelSpielfeld,panelSpielfeldKopie;
JButton[] jbArrayy;
static SetzenActionListener sal = new SetzenActionListener();
static MouseMotionActionListener mmal = new MouseMotionActionListener();
public kindFenster(state s,LangtonsAmeise la) {
super("Kind " + (++nr), true, true, true, true);
setLayout(new BorderLayout());
this.s=s;
jbArrayy=new JButton[s.jbArrayy.length];
for (int b = 1; b<s.jbArrayy.length;b++) {
this.jbArrayy[b] = s.jbArrayy[b];
}
this.la=la;
setSize(new Dimension(xFrame, yFrame));
this.addInternalFrameListener(listener);
this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
panelSpielfeld = new JPanel();
panelSpielfeld.setLayout(new GridLayout(s.y, s.x));
panelButtonsKind = new JPanel();
panelButtonsKind.setLayout(new GridLayout(1, 3));
save = new JButton("<html>Save<br>simulation</html>");
addAnt = new JButton("<html>Add<br>ant</html>");
newView = new JButton("<html>New<br>View</html>");
save.setActionCommand("save");
addAnt.setActionCommand("addAnt");
newView.setActionCommand("newView");
save.setMargin(new Insets(0, 0, 0, 0));
addAnt.setMargin(new Insets(0, 0, 0, 0));
addAnt.addActionListener(this);
save.addActionListener(this);
newView.addActionListener(this);
sliderKind = new JSlider(JSlider.HORIZONTAL, 1, 9, 5);
sliderKind.setSnapToTicks(true);
sliderKind.setPaintTicks(true);
sliderKind.setPaintTrack(true);
sliderKind.setMajorTickSpacing(1);
sliderKind.setPaintLabels(true);
sliderKind.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
if (!source.getValueIsAdjusting()) {
int speed = source.getValue();
state.sleeptime = 1000 / speed;
}
}
});
panelButtonsKind.add(save);
panelButtonsKind.add(newView);
panelButtonsKind.add(sliderKind);
panelButtonsKind.add(addAnt);
add(panelButtonsKind, BorderLayout.NORTH);
add(panelSpielfeld, BorderLayout.CENTER);
this.addComponentListener(new MyComponentAdapter());
for (int i = 1 ; i<jbArrayy.length;i++) {
panelSpielfeld.add(jbArrayy[i]);
}
}
// I have been trying around to change the orientation of the buttons in the copy of the frame
public void secondViewFrameSettings() {
int temp;
for (int i = 1; i<=x;i++) {
for (int k = 0; k<y;k++) {
temp = i+(k*x);
panelSpielfeldKopie.add(s.jbArrayy[temp]);
}
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("addAnt")) {
s.addAnt();
}
if (e.getActionCommand().equals("newView")){
kindFenster kk = new kindFenster(s,la);
s.addObserver(kk);
la.addChild(kk);
}
if (e.getActionCommand().equals("save")) {
OutputStream fos = null;
try {
LangtonsAmeise.running=false;
try {
fc = new JFileChooser(System.getProperty("user.dir"));
fc.showSaveDialog(null);
LangtonsAmeise.fc.setCurrentDirectory(fc.getSelectedFile());
fos = new FileOutputStream(fc.getSelectedFile());
ObjectOutputStream o = new ObjectOutputStream(fos);
o.writeObject(s);
} catch (NullPointerException e2) {
System.out.println("Fehler beim Auswählen der Datei. Wenden Sie sich an den Entwickler.");
}
} catch (IOException e1) {
LangtonsAmeise.running=true;
System.err.println(e1);
} finally {
try {
fos.close();
} catch (NullPointerException | IOException e1) {
LangtonsAmeise.running=true;
}
LangtonsAmeise.running=true;
}
LangtonsAmeise.running=true;
}
}
InternalFrameListener listener = new InternalFrameAdapter() {
public void internalFrameClosing(InternalFrameEvent e) {
e.getInternalFrame().dispose();
s.simulation.suspend();
}
};
class MyComponentAdapter extends ComponentAdapter {
public void componentResized(ComponentEvent e) {
//Ameisenbilder an die Buttongrößen anpassen
xScale=s.jbArrayy[1].getSize().width;
yScale=s.jbArrayy[1].getSize().height;
s.ameisen.clear();
s.ameisen.add(new ImageIcon(new ImageIcon("ameise.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
s.ameisen.add(new ImageIcon(new ImageIcon("ameise90.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
s.ameisen.add(new ImageIcon(new ImageIcon("ameise180.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
s.ameisen.add(new ImageIcon(new ImageIcon("ameise270.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
}
}
public void update(Observable o, Object arg) {
if (o == s) {
for (int i = 1;i<s.jbArrayy.length;i++) {
jbArrayy[i].setBackground(s.jbArrayy[i].getBackground());
}
}
}
}
class SetzenActionListener implements ActionListener,Serializable {
JButton source;
@Override
public void actionPerformed(ActionEvent e) {
source = (JButton) e.getSource();
if (LangtonsAmeise.bSetzen == true) {
if (source.getBackground().equals(Color.GREEN)) {
source.setBackground(Color.WHITE);
} else {
source.setBackground(Color.GREEN);
}
}
}
}
class MouseMotionActionListener extends MouseInputAdapter implements Serializable {
boolean dragged = false;
JButton tempJButton = new JButton();
public void mouseEntered(MouseEvent e) {
if (LangtonsAmeise.bMalen == true && dragged == true) {
((JButton) e.getSource()).setBackground(Color.GREEN);
}
}
public void mouseDragged(MouseEvent e) {
dragged = true;
}
public void mouseReleased(MouseEvent e) {
dragged = false;
}
}
Наблюдаемый класс:
public class state extends Observable implements Serializable {
/**
*
*/
private static final long serialVersionUID = 450773214079105589L;
int[] obRand, reRand, unRand, liRand;
int x, y, temp;
static int sleeptime = 200;
Color background;
int posAmeise, aktuellesIcon = 1, altePosAmeise, xScale, yScale;
Color alteFarbe, neueFarbe, color1, color2;
ArrayList<JButton> jbSer = new ArrayList<JButton>();
private List<Ant> ants = new ArrayList<Ant>();
ArrayList<ImageIcon> ameisen = new ArrayList<>();
JButton[] jbArrayy;
transient Thread simulation;
public state() {
this.x = LangtonsAmeise.xInt;
this.y = LangtonsAmeise.yInt;
color1 = Color.WHITE;
color2 = Color.GREEN;
jbArrayy = new JButton[x * y + 1];
initializeBorders();
initializeAntsImages();
initializeSimulationButtons();
xScale = jbArrayy[1].getSize().width;
yScale = jbArrayy[1].getSize().height;
// Startpunkt für die Ameise festlegen
posAmeise = (((x / 2) * y) - y / 2);
background = jbArrayy[posAmeise].getBackground();
ants.add(new Ant(this));
}
public void initializeAntsImages() {
ameisen.add(new ImageIcon(new ImageIcon("ameise.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
ameisen.add(new ImageIcon(new ImageIcon("ameise90.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
ameisen.add(new ImageIcon(new ImageIcon("ameise180.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
ameisen.add(new ImageIcon(new ImageIcon("ameise270.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
}
// Alle Buttons für das Simulationsfeld werden erstellt
public void initializeSimulationButtons() {
jbArrayy[0] = new JButton();
for (int i = 1; i < jbArrayy.length; i++) {
jbArrayy[i] = new JButton();
jbArrayy[i].setBackground(color1);
jbArrayy[i].addActionListener(kindFenster.sal);
jbArrayy[i].addMouseListener(kindFenster.mmal);
jbArrayy[i].addMouseMotionListener(kindFenster.mmal);
}
}
// Ränderindex in Array schreiben
public void initializeBorders() {
reRand = new int[y];
liRand = new int[y];
obRand = new int[x];
unRand = new int[x];
for (int i = 0; i < x; i++) {
obRand[i] = i + 1;
unRand[i] = (x * y - x) + i + 1;
}
for (int i = 1; i <= y; i++) {
reRand[i - 1] = i * x;
liRand[i - 1] = i * x - (x - 1);
}
}
public void initializeSimulation() {
if (simulation != null && simulation.isAlive()) {
simulation.stop();
}
simulation = new Thread() {
@Override
public void run() {
super.run();
while (true) {
try {
sleep(300);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
while (LangtonsAmeise.running && countObservers() > 0) {
try {
Thread.sleep(sleeptime);
for (Ant a : ants) {
move(a);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};
}
public void startSimulation() {
initializeSimulation();
simulation.start();
}
public void changeColor(int altePos, Color c) {
jbArrayy[altePos].setBackground(c);
}
public void addAnt() {
ants.add(new Ant(this));
}
public void changeIcon(boolean k, Ant a) {
int g = (k == true) ? 1 : -1;
if (a.aktuellesIcon + g < 0) {
a.aktuellesIcon = 3;
} else if (a.aktuellesIcon + g > 3) {
a.aktuellesIcon = 0;
} else {
a.aktuellesIcon += g;
}
jbArrayy[a.posAmeise].setIcon(ameisen.get(a.aktuellesIcon));
setChanged();
notifyObservers();
}
public void rightCheck(Ant a) {
if (checkInArray(a.posAmeise, reRand)) {
a.posAmeise -= x - 1;
} else {
a.posAmeise += 1;
}
}
public void leftCheck(Ant a) {
if (checkInArray(a.posAmeise, liRand)) {
a.posAmeise += x - 1;
} else {
a.posAmeise -= 1;
}
}
public void upCheck(Ant a) {
if (checkInArray(a.posAmeise, obRand)) {
a.posAmeise += (y - 1) * x;
} else {
a.posAmeise -= x;
}
}
public void downCheck(Ant a) {
if (checkInArray(a.posAmeise, unRand)) {
a.posAmeise -= (y - 1) * x;
} else {
a.posAmeise += x;
}
}
public void checkAmeisenSize(Ant a) {
while (!(ameisen.size() == 4)) {
}
;
}
public static boolean checkInArray(int currentState, int[] myArray) {
int i = 0;
for (; i < myArray.length; i++) {
if (myArray[i] == currentState)
break;
}
return i != myArray.length;
}
public ImageIcon getAntImage() {
return ameisen.get(aktuellesIcon);
}
public void move(Ant a) throws InterruptedException {
try {
a.altePosAmeise = a.posAmeise;
a.alteFarbe = jbArrayy[a.posAmeise].getBackground();
if (a.alteFarbe.equals(Color.GREEN) && ameisen.size() == 4) {
if (a.aktuellesIcon == 0) {
checkAmeisenSize(a);
rightCheck(a);
} else if (a.aktuellesIcon == 1) {
checkAmeisenSize(a);
downCheck(a);
} else if (a.aktuellesIcon == 2) {
checkAmeisenSize(a);
leftCheck(a);
} else if (a.aktuellesIcon == 3) {
checkAmeisenSize(a);
upCheck(a);
}
changeIcon(true, a);
changeColor(a.altePosAmeise, Color.WHITE);
} else if (a.alteFarbe.equals(Color.WHITE) && ameisen.size() == 4) {
if (a.aktuellesIcon == 0) {
checkAmeisenSize(a);
leftCheck(a);
} else if (a.aktuellesIcon == 1) {
checkAmeisenSize(a);
upCheck(a);
} else if (a.aktuellesIcon == 2) {
checkAmeisenSize(a);
rightCheck(a);
} else if (a.aktuellesIcon == 3) {
checkAmeisenSize(a);
downCheck(a);
}
changeIcon(false, a);
changeColor(a.altePosAmeise, Color.GREEN);
setChanged();
notifyObservers();
}
jbArrayy[a.altePosAmeise].setIcon(new ImageIcon());
} catch (IndexOutOfBoundsException e) {
move(a);
}
}
}
Редактировать: Муравей Класс
import java.awt.Color;
import java.awt.Image;
import java.io.Serializable;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Ant implements Serializable {
int posAmeise, aktuellesIcon = 1, altePosAmeise;
Color alteFarbe, neueFarbe;
ArrayList<ImageIcon> ameisen = new ArrayList<>();
public Ant(state s) {
this.posAmeise = s.posAmeise;
s.jbArrayy[posAmeise].setIcon(s.ameisen.get(aktuellesIcon));
}
}