From 318eadddbcec0cf2e3bc94ffc81fc55bab08d07a Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 11 Apr 2012 11:34:16 +0200 Subject: [PATCH] multi column list --- .../ui/components/FixedColumnsModel.java | 47 +++++ .../ui/components/FixedRowsModel.java | 47 +++++ .../ui/components/MultiColumnList.java | 162 ++++++++++++++++++ .../ui/components/MultiColumnListModel.java | 47 +++++ 4 files changed, 303 insertions(+) create mode 100644 platform/platform-api/src/com/intellij/ui/components/FixedColumnsModel.java create mode 100644 platform/platform-api/src/com/intellij/ui/components/FixedRowsModel.java create mode 100644 platform/platform-api/src/com/intellij/ui/components/MultiColumnList.java create mode 100644 platform/platform-api/src/com/intellij/ui/components/MultiColumnListModel.java diff --git a/platform/platform-api/src/com/intellij/ui/components/FixedColumnsModel.java b/platform/platform-api/src/com/intellij/ui/components/FixedColumnsModel.java new file mode 100644 index 000000000000..dda70558e03b --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/components/FixedColumnsModel.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * 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.intellij.ui.components; + +import javax.swing.*; + +/** + * @author Konstantin Bulenkov + */ +public class FixedColumnsModel extends MultiColumnListModel { + private final int myMaxColumns; + + public FixedColumnsModel(ListModel model, int maxColumns) { + super(model); + myMaxColumns = maxColumns; + } + + @Override + public int getRowCount() { + final int columns = getColumnCount(); + return columns == 0 ? 0 : getSize() / columns + 1; + } + + @Override + public int getColumnCount() { + return Math.min(myMaxColumns, getSize()); + } + + @Override + public int toListIndex(int row, int column) { + final int columns = getColumnCount(); + return columns == 0 ? -1 : row * columns + column; + } +} diff --git a/platform/platform-api/src/com/intellij/ui/components/FixedRowsModel.java b/platform/platform-api/src/com/intellij/ui/components/FixedRowsModel.java new file mode 100644 index 000000000000..45043e514c89 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/components/FixedRowsModel.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * 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.intellij.ui.components; + +import javax.swing.*; + +/** +* @author Konstantin Bulenkov +*/ +class FixedRowsModel extends MultiColumnListModel { + private final int myMaxRows; + + public FixedRowsModel(ListModel model, int rows) { + super(model); + myMaxRows = rows; + } + + @Override + public int getRowCount() { + return Math.min(myMaxRows, getSize()); + } + + @Override + public int getColumnCount() { + final int rows = getRowCount(); + return rows == 0 ? 0 : getSize() / rows + 1; + } + + @Override + public int toListIndex(int row, int column) { + final int rows = getRowCount(); + return rows == 0 ? -1 : column * rows + row; + } +} diff --git a/platform/platform-api/src/com/intellij/ui/components/MultiColumnList.java b/platform/platform-api/src/com/intellij/ui/components/MultiColumnList.java new file mode 100644 index 000000000000..82a7fef7a469 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/components/MultiColumnList.java @@ -0,0 +1,162 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * 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.intellij.ui.components; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.table.TableCellRenderer; +import java.awt.*; + +/** + * @author Konstantin Bulenkov + */ +public class MultiColumnList extends JTable { + private final ListModel myModel; + private ListCellRenderer myRenderer; + private JList myList; + private Dimension myPrefSize; + + public MultiColumnList(ListModel model) { + super(new FixedRowsModel(model, 25)); + myModel = model; + setRowHeight(20); + setShowGrid(false); + setCellSelectionEnabled(true); + setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + //noinspection UndesirableClassUsage + myList = new JList(model) { + @Override + public void setBorder(Border border) { + super.setBorder(border); + MultiColumnList.this.setBorder(border); + } + + @Override + public void repaint() { + MultiColumnList.this.repaint(); + } + + @Override + public void setCellRenderer(ListCellRenderer cellRenderer) { + super.setCellRenderer(cellRenderer); + if (myRenderer != cellRenderer) { + MultiColumnList.this.setCellRenderer(cellRenderer); + } + } + }; + getColumnModel().setColumnMargin(0); + } + + public MultiColumnList(Object...elements) { + this(createListModel(elements)); + } + + private static ListModel createListModel(Object...elements) { + final DefaultListModel model = new DefaultListModel(); + for (Object element : elements) { + model.addElement(element); + } + + return model; + } + + public void setCellRenderer(ListCellRenderer renderer) { + myRenderer = renderer; + setDefaultRenderer(Object.class, new TableCellRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + final int index = getModel().toListIndex(row, column); + if (isSelected) { + myList.addSelectionInterval(index, index); + } else { + myList.removeSelectionInterval(index, index); + } + return myRenderer.getListCellRendererComponent(myList, value, index, isSelected, hasFocus); + } + }); + } + + public void setFixedRowsMode(int maxRows) { + if (maxRows < 1) { + throw new IllegalArgumentException("Should be greater than 0"); + } + + setModel(new FixedRowsModel(myModel, maxRows)); + getModel().fireTableStructureChanged(); + } + + @Override + public MultiColumnListModel getModel() { + return (MultiColumnListModel)super.getModel(); + } + + public void setFixedColumnsMode(int maxColumns) { + if (maxColumns < 1) { + throw new IllegalArgumentException("Should be greater than 0"); + } + + setModel(new FixedColumnsModel(myModel, maxColumns)); + getModel().fireTableStructureChanged(); + } + + public JList getDelegate() { + return myList; + } + + @Override + public Dimension getPreferredSize() { + if (myPrefSize == null) { + Dimension dimension = new Dimension(); + int rowHeight = 0; + for (int column = 0; column < getColumnCount(); column++) { + int columnWidth = 0; + for (int row = 0; row < getRowCount(); row++) { + final TableCellRenderer renderer = getCellRenderer(row, column); + if (renderer != null) { + final Object value = getValueAt(row, column); + final Component component = renderer.getTableCellRendererComponent(this, value, true, true, row, column); + if (component != null) { + final Dimension size = component.getPreferredSize(); + rowHeight = Math.max(size.height, rowHeight); + columnWidth = Math.max(size.width, columnWidth); + } + } + } + getColumnModel().getColumn(column).setWidth(columnWidth + 5); + dimension.width += columnWidth + 5; + } + dimension.height = getRowCount() * rowHeight; + myPrefSize = dimension; + } + return myPrefSize; + } + + public static void main(String[] args) { + final JFrame frame = new JFrame("Test"); + frame.setSize(300, 300); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + final MultiColumnList list = new MultiColumnList("1", 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13); + list.setFixedColumnsMode(5); + frame.getContentPane().add(list); + frame.setVisible(true); + } +} diff --git a/platform/platform-api/src/com/intellij/ui/components/MultiColumnListModel.java b/platform/platform-api/src/com/intellij/ui/components/MultiColumnListModel.java new file mode 100644 index 000000000000..a3189213d09a --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/components/MultiColumnListModel.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * 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.intellij.ui.components; + +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableModel; + +/** + * @author Konstantin Bulenkov + */ +public abstract class MultiColumnListModel extends AbstractTableModel implements TableModel { + private final ListModel myModel; + + public MultiColumnListModel(ListModel model) { + myModel = model; + } + + public abstract int toListIndex(int row, int column); + + public int getSize() { + return myModel.getSize(); + } + + @Nullable + @Override + public Object getValueAt(int row, int column) { + final int index = toListIndex(row, column); + return index == -1 || index >= myModel.getSize() ? null + : myModel.getElementAt(index); + } +}