/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */
package com.cburch.logisim.gui.log;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import com.cburch.logisim.circuit.CircuitState;
import com.cburch.logisim.circuit.Simulator;
import com.cburch.logisim.circuit.SimulatorEvent;
import com.cburch.logisim.circuit.SimulatorListener;
import com.cburch.logisim.file.LibraryEvent;
import com.cburch.logisim.file.LibraryListener;
import com.cburch.logisim.gui.generic.LFrame;
import com.cburch.logisim.gui.menu.LogisimMenuBar;
import com.cburch.logisim.proj.Project;
import com.cburch.logisim.proj.ProjectEvent;
import com.cburch.logisim.proj.ProjectListener;
import com.cburch.logisim.util.LocaleListener;
import com.cburch.logisim.util.LocaleManager;
import com.cburch.logisim.util.WindowMenuItemManager;
import static com.cburch.logisim.util.LocaleString.*;
@SuppressWarnings("serial")
public class LogFrame extends LFrame {
// TODO should automatically repaint icons when component attr change
// TODO ? moving a component using Select tool removes it from selection
private class WindowMenuManager extends WindowMenuItemManager
implements LocaleListener, ProjectListener, LibraryListener {
WindowMenuManager() {
super(getFromLocale("logFrameMenuItem"), false);
project.addProjectListener(this);
project.addLibraryListener(this);
}
@Override
public JFrame getJFrame(boolean create) {
return LogFrame.this;
}
@Override
public void localeChanged() {
String title = project.getLogisimFile().getDisplayName();
setText(getFromLocale("logFrameMenuItem", title));
}
@Override
public void projectChanged(ProjectEvent event) {
if (event.getAction() == ProjectEvent.ACTION_SET_FILE) {
localeChanged();
}
}
@Override
public void libraryChanged(LibraryEvent event) {
if (event.getAction() == LibraryEvent.SET_NAME) {
localeChanged();
}
}
}
private class MyListener
implements ActionListener, ProjectListener, LibraryListener,
SimulatorListener, LocaleListener {
@Override
public void actionPerformed(ActionEvent event) {
Object src = event.getSource();
if (src == close) {
WindowEvent e = new WindowEvent(LogFrame.this,
WindowEvent.WINDOW_CLOSING);
LogFrame.this.processWindowEvent(e);
}
}
@Override
public void projectChanged(ProjectEvent event) {
int action = event.getAction();
if (action == ProjectEvent.ACTION_SET_STATE) {
setSimulator(event.getProject().getSimulator(),
event.getProject().getCircuitState());
} else if (action == ProjectEvent.ACTION_SET_FILE) {
setTitle(computeTitle(curModel, project));
}
}
@Override
public void libraryChanged(LibraryEvent event) {
int action = event.getAction();
if (action == LibraryEvent.SET_NAME) {
setTitle(computeTitle(curModel, project));
}
}
@Override
public void localeChanged() {
setTitle(computeTitle(curModel, project));
for (int i = 0; i < panels.length; i++) {
tabbedPane.setTitleAt(i, panels[i].getTitle());
tabbedPane.setToolTipTextAt(i, panels[i].getToolTipText());
panels[i].localeChanged();
}
close.setText(getFromLocale("closeButton"));
windowManager.localeChanged();
}
@Override
public void propagationCompleted(SimulatorEvent e) {
curModel.propagationCompleted();
}
@Override
public void tickCompleted(SimulatorEvent e) { }
@Override
public void simulatorStateChanged(SimulatorEvent e) { }
}
private Project project;
private Simulator curSimulator = null;
private Model curModel;
private Map<CircuitState,Model> modelMap = new HashMap<CircuitState,Model>();
private MyListener myListener = new MyListener();
private WindowMenuManager windowManager;
private LogPanel[] panels;
private JTabbedPane tabbedPane;
private JButton close = new JButton();
public LogFrame(Project project) {
this.project = project;
this.windowManager = new WindowMenuManager();
project.addProjectListener(myListener);
project.addLibraryListener(myListener);
setDefaultCloseOperation(HIDE_ON_CLOSE);
setJMenuBar(new LogisimMenuBar(this, project));
setSimulator(project.getSimulator(), project.getCircuitState());
panels = new LogPanel[] {
new SelectionPanel(this),
new ScrollPanel(this),
new FilePanel(this),
};
tabbedPane = new JTabbedPane();
for (int index = 0; index < panels.length; index++) {
LogPanel panel = panels[index];
tabbedPane.addTab(panel.getTitle(), null, panel, panel.getToolTipText());
}
JPanel buttonPanel = new JPanel();
buttonPanel.add(close);
close.addActionListener(myListener);
Container contents = getContentPane();
tabbedPane.setPreferredSize(new Dimension(450, 300));
contents.add(tabbedPane, BorderLayout.CENTER);
contents.add(buttonPanel, BorderLayout.SOUTH);
LocaleManager.addLocaleListener(myListener);
myListener.localeChanged();
pack();
}
public Project getProject() {
return project;
}
Model getModel() {
return curModel;
}
private void setSimulator(Simulator value, CircuitState state) {
if ((value == null) == (curModel == null)) {
if (value == null || value.getCircuitState() == curModel.getCircuitState()) {
return;
}
}
LogisimMenuBar menubar = (LogisimMenuBar) getJMenuBar();
menubar.setCircuitState(value, state);
if (curSimulator != null) {
curSimulator.removeSimulatorListener(myListener);
}
if (curModel != null) {
curModel.setSelected(this, false);
}
Model oldModel = curModel;
Model data = null;
if (value != null) {
data = modelMap.get(value.getCircuitState());
if (data == null) {
data = new Model(value.getCircuitState());
modelMap.put(data.getCircuitState(), data);
}
}
curSimulator = value;
curModel = data;
if (curSimulator != null) {
curSimulator.addSimulatorListener(myListener);
}
if (curModel != null) {
curModel.setSelected(this, true);
}
setTitle(computeTitle(curModel, project));
if (panels != null) {
for (int i = 0; i < panels.length; i++) {
panels[i].modelChanged(oldModel, curModel);
}
}
}
@Override
public void setVisible(boolean value) {
if (value) {
windowManager.frameOpened(this);
}
super.setVisible(value);
}
LogPanel[] getPrefPanels() {
return panels;
}
private static String computeTitle(Model data, Project proj) {
String name = data == null ? "???" : data.getCircuitState().getCircuit().getName();
return getFromLocale("logFrameTitle", name, proj.getLogisimFile().getDisplayName());
}
}