Package com.cburch.logisim.gui.menu

Source Code of com.cburch.logisim.gui.menu.MenuSimulate$MyListener

/* 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.menu;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.ButtonGroup;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.cburch.logisim.circuit.Circuit;
import com.cburch.logisim.circuit.CircuitEvent;
import com.cburch.logisim.circuit.CircuitListener;
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.gui.log.LogFrame;
import com.cburch.logisim.proj.Project;
import com.cburch.logisim.util.StringUtil;

import java.util.ArrayList;

class MenuSimulate extends Menu {
  private class TickFrequencyChoice extends JRadioButtonMenuItem
      implements ActionListener {
    private double freq;

    public TickFrequencyChoice(double value) {
      freq = value;
      addActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
      if (currentSim != null) currentSim.setTickFrequency(freq);
    }

    public void localeChanged() {
      double f = freq;
      if (f < 1000) {
        String hzStr;
        if (Math.abs(f - Math.round(f)) < 0.0001) {
          hzStr = "" + (int) Math.round(f);
        } else {
          hzStr = "" + f;
        }
        setText(StringUtil.format(Strings.get("simulateTickFreqItem"), hzStr));
      } else {
        String kHzStr;
        double kf = Math.round(f / 100) / 10.0;
        if (kf == Math.round(kf)) {
          kHzStr = "" + (int) kf;
        } else {
          kHzStr = "" + kf;
        }
        setText(StringUtil.format(Strings.get("simulateTickKFreqItem"), kHzStr));
      }
    }
  }

  private class CircuitStateMenuItem extends JMenuItem
      implements CircuitListener, ActionListener {
    private CircuitState circuitState;

    public CircuitStateMenuItem(CircuitState circuitState) {
      this.circuitState = circuitState;

      Circuit circuit = circuitState.getCircuit();
      circuit.addCircuitListener(this);
      this.setText(circuit.getName());
      addActionListener(this);
    }
   
    void unregister() {
      Circuit circuit = circuitState.getCircuit();
      circuit.removeCircuitListener(this);
    }

    public void circuitChanged(CircuitEvent event) {
      if (event.getAction() == CircuitEvent.ACTION_SET_NAME) {
        this.setText(circuitState.getCircuit().getName());
      }
    }

    public void actionPerformed(ActionEvent e) {
      menubar.fireStateChanged(currentSim, circuitState);
    }
  }

  private class MyListener implements ActionListener, SimulatorListener,
      ChangeListener {
    public void actionPerformed(ActionEvent e) {
      Object src = e.getSource();
      Project proj = menubar.getProject();
      Simulator sim = proj == null ? null : proj.getSimulator();
      if (src == run || src == LogisimMenuBar.SIMULATE_ENABLE) {
        if (sim != null) {
          sim.setIsRunning(!sim.isRunning());
          proj.repaintCanvas();
        }
      } else if (src == reset) {
        if (sim != null) sim.requestReset();
      } else if (src == step || src == LogisimMenuBar.SIMULATE_STEP) {
        if (sim != null) sim.step();
      } else if (src == tickOnce || src == LogisimMenuBar.TICK_STEP) {
        if (sim != null) sim.tick();
      } else if (src == ticksEnabled || src == LogisimMenuBar.TICK_ENABLE) {
        if (sim != null) sim.setIsTicking(!sim.isTicking());
      } else if (src == log) {
        LogFrame frame = menubar.getProject().getLogFrame(true);
        frame.setVisible(true);
      }
    }

    public void propagationCompleted(SimulatorEvent e) { }
    public void tickCompleted(SimulatorEvent e) { }
    public void simulatorStateChanged(SimulatorEvent e) {
      Simulator sim = e.getSource();
      if (sim != currentSim) return;
      computeEnabled();
      run.setSelected(sim.isRunning());
      ticksEnabled.setSelected(sim.isTicking());
      double freq = sim.getTickFrequency();
      for (int i = 0; i < tickFreqs.length; i++) {
        TickFrequencyChoice item = tickFreqs[i];
        item.setSelected(freq == item.freq);
      }
    }

    public void stateChanged(ChangeEvent e) {
      step.setEnabled(run.isEnabled() && !run.isSelected());
    }
  }

  private LogisimMenuBar menubar;
  private MyListener myListener = new MyListener();
  private CircuitState currentState = null;
  private CircuitState bottomState = null;
  private Simulator currentSim = null;

  private MenuItemCheckImpl run;
  private JMenuItem reset = new JMenuItem();
  private MenuItemImpl step;
  private MenuItemCheckImpl ticksEnabled;
  private MenuItemImpl tickOnce;
  private JMenu tickFreq = new JMenu();
  private TickFrequencyChoice[] tickFreqs = {
    new TickFrequencyChoice(4096),
    new TickFrequencyChoice(2048),
    new TickFrequencyChoice(1024),
    new TickFrequencyChoice(512),
    new TickFrequencyChoice(256),
    new TickFrequencyChoice(128),
    new TickFrequencyChoice(64),
    new TickFrequencyChoice(32),
    new TickFrequencyChoice(16),
    new TickFrequencyChoice(8),
    new TickFrequencyChoice(4),
    new TickFrequencyChoice(2),
    new TickFrequencyChoice(1),
    new TickFrequencyChoice(0.5),
    new TickFrequencyChoice(0.25),
  };
  private JMenu downStateMenu = new JMenu();
  private ArrayList<CircuitStateMenuItem> downStateItems
    = new ArrayList<CircuitStateMenuItem>();
  private JMenu upStateMenu = new JMenu();
  private ArrayList<CircuitStateMenuItem> upStateItems
    = new ArrayList<CircuitStateMenuItem>();
  private JMenuItem log = new JMenuItem();

  public MenuSimulate(LogisimMenuBar menubar) {
    this.menubar = menubar;
   
    run = new MenuItemCheckImpl(this, LogisimMenuBar.SIMULATE_ENABLE);
    step = new MenuItemImpl(this, LogisimMenuBar.SIMULATE_STEP);
    ticksEnabled = new MenuItemCheckImpl(this, LogisimMenuBar.TICK_ENABLE);
    tickOnce = new MenuItemImpl(this, LogisimMenuBar.TICK_STEP);

    menubar.registerItem(LogisimMenuBar.SIMULATE_ENABLE, run);
    menubar.registerItem(LogisimMenuBar.SIMULATE_STEP, step);
    menubar.registerItem(LogisimMenuBar.TICK_ENABLE, ticksEnabled);
    menubar.registerItem(LogisimMenuBar.TICK_STEP, tickOnce);

    int menuMask = getToolkit().getMenuShortcutKeyMask();
    run.setAccelerator(KeyStroke.getKeyStroke(
        KeyEvent.VK_E, menuMask));
    reset.setAccelerator(KeyStroke.getKeyStroke(
        KeyEvent.VK_R, menuMask));
    step.setAccelerator(KeyStroke.getKeyStroke(
        KeyEvent.VK_I, menuMask));
    tickOnce.setAccelerator(KeyStroke.getKeyStroke(
        KeyEvent.VK_T, menuMask));
    ticksEnabled.setAccelerator(KeyStroke.getKeyStroke(
        KeyEvent.VK_K, menuMask));

    ButtonGroup bgroup = new ButtonGroup();
    for (int i = 0; i < tickFreqs.length; i++) {
      bgroup.add(tickFreqs[i]);
      tickFreq.add(tickFreqs[i]);
    }

    add(run);
    add(reset);
    add(step);
    addSeparator();
    add(upStateMenu);
    add(downStateMenu);
    addSeparator();
    add(tickOnce);
    add(ticksEnabled);
    add(tickFreq);
    addSeparator();
    add(log);

    setEnabled(false);
    run.setEnabled(false);
    reset.setEnabled(false);
    step.setEnabled(false);
    upStateMenu.setEnabled(false);
    downStateMenu.setEnabled(false);
    tickOnce.setEnabled(false);
    ticksEnabled.setEnabled(false);
    tickFreq.setEnabled(false);
   
    run.addChangeListener(myListener);
    menubar.addActionListener(LogisimMenuBar.SIMULATE_ENABLE, myListener);
    menubar.addActionListener(LogisimMenuBar.SIMULATE_STEP, myListener);
    menubar.addActionListener(LogisimMenuBar.TICK_ENABLE, myListener);
    menubar.addActionListener(LogisimMenuBar.TICK_STEP, myListener);
    // run.addActionListener(myListener);
    reset.addActionListener(myListener);
    // step.addActionListener(myListener);
    // tickOnce.addActionListener(myListener);
    // ticksEnabled.addActionListener(myListener);
    log.addActionListener(myListener);
   
    computeEnabled();
  }

  public void localeChanged() {
    this.setText(Strings.get("simulateMenu"));
    run.setText(Strings.get("simulateRunItem"));
    reset.setText(Strings.get("simulateResetItem"));
    step.setText(Strings.get("simulateStepItem"));
    tickOnce.setText(Strings.get("simulateTickOnceItem"));
    ticksEnabled.setText(Strings.get("simulateTickItem"));
    tickFreq.setText(Strings.get("simulateTickFreqMenu"));
    for (int i = 0; i < tickFreqs.length; i++) {
      tickFreqs[i].localeChanged();
    }
    downStateMenu.setText(Strings.get("simulateDownStateMenu"));
    upStateMenu.setText(Strings.get("simulateUpStateMenu"));
    log.setText(Strings.get("simulateLogItem"));
  }
 
  public void setCurrentState(Simulator sim, CircuitState value) {
    if (currentState == value) return;
    Simulator oldSim = currentSim;
    CircuitState oldState = currentState;
    currentSim = sim;
    currentState = value;
    if (bottomState == null) {
      bottomState = currentState;
    } else if (currentState == null) {
      bottomState = null;
    } else {
      CircuitState cur = bottomState;
      while (cur != null && cur != currentState) {
        cur = cur.getParentState();
      }
      if (cur == null) bottomState = currentState;
    }
   
    boolean oldPresent = oldState != null;
    boolean present = currentState != null;
    if (oldPresent != present) {
      computeEnabled();
    }

    if (currentSim != oldSim) {
      double freq = currentSim == null ? 1.0 : currentSim.getTickFrequency();
      for (int i = 0; i < tickFreqs.length; i++) {
        tickFreqs[i].setSelected(Math.abs(tickFreqs[i].freq - freq) < 0.001);
      }

      if (oldSim != null) oldSim.removeSimulatorListener(myListener);
      if (currentSim != null) currentSim.addSimulatorListener(myListener);
      myListener.simulatorStateChanged(new SimulatorEvent(sim));
    }

    clearItems(downStateItems);
    CircuitState cur = bottomState;
    while (cur != null && cur != currentState) {
      downStateItems.add(new CircuitStateMenuItem(cur));
      cur = cur.getParentState();
    }
    if (cur != null) cur = cur.getParentState();
    clearItems(upStateItems);
    while (cur != null) {
      upStateItems.add(0, new CircuitStateMenuItem(cur));
      cur = cur.getParentState();
    }
    recreateStateMenus();
  }
 
  private void clearItems(ArrayList<CircuitStateMenuItem> items) {
    for (CircuitStateMenuItem item : items) {
      item.unregister();
    }
    items.clear();
  }

  private void recreateStateMenus() {
    recreateStateMenu(downStateMenu, downStateItems, KeyEvent.VK_RIGHT);
    recreateStateMenu(upStateMenu, upStateItems, KeyEvent.VK_LEFT);
  }
 
  private void recreateStateMenu(JMenu menu,
      ArrayList<CircuitStateMenuItem> items, int code) {
    menu.removeAll();
    menu.setEnabled(items.size() > 0);
    boolean first = true;
    int mask = getToolkit().getMenuShortcutKeyMask();
    for (int i = items.size() - 1; i >= 0; i--) {
      JMenuItem item = items.get(i);
      menu.add(item);
      if (first) {
        item.setAccelerator(KeyStroke.getKeyStroke(code, mask));
        first = false;
      } else {
        item.setAccelerator(null);
      }
    }
  }

  @Override
  void computeEnabled() {
    boolean present = currentState != null;
    Simulator sim = this.currentSim;
    boolean simRunning = sim != null && sim.isRunning();
    setEnabled(present);
    run.setEnabled(present);
    reset.setEnabled(present);
    step.setEnabled(present && !simRunning);
    upStateMenu.setEnabled(present);
    downStateMenu.setEnabled(present);
    tickOnce.setEnabled(present);
    ticksEnabled.setEnabled(present && simRunning);
    tickFreq.setEnabled(present);
    menubar.fireEnableChanged();
  }
}
TOP

Related Classes of com.cburch.logisim.gui.menu.MenuSimulate$MyListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.