/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tools.idea.editors.allocations;
import com.android.annotations.Nullable;
import com.android.ddmlib.AllocationInfo;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.ui.TableSpeedSearch;
import com.intellij.ui.table.BaseTableView;
import com.intellij.ui.table.JBTable;
import com.intellij.util.config.Storage;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import java.awt.*;
public class AllocationsTableUtil {
enum Column {
ALLOCATION_ORDER("Allocation Order", 0),
ALLOCATED_CLASS("Allocated Class", "com.sample.data.AllocatedClass"),
ALLOCATION_SIZE("Allocation Size", 0),
THREAD_ID("Thread Id", 0),
ALLOCATION_SITE("Allocation Site", "com.sample.data.AllocationSite.method(AllocationSite.java:000)");
public final String description;
public final Object sampleData;
Column(String description, Object sampleData) {
this.description = description;
this.sampleData = sampleData;
}
}
public static void setUpTable(@Nullable final Storage.PropertiesComponentStorage storage, @NotNull final JBTable allocationsTable,
@Nullable ConsoleView consoleView) {
// Allows multiple selection (some users want to copy/paste the whole table into a spreadsheet)
allocationsTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
new TableSpeedSearch(allocationsTable) {
@Override
public int getElementCount() {
return myComponent.getRowCount() * myComponent.getColumnCount();
}
};
allocationsTable.getSelectionModel().addListSelectionListener(new AllocationsRowListener(allocationsTable, consoleView));
allocationsTable.setModel(new AllocationsTableModel(new AllocationInfo[]{}));
allocationsTable.setRowSorter(new AllocationsRowSorter(allocationsTable.getModel()));
if (storage != null) {
if (storage.get("widthsSet") == null) {
storage.put("widthsSet", Boolean.toString(true));
setDefaultColumnWidths(allocationsTable);
BaseTableView.storeWidth(storage, allocationsTable.getColumnModel());
}
BaseTableView.restore(storage, allocationsTable);
allocationsTable.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
@Override
public void columnAdded(TableColumnModelEvent e) {
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
}
@Override
public void columnMoved(TableColumnModelEvent e) {
BaseTableView.store(storage, allocationsTable);
}
@Override
public void columnMarginChanged(ChangeEvent e) {
BaseTableView.storeWidth(storage, allocationsTable.getColumnModel());
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
});
}
}
private static void setDefaultColumnWidths(@NotNull JBTable allocationsTable) {
Column[] columns = Column.values();
int cumulativeWidth = 0;
int[] defaultWidths = new int[columns.length];
FontMetrics metrics = allocationsTable.getFontMetrics(allocationsTable.getFont());
for (Column column : columns) {
// Multiples width by ~1.5 so text is not right against column sides
int columnWidth = 3 * Math.max(metrics.stringWidth(column.description), metrics.stringWidth(String.valueOf(column.sampleData))) / 2;
defaultWidths[column.ordinal()] = columnWidth;
if (column != Column.ALLOCATION_SITE) {
cumulativeWidth += columnWidth;
}
}
// If possible, uses remaining width, which makes the table respect the preferred column widths exactly.
int remainingWidth = allocationsTable.getWidth() - cumulativeWidth;
if (remainingWidth > 0) {
defaultWidths[Column.ALLOCATION_SITE.ordinal()] = remainingWidth;
}
for (Column column : columns) {
allocationsTable.getColumn(column.description).setPreferredWidth(defaultWidths[column.ordinal()]);
}
}
}