/**
   * Creates a new {@link PlayerStatsChartFactory}.
   *
   * @param chartsComp reference to the charts component that created us
   */
  public PlayerStatsChartFactory(final ChartsComp chartsComp) {
    super(chartsComp);

    statComboBox.addActionListener(chartsComp.chartsRebuilder);
    statComboBox.addActionListener(
        new ActionAdapter(true) {
          @Override
          public void actionPerformed(final ActionEvent event) {
            final boolean hasMinGas = statComboBox.getSelectedItem().hasMinGas;
            minsCheckBox.setVisible(hasMinGas);
            gasCheckBox.setVisible(hasMinGas);
            separateMinsGasCheckBox.setVisible(hasMinGas);
          }
        });
    statComboBox.markSeparatedItems(
        Stat.FOOD_MADE_USED, Stat.ARMY_RES_IN_PROGRESS, Stat.ECON_RES_IN_PROGRESS);
    statComboBox.setMaximumRowCount(statComboBox.getItemCount());

    presentationComboBox.addActionListener(chartsComp.chartsReconfigurer);

    minsCheckBox.setText("Minerals");
    minsCheckBox.setToolTipText(Settings.PLAYER_STATS_INCLUDE_MINS.name);
    minsCheckBox.addActionListener(chartsComp.chartsRebuilder);

    gasCheckBox.setText("Gas");
    gasCheckBox.setToolTipText(Settings.PLAYER_STATS_INCLUDE_GAS.name);
    gasCheckBox.addActionListener(chartsComp.chartsRebuilder);

    separateMinsGasCheckBox.setText("Separate Mins/Gas");
    separateMinsGasCheckBox.setToolTipText(Settings.PLAYER_STATS_SEPARATE_MINS_GAS.name);
    separateMinsGasCheckBox.addActionListener(chartsComp.chartsRebuilder);
  }
Example #2
0
  /**
   * Creates a new {@link BinaryDataComp}.
   *
   * @param repProc replay processor
   */
  public BinaryDataComp(final RepProcessor repProc) {
    super(repProc);

    hexLineSizeComboBox =
        SettingsGui.createSettingComboBox(
            Settings.HEX_LINE_SIZE, Env.APP_SETTINGS, rebuilderListener);

    final Vector<DataSource> sourceVector = new Vector<>();
    final List<DataSource> separatedDsList = new ArrayList<>();

    // The replay file
    sourceVector.add(new FullFileDataSource("Replay File", repProc.file));
    separatedDsList.add(sourceVector.get(sourceVector.size() - 1));
    // General Replay MPQ content
    sourceVector.add(new MpqUserDataDataSource(repProc.file));
    for (final MpqContent mpqContent : MpqContent.VALUES)
      sourceVector.add(new MpqContentDataSource(repProc.file, mpqContent));
    separatedDsList.add(sourceVector.get(sourceVector.size() - 1));
    // Replay content
    for (final RepContent mpqContent : RepContent.VALUES) {
      sourceVector.add(new MpqContentDataSource(repProc.file, mpqContent));
      if (mpqContent == RepContent.TRACKER_EVENTS)
        separatedDsList.add(sourceVector.get(sourceVector.size() - 1));
    }
    separatedDsList.add(sourceVector.get(sourceVector.size() - 1));
    // General Map MPQ content
    final Path mapFile = MapParser.getMapFile(repProc);
    sourceVector.add(new MpqUserDataDataSource(mapFile));
    for (final MpqContent mpqContent : MpqContent.VALUES)
      sourceVector.add(new MpqContentDataSource(mapFile, mpqContent));
    separatedDsList.add(sourceVector.get(sourceVector.size() - 1));
    // Map content
    for (final MapContent mpqContent : MapContent.VALUES)
      sourceVector.add(new MpqContentDataSource(mapFile, mpqContent));

    dataSourceComboBox = new XComboBox<>(sourceVector);
    dataSourceComboBox.markSeparatedItems(separatedDsList);

    searcher =
        new ByteIntPosBaseSearcher() {
          /** Bytes of the search text, as <code>int</code>s. */
          private int[] searchTextBytes;

          @Override
          protected void prepareNew() {
            // Note: Texts found in binary data are usually UTF-8 encoded.
            // This text search converts the searched text to bytes using the same
            // encoding (UTF-8), and this byte sequence will be searched.
            // For more details see the Tips.BINARY_DATA_TEXT_SEARCH tip.
            final byte[] bytes = searchText.getBytes(Env.UTF8);
            searchTextBytes = new int[bytes.length];
            maxOffset = searchTextBytes.length - 1;
            for (int i = maxOffset; i >= 0; i--) searchTextBytes[i] = bytes[i] & 0xff;
            super.prepareNew();
          }

          @Override
          public boolean matches() {
            // Local vars for fast access
            final byte[] data = BinaryDataComp.this.data;
            final int[] searchTextBytes = this.searchTextBytes;
            final int searchPos = this.searchPos;
            if (searchPos + maxOffset > maxPos)
              return false; // Would overflow in data, surely cannot match

            for (int offset = maxOffset; offset >= 0; offset--) {
              final int searchChar = searchTextBytes[offset];
              final int ch = data[searchPos + offset] & 0xff;
              if (ch != searchChar) {
                // Also check in a case insensitive manner (lower-cased version of ch):
                if (ch >= 'A' && ch <= 'Z') {
                  if (ch - ('A' - 'a') != searchChar) return false;
                } else return false;
              }
            }

            // Match!
            handleMatch();
            // Clear the other searcher (so it will start from this line)
            hexSearcher.clearLastSearchPos();

            return true;
          }
        };

    hexSearcher =
        new ByteIntPosBaseSearcher() {
          /** Bytes specified by the hex search text. */
          private byte[] searchTextBytes;

          @Override
          protected void prepareNew() {
            searchTextBytes = Utils.hexToBytes(searchText);
            if (searchTextBytes == null) searchTextBytes = new byte[0];
            maxOffset = searchTextBytes.length - 1;
            super.prepareNew();
          }

          @Override
          public boolean matches() {
            if (searchTextBytes.length == 0) return true; // To end the search
            // Local vars for fast access
            final byte[] data = BinaryDataComp.this.data;
            final byte[] searchTextBytes = this.searchTextBytes;
            final int searchPos = this.searchPos;
            if (searchPos + maxOffset > maxPos)
              return false; // Would overflow in data, surely cannot match

            for (int offset = maxOffset; offset >= 0; offset--)
              if (searchTextBytes[offset] != data[searchPos + offset]) return false;

            // Match!
            handleMatch();
            // Clear the other searcher (so it will start from this line)
            searcher.clearLastSearchPos();

            return true;
          }
        };

    buildGui();
  }