You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by no...@apache.org on 2009/11/13 12:01:03 UTC
svn commit: r835809 - in /incubator/pivot/trunk/wtk:
src/org/apache/pivot/wtk/ src/org/apache/pivot/wtk/skin/
src/org/apache/pivot/wtk/skin/terra/ test/org/apache/pivot/wtk/test/
Author: noelgrandin
Date: Fri Nov 13 11:01:02 2009
New Revision: 835809
URL: http://svn.apache.org/viewvc?rev=835809&view=rev
Log:
PIVOT-227 Add a GridPane container
Added:
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/GridPane.java
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/GridPaneListener.java
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/GridPaneFillerSkin.java
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/GridPaneSkin.java
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraGridPaneSkin.java
incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/GridPaneTest.java
incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/gridpane_test.wtkx
Modified:
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Theme.java
incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraTheme.java
Added: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/GridPane.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/GridPane.java?rev=835809&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/GridPane.java (added)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/GridPane.java Fri Nov 13 11:01:02 2009
@@ -0,0 +1,768 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 org.apache.pivot.wtk;
+
+import java.util.Iterator;
+
+import org.apache.pivot.collections.ArrayList;
+import org.apache.pivot.collections.Sequence;
+import org.apache.pivot.util.ImmutableIterator;
+import org.apache.pivot.util.ListenerList;
+
+
+/**
+ * Container that arranges components in a two-dimensional grid, where every cell is the same size.
+ */
+public class GridPane extends Container {
+ /**
+ * Represents a grid pane row.
+ */
+ public static final class Row implements Sequence<Component>, Iterable<Component> {
+ private boolean highlighted;
+
+ private ArrayList<Component> cells = new ArrayList<Component>();
+
+ private GridPane gridPane = null;
+
+ public Row() {
+ this(false);
+ }
+
+ public Row(boolean highlighted) {
+ this.highlighted = highlighted;
+ }
+
+ /**
+ * Returns the grid pane with which this row is associated.
+ *
+ * @return
+ * The row's grid pane, or <tt>null</tt> if the row does not
+ * currently belong to a grid.
+ */
+ public GridPane getGridPane() {
+ return gridPane;
+ }
+
+ /**
+ * Sets the grid pane with which this row is associated.
+ *
+ * @param gridPane
+ * The row's grid pane, or <tt>null</tt> if the row does not
+ * currently belong to a grid.
+ */
+ private void setGridPane(GridPane gridPane) {
+ this.gridPane = gridPane;
+ }
+
+ /**
+ * Returns the highlighted flag.
+ *
+ * @return
+ * <tt>true</tt> if the row is highlighted, <tt>false</tt> if it is not
+ */
+ public boolean isHighlighted() {
+ return highlighted;
+ }
+
+ /**
+ * Sets the highlighted flag.
+ *
+ * @param highlighted
+ * <tt>true</tt> to set the row as highlighted, <tt>false</tt> to set
+ * it as not highlighted
+ */
+ public void setHighlighted(boolean highlighted) {
+ if (highlighted != this.highlighted) {
+ this.highlighted = highlighted;
+
+ if (gridPane != null) {
+ gridPane.gridPaneListeners.rowHighlightedChanged(this);
+ }
+ }
+ }
+
+ /**
+ * Sets the visible flag for all components in the row.
+ * <p>
+ * This is a convenience method that iterates through the row, calling
+ * <tt>setVisible</tt> on all components.
+ */
+ public void setVisible(boolean visible) {
+ if (gridPane != null) {
+ for (Component component : cells) {
+ component.setVisible(visible);
+ }
+ }
+ }
+
+ @Override
+ public int add(Component component) {
+ int i = getLength();
+ insert(component, i);
+
+ return i;
+ }
+
+ @Override
+ public void insert(Component component, int index) {
+ if (component == null) {
+ throw new IllegalArgumentException("Component is null.");
+ }
+
+ if (component.getParent() != null) {
+ throw new IllegalArgumentException("Component already has a parent.");
+ }
+
+ cells.insert(component, index);
+
+ if (gridPane != null) {
+ gridPane.add(component);
+ gridPane.gridPaneListeners.cellInserted(this, index);
+ }
+ }
+
+ @Override
+ public Component update(int index, Component component) {
+ Component previousComponent = cells.get(index);
+
+ if (component != previousComponent) {
+ if (component == null) {
+ throw new IllegalArgumentException("Component is null.");
+ }
+
+ if (component.getParent() != null) {
+ throw new IllegalArgumentException("Component already has a parent.");
+ }
+
+ cells.update(index, component);
+ previousComponent.setAttributes(null);
+
+ if (gridPane != null) {
+ gridPane.add(component);
+ gridPane.gridPaneListeners.cellUpdated(this, index, previousComponent);
+ gridPane.remove(previousComponent);
+ }
+ }
+
+ return previousComponent;
+ }
+
+ @Override
+ public int remove(Component component) {
+ int index = indexOf(component);
+ if (index != -1) {
+ remove(index, 1);
+ }
+
+ return index;
+ }
+
+ @Override
+ public Sequence<Component> remove(int index, int count) {
+ Sequence<Component> removed = cells.remove(index, count);
+
+ for (int i = 0, n = removed.getLength(); i < n; i++) {
+ Component component = removed.get(i);
+ component.setAttributes(null);
+ }
+
+ if (gridPane != null) {
+ gridPane.gridPaneListeners.cellsRemoved(this, index, removed);
+
+ for (int i = 0, n = removed.getLength(); i < n; i++) {
+ Component component = removed.get(i);
+ gridPane.remove(component);
+ }
+ }
+
+ return removed;
+ }
+
+ @Override
+ public Component get(int index) {
+ return cells.get(index);
+ }
+
+ @Override
+ public int indexOf(Component component) {
+ return cells.indexOf(component);
+ }
+
+ @Override
+ public int getLength() {
+ return cells.getLength();
+ }
+
+ @Override
+ public Iterator<Component> iterator() {
+ return new ImmutableIterator<Component>(cells.iterator());
+ }
+ }
+
+ /**
+ * Represents a grid pane column.
+ */
+ public static class Column {
+ private GridPane gridPane = null;
+
+ private boolean highlighted;
+
+ public Column() {
+ this(false);
+ }
+
+ public Column(boolean highlighted) {
+ this.highlighted = highlighted;
+ }
+
+ /**
+ * Returns the grid pane with which this column is associated.
+ *
+ * @return
+ * The column's grid pane, or <tt>null</tt> if the column does not
+ * currently belong to a grid.
+ */
+ public GridPane getGridPane() {
+ return gridPane;
+ }
+
+ /**
+ * Sets the grid pane with which this column is associated.
+ *
+ * @param gridPane
+ * The column's grid pane, or <tt>null</tt> if the column does not
+ * currently belong to a grid.
+ */
+ private void setGridPane(GridPane gridPane) {
+ this.gridPane = gridPane;
+ }
+
+ /**
+ * Returns the highlighted flag.
+ *
+ * @return
+ * <tt>true</tt> if the column is highlighted, <tt>false</tt> if it is not
+ */
+ public boolean isHighlighted() {
+ return highlighted;
+ }
+
+ /**
+ * Sets the highlighted flag.
+ *
+ * @param highlighted
+ * <tt>true</tt> to set the column as highlighted, <tt>false</tt> to set
+ * it as not highlighted
+ */
+ public void setHighlighted(boolean highlighted) {
+ if (highlighted != this.highlighted) {
+ this.highlighted = highlighted;
+
+ if (gridPane != null) {
+ gridPane.gridPaneListeners.columnHighlightedChanged(this);
+ }
+ }
+ }
+
+ /**
+ * Sets the visible flag for all components in the column.
+ * <p>
+ * This is a convenience method that iterates through the components in
+ * the column, calling <tt>setVisible</tt> on all such components.
+ */
+ public void setVisible(boolean visible) {
+ if (gridPane != null) {
+ int columnIndex = gridPane.columns.indexOf(this);
+
+ for (Row row : gridPane.rows) {
+ if (row.getLength() > columnIndex) {
+ row.get(columnIndex).setVisible(visible);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * grid pane skin interface. grid pane skins must implement
+ * this interface to facilitate additional communication between the
+ * component and the skin.
+ */
+ public interface Skin {
+ public int getRowAt(int y);
+ public Bounds getRowBounds(int row);
+ public int getColumnAt(int x);
+ public Bounds getColumnBounds(int column);
+ }
+
+ /**
+ * Class that manages a grid pane's row list. Callers get access to the
+ * row sequence via {@link GridPane#getRows()}.
+ */
+ public final class RowSequence implements Sequence<Row>, Iterable<Row> {
+ private RowSequence() {
+ }
+
+ @Override
+ public int add(Row row) {
+ int i = getLength();
+ insert(row, i);
+
+ return i;
+ }
+
+ @Override
+ public void insert(Row row, int index) {
+ if (row == null) {
+ throw new IllegalArgumentException("row is null.");
+ }
+
+ if (row.getGridPane() != null) {
+ throw new IllegalArgumentException
+ ("row is already in use by another grid pane.");
+ }
+
+ rows.insert(row, index);
+ row.setGridPane(GridPane.this);
+
+ for (int i = 0, n = row.getLength(); i < n; i++) {
+ Component component = row.get(i);
+ GridPane.this.add(component);
+ }
+
+ // Notify listeners
+ gridPaneListeners.rowInserted(GridPane.this, index);
+ }
+
+ @Override
+ public Row update(int index, Row row) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int remove(Row row) {
+ int index = indexOf(row);
+ if (index != -1) {
+ remove(index, 1);
+ }
+
+ return index;
+ }
+
+ @Override
+ public Sequence<Row> remove(int index, int count) {
+ Sequence<Row> removed = rows.remove(index, count);
+
+ if (count > 0) {
+ for (int i = 0, n = removed.getLength(); i < n; i++) {
+ Row row = removed.get(i);
+ row.setGridPane(null);
+
+ for (int j = 0, m = row.getLength(); j < m; j++) {
+ Component component = row.get(j);
+ GridPane.this.remove(component);
+ }
+ }
+
+ gridPaneListeners.rowsRemoved(GridPane.this, index, removed);
+ }
+
+ return removed;
+ }
+
+ @Override
+ public Row get(int index) {
+ return rows.get(index);
+ }
+
+ @Override
+ public int indexOf(Row row) {
+ return rows.indexOf(row);
+ }
+
+ @Override
+ public int getLength() {
+ return rows.getLength();
+ }
+
+ @Override
+ public Iterator<Row> iterator() {
+ return new ImmutableIterator<Row>(rows.iterator());
+ }
+ }
+
+ /**
+ * Class that manages a grid pane's column list. Callers get access to the
+ * column sequence via {@link GridPane#getColumns()}.
+ */
+ public final class ColumnSequence implements Sequence<Column>, Iterable<Column> {
+ private ColumnSequence() {
+ }
+
+ @Override
+ public int add(Column column) {
+ int i = getLength();
+ insert(column, i);
+
+ return i;
+ }
+
+ @Override
+ public void insert(Column column, int index) {
+ if (column == null) {
+ throw new IllegalArgumentException("column is null.");
+ }
+
+ if (column.getGridPane() != null) {
+ throw new IllegalArgumentException
+ ("column is already in use by another grid pane.");
+ }
+
+ columns.insert(column, index);
+ column.setGridPane(GridPane.this);
+
+ // Notify listeners
+ gridPaneListeners.columnInserted(GridPane.this, index);
+ }
+
+ @Override
+ public Column update(int index, Column column) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int remove(Column column) {
+ int index = indexOf(column);
+ if (index != -1) {
+ remove(index, 1);
+ }
+
+ return index;
+ }
+
+ @Override
+ public Sequence<Column> remove(int index, int count) {
+ Sequence<Column> removed = columns.remove(index, count);
+
+ if (count > 0) {
+ for (int i = 0, n = removed.getLength(); i < n; i++) {
+ Column column = removed.get(i);
+ column.setGridPane(null);
+ }
+
+ gridPaneListeners.columnsRemoved(GridPane.this, index, removed);
+ }
+
+ return removed;
+ }
+
+ @Override
+ public Column get(int index) {
+ return columns.get(index);
+ }
+
+ @Override
+ public int indexOf(Column column) {
+ return columns.indexOf(column);
+ }
+
+ @Override
+ public int getLength() {
+ return columns.getLength();
+ }
+
+ @Override
+ public Iterator<Column> iterator() {
+ return new ImmutableIterator<Column>(columns.iterator());
+ }
+ }
+
+ /**
+ * Component that can be used as filler for empty cells.
+ */
+ public static class Filler extends Component {
+ public Filler() {
+ installThemeSkin(Filler.class);
+ }
+ }
+
+ private static class GridPaneListenerList extends ListenerList<GridPaneListener>
+ implements GridPaneListener {
+ @Override
+ public void rowInserted(GridPane gridPane, int index) {
+ for (GridPaneListener listener : this) {
+ listener.rowInserted(gridPane, index);
+ }
+ }
+
+ @Override
+ public void rowsRemoved(GridPane gridPane, int index,
+ Sequence<GridPane.Row> rows) {
+ for (GridPaneListener listener : this) {
+ listener.rowsRemoved(gridPane, index, rows);
+ }
+ }
+
+ @Override
+ public void rowHighlightedChanged(GridPane.Row row) {
+ for (GridPaneListener listener : this) {
+ listener.rowHighlightedChanged(row);
+ }
+ }
+
+ @Override
+ public void columnInserted(GridPane gridPane, int index) {
+ for (GridPaneListener listener : this) {
+ listener.columnInserted(gridPane, index);
+ }
+ }
+
+ @Override
+ public void columnsRemoved(GridPane gridPane, int index,
+ Sequence<GridPane.Column> columns) {
+ for (GridPaneListener listener : this) {
+ listener.columnsRemoved(gridPane, index, columns);
+ }
+ }
+
+ @Override
+ public void columnHighlightedChanged(GridPane.Column column) {
+ for (GridPaneListener listener : this) {
+ listener.columnHighlightedChanged(column);
+ }
+ }
+
+ @Override
+ public void cellInserted(GridPane.Row row, int column) {
+ for (GridPaneListener listener : this) {
+ listener.cellInserted(row, column);
+ }
+ }
+
+ @Override
+ public void cellsRemoved(GridPane.Row row, int column,
+ Sequence<Component> removed) {
+ for (GridPaneListener listener : this) {
+ listener.cellsRemoved(row, column, removed);
+ }
+ }
+
+ @Override
+ public void cellUpdated(GridPane.Row row, int column,
+ Component previousComponent) {
+ for (GridPaneListener listener : this) {
+ listener.cellUpdated(row, column, previousComponent);
+ }
+ }
+ }
+
+ private ArrayList<Row> rows = null;
+ private RowSequence rowSequence = new RowSequence();
+
+ private ArrayList<Column> columns = null;
+ private ColumnSequence columnSequence = new ColumnSequence();
+
+ private GridPaneListenerList gridPaneListeners = new GridPaneListenerList();
+
+ public static final String RELATIVE_SIZE_INDICATOR = "*";
+
+ /**
+ * Creates a new <tt>GridPane</tt> with empty row and column sequences.
+ */
+ public GridPane() {
+ this(new ArrayList<Column>());
+ }
+
+ /**
+ * Creates a new <tt>GridPane</tt> with the specified columns.
+ *
+ * @param columns
+ * The column sequence to use. A copy of this sequence will be made
+ */
+ public GridPane(Sequence<Column> columns) {
+ if (columns == null) {
+ throw new IllegalArgumentException("columns is null");
+ }
+
+ this.rows = new ArrayList<Row>();
+ this.columns = new ArrayList<Column>(columns);
+
+ installThemeSkin(GridPane.class);
+ }
+
+ @Override
+ protected void setSkin(org.apache.pivot.wtk.Skin skin) {
+ if (!(skin instanceof GridPane.Skin)) {
+ throw new IllegalArgumentException("Skin class must implement "
+ + GridPane.Skin.class.getName());
+ }
+
+ super.setSkin(skin);
+ }
+
+ /**
+ * Returns the grid pane row sequence.
+ *
+ * @return
+ * The grid pane row sequence
+ */
+ public RowSequence getRows() {
+ return rowSequence;
+ }
+
+ /**
+ * Returns the index of the row at a given location.
+ *
+ * @param y
+ * The y-coordinate of the row to identify.
+ *
+ * @return
+ * The row index, or <tt>-1</tt> if there is no row at the given
+ * y-coordinate.
+ */
+ public int getRowAt(int y) {
+ GridPane.Skin gridPaneSkin = (GridPane.Skin)getSkin();
+ return gridPaneSkin.getRowAt(y);
+ }
+
+ /**
+ * Returns the bounds of a given row.
+ *
+ * @param row
+ * The row index.
+ */
+ public Bounds getRowBounds(int row) {
+ GridPane.Skin gridPaneSkin = (GridPane.Skin)getSkin();
+ return gridPaneSkin.getRowBounds(row);
+ }
+
+ /**
+ * Returns the grid pane column sequence.
+ *
+ * @return
+ * The grid pane column sequence
+ */
+ public ColumnSequence getColumns() {
+ return columnSequence;
+ }
+
+ /**
+ * Returns the index of the column at a given location.
+ *
+ * @param x
+ * The x-coordinate of the column to identify.
+ *
+ * @return
+ * The column index, or <tt>-1</tt> if there is no column at the given
+ * x-coordinate.
+ */
+ public int getColumnAt(int x) {
+ GridPane.Skin gridPaneSkin = (GridPane.Skin)getSkin();
+ return gridPaneSkin.getColumnAt(x);
+ }
+
+ /**
+ * Returns the bounds of a given column.
+ *
+ * @param column
+ * The column index.
+ */
+ public Bounds getColumnBounds(int column) {
+ GridPane.Skin gridPaneSkin = (GridPane.Skin)getSkin();
+ return gridPaneSkin.getColumnBounds(column);
+ }
+
+ /**
+ * Gets the component at the specified cell in this grid pane.
+ *
+ * @param rowIndex
+ * The row index of the cell
+ *
+ * @param columnIndex
+ * The column index of the cell
+ *
+ * @return
+ * The component in the specified cell, or <tt>null</tt> if the cell is
+ * empty
+ */
+ public Component getCellComponent(int rowIndex, int columnIndex) {
+ Row row = rows.get(rowIndex);
+
+ Component component = null;
+
+ if (row.getLength() > columnIndex) {
+ component = row.get(columnIndex);
+ }
+
+ return component;
+ }
+
+ /**
+ * Sets the component at the specified cell in this grid pane.
+ *
+ * @param row
+ * The row index of the cell
+ *
+ * @param column
+ * The column index of the cell
+ *
+ * @param component
+ * The component to place in the specified cell, or <tt>null</tt> to empty
+ * the cell
+ */
+ public void setCellComponent(int row, int column, Component component) {
+ rows.get(row).update(column, component);
+ }
+
+ /**
+ * Overrides the base method to check whether or not a cell component is
+ * being removed, and fires the appropriate event in that case.
+ *
+ * @param index
+ * The index at which components were removed
+ *
+ * @param count
+ * The number of components removed
+ *
+ * @return
+ * The sequence of components that were removed
+ */
+ @Override
+ public Sequence<Component> remove(int index, int count) {
+ for (int i = index, n = index + count; i < n; i++) {
+ Component component = get(i);
+
+ for (Row row : rows) {
+ if (row.indexOf(component) >= 0) {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ // Call the base method to remove the components
+ return super.remove(index, count);
+ }
+
+ /**
+ * Returns the grid pane listener list.
+ */
+ public ListenerList<GridPaneListener> getGridPaneListeners() {
+ return gridPaneListeners;
+ }
+
+
+}
Added: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/GridPaneListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/GridPaneListener.java?rev=835809&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/GridPaneListener.java (added)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/GridPaneListener.java Fri Nov 13 11:01:02 2009
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 org.apache.pivot.wtk;
+
+import org.apache.pivot.collections.Sequence;
+
+/**
+ * Table pane listener interface.
+ */
+public interface GridPaneListener {
+ /**
+ * Table pane listener adapter.
+ */
+ public static class Adapter implements GridPaneListener {
+ @Override
+ public void rowInserted(GridPane GridPane, int index) {
+ }
+
+ @Override
+ public void rowsRemoved(GridPane GridPane, int index,
+ Sequence<GridPane.Row> rows) {
+ }
+
+ @Override
+ public void rowHighlightedChanged(GridPane.Row row) {
+ }
+
+ @Override
+ public void columnInserted(GridPane GridPane, int index) {
+ }
+
+ @Override
+ public void columnsRemoved(GridPane GridPane, int index,
+ Sequence<GridPane.Column> columns) {
+ }
+
+ @Override
+ public void columnHighlightedChanged(GridPane.Column column) {
+ }
+
+ @Override
+ public void cellInserted(GridPane.Row row, int column) {
+ }
+
+ @Override
+ public void cellsRemoved(GridPane.Row row, int column,
+ Sequence<Component> removed) {
+ }
+
+ @Override
+ public void cellUpdated(GridPane.Row row, int column,
+ Component previousComponent) {
+ }
+ }
+
+ /**
+ * Called when a row has been inserted into a table pane.
+ *
+ * @param GridPane
+ * @param index
+ */
+ public void rowInserted(GridPane GridPane, int index);
+
+ /**
+ * Called when rows have been removed from a table pane.
+ *
+ * @param GridPane
+ * @param index
+ * @param rows
+ */
+ public void rowsRemoved(GridPane GridPane, int index,
+ Sequence<GridPane.Row> rows);
+
+ /**
+ * Called when a row's highlighted state has changed.
+ *
+ * @param row
+ */
+ public void rowHighlightedChanged(GridPane.Row row);
+
+ /**
+ * Called when a column has been inserted into a table pane.
+ *
+ * @param GridPane
+ * @param index
+ */
+ public void columnInserted(GridPane GridPane, int index);
+
+ /**
+ * Called when column's have been removed from a table pane.
+ *
+ * @param GridPane
+ * @param index
+ * @param columns
+ */
+ public void columnsRemoved(GridPane GridPane, int index,
+ Sequence<GridPane.Column> columns);
+
+ /**
+ * Called when a column's highlighted state has changed.
+ *
+ * @param column
+ */
+ public void columnHighlightedChanged(GridPane.Column column);
+
+ /**
+ * Called when a cell has been inserted into a table pane.
+ *
+ * @param row
+ * @param column
+ */
+ public void cellInserted(GridPane.Row row, int column);
+
+ /**
+ * Called when cell's have been removed from a table pane.
+ *
+ * @param row
+ * @param column
+ * @param removed
+ */
+ public void cellsRemoved(GridPane.Row row, int column,
+ Sequence<Component> removed);
+
+ /**
+ * Called when a cell has been updated in a table pane.
+ *
+ * @param row
+ * @param column
+ * @param previousComponent
+ */
+ public void cellUpdated(GridPane.Row row, int column,
+ Component previousComponent);
+}
Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Theme.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Theme.java?rev=835809&r1=835808&r2=835809&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Theme.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/Theme.java Fri Nov 13 11:01:02 2009
@@ -23,10 +23,12 @@
import org.apache.pivot.util.Service;
import org.apache.pivot.wtk.media.Image;
import org.apache.pivot.wtk.skin.BorderSkin;
+import org.apache.pivot.wtk.skin.BoxPaneSkin;
import org.apache.pivot.wtk.skin.CardPaneSkin;
import org.apache.pivot.wtk.skin.ColorChooserButtonSkin;
-import org.apache.pivot.wtk.skin.BoxPaneSkin;
import org.apache.pivot.wtk.skin.FlowPaneSkin;
+import org.apache.pivot.wtk.skin.GridPaneFillerSkin;
+import org.apache.pivot.wtk.skin.GridPaneSkin;
import org.apache.pivot.wtk.skin.ImageViewSkin;
import org.apache.pivot.wtk.skin.LabelSkin;
import org.apache.pivot.wtk.skin.MovieViewSkin;
@@ -83,6 +85,8 @@
componentSkinMap.put(ColorChooserButtonSkin.ColorChooserPopup.class,
ColorChooserButtonSkin.ColorChooserPopupSkin.class);
componentSkinMap.put(FlowPane.class, FlowPaneSkin.class);
+ componentSkinMap.put(GridPane.class, GridPaneSkin.class);
+ componentSkinMap.put(GridPane.Filler.class, GridPaneFillerSkin.class);
componentSkinMap.put(ImageView.class, ImageViewSkin.class);
componentSkinMap.put(Label.class, LabelSkin.class);
componentSkinMap.put(MovieView.class, MovieViewSkin.class);
Added: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/GridPaneFillerSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/GridPaneFillerSkin.java?rev=835809&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/GridPaneFillerSkin.java (added)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/GridPaneFillerSkin.java Fri Nov 13 11:01:02 2009
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 org.apache.pivot.wtk.skin;
+
+import java.awt.Graphics2D;
+
+/**
+ * Grid pane filler skin.
+ */
+public class GridPaneFillerSkin extends ComponentSkin {
+ @Override
+ public boolean isFocusable() {
+ return false;
+ }
+
+ @Override
+ public boolean isOpaque() {
+ return false;
+ }
+
+ @Override
+ public void layout() {
+ // No-op
+ }
+
+ @Override
+ public int getPreferredHeight(int width) {
+ return 0;
+ }
+
+ @Override
+ public int getPreferredWidth(int height) {
+ return 0;
+ }
+
+ @Override
+ public void paint(Graphics2D graphics) {
+ }
+}
Added: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/GridPaneSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/GridPaneSkin.java?rev=835809&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/GridPaneSkin.java (added)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/GridPaneSkin.java Fri Nov 13 11:01:02 2009
@@ -0,0 +1,828 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 org.apache.pivot.wtk.skin;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+
+import org.apache.pivot.collections.Dictionary;
+import org.apache.pivot.collections.Sequence;
+import org.apache.pivot.wtk.Bounds;
+import org.apache.pivot.wtk.Component;
+import org.apache.pivot.wtk.Dimensions;
+import org.apache.pivot.wtk.GraphicsUtilities;
+import org.apache.pivot.wtk.GridPane;
+import org.apache.pivot.wtk.GridPaneListener;
+import org.apache.pivot.wtk.Insets;
+import org.apache.pivot.wtk.Orientation;
+
+/**
+ * Grid pane skin.
+ */
+public class GridPaneSkin extends ContainerSkin implements GridPane.Skin,
+ GridPaneListener {
+ private Insets padding = Insets.NONE;
+ private int horizontalSpacing = 0;
+ private int verticalSpacing = 0;
+ private boolean showHorizontalGridLines = false;
+ private boolean showVerticalGridLines = false;
+ private Color horizontalGridColor = Color.BLACK;
+ private Color verticalGridColor = Color.BLACK;
+ private Color highlightBackgroundColor = Color.GRAY;
+
+ private int cellWidth = 0;
+ private int cellHeight = 0;
+
+ @Override
+ public void install(Component component) {
+ super.install(component);
+
+ GridPane gridPane = (GridPane)component;
+ gridPane.getGridPaneListeners().add(this);
+ }
+
+ @Override
+ public int getPreferredWidth(int height) {
+ GridPane gridPane = (GridPane)getComponent();
+ GridPane.RowSequence rows = gridPane.getRows();
+ GridPane.ColumnSequence columns = gridPane.getColumns();
+
+ int rowCount = rows.getLength();
+ int columnCount = columns.getLength();
+ boolean[] visibleColumns = new boolean[columnCount];
+ boolean[] visibleRows = new boolean[rowCount];
+
+ for (int i = 0; i < rowCount; i++) {
+ GridPane.Row row = rows.get(i);
+
+ for (int j = 0, n = row.getLength(); j < n && j < columnCount; j++) {
+ Component component = row.get(j);
+
+ if (component != null
+ && component.isVisible()) {
+ visibleColumns[j] = true;
+ visibleRows[i] = true;
+ }
+ }
+ }
+
+ int visibleRowCount = 0;
+ int clientHeight = height - padding.top - padding.bottom;
+ for (int i = 0; i < rowCount; i++) {
+ if (visibleRows[i]) {
+ visibleRowCount++;
+ }
+ }
+
+ if (visibleRowCount > 1) {
+ clientHeight -= (visibleRowCount - 1) * verticalSpacing;
+ }
+ int cellHeight = 0;
+ if (visibleRowCount > 0) {
+ cellHeight = clientHeight / visibleRowCount;
+ }
+
+ int cellPreferredWidth = 0;
+ for (int i = 0; i < rowCount; i++) {
+ GridPane.Row row = rows.get(i);
+
+ for (int j = 0, n = row.getLength(); j < n && j < columnCount; j++) {
+ Component component = row.get(j);
+
+ if (component != null
+ && component.isVisible()) {
+ cellPreferredWidth = Math.max(cellPreferredWidth, component.getPreferredWidth(cellHeight));
+ }
+ }
+ }
+
+ // The preferred width of the grid pane is the sum of the column
+ // widths, plus padding and spacing
+
+ int visibleColumnCount = 0;
+ int preferredWidth = padding.left + padding.right;
+
+ for (int j = 0; j < columnCount; j++) {
+ if (visibleColumns[j]) {
+ preferredWidth += cellPreferredWidth;
+ visibleColumnCount++;
+ }
+ }
+
+ if (visibleColumnCount > 1) {
+ preferredWidth += (visibleColumnCount - 1) * horizontalSpacing;
+ }
+
+ return preferredWidth;
+ }
+
+ @Override
+ public int getPreferredHeight(int width) {
+ GridPane gridPane = (GridPane)getComponent();
+ GridPane.RowSequence rows = gridPane.getRows();
+ GridPane.ColumnSequence columns = gridPane.getColumns();
+
+ int rowCount = rows.getLength();
+ int columnCount = columns.getLength();
+ boolean[] visibleColumns = new boolean[columnCount];
+ boolean[] visibleRows = new boolean[rowCount];
+
+ for (int i = 0; i < rowCount; i++) {
+ GridPane.Row row = rows.get(i);
+
+ for (int j = 0, n = row.getLength(); j < n && j < columnCount; j++) {
+ Component component = row.get(j);
+
+ if (component != null
+ && component.isVisible()) {
+ visibleColumns[j] = true;
+ visibleRows[i] = true;
+ }
+ }
+ }
+
+ int visibleColumnCount = 0;
+ int clientWidth = width - padding.left - padding.right;
+ for (int i = 0; i < columnCount; i++) {
+ if (visibleColumns[i]) {
+ visibleColumnCount++;
+ }
+ }
+
+ if (visibleColumnCount > 1) {
+ clientWidth -= (visibleColumnCount - 1) * horizontalSpacing;
+ }
+ int cellWidth = 0;
+ if (visibleColumnCount > 0) {
+ cellWidth = clientWidth / visibleColumnCount;
+ }
+
+ // The preferred height of the grid pane is the sum of the row
+ // heights, plus padding and spacing
+
+ int visibleRowCount = 0;
+ int preferredHeight = padding.top + padding.bottom;
+
+ for (int i = 0; i < rowCount; i++) {
+
+ if (visibleRows[i]) {
+ preferredHeight += cellWidth;
+ visibleRowCount++;
+ }
+ }
+
+ if (visibleRowCount > 1) {
+ preferredHeight += (visibleRowCount - 1) * verticalSpacing;
+ }
+
+ return preferredHeight;
+ }
+
+ @Override
+ public Dimensions getPreferredSize() {
+ GridPane gridPane = (GridPane)getComponent();
+ GridPane.RowSequence rows = gridPane.getRows();
+ GridPane.ColumnSequence columns = gridPane.getColumns();
+
+ int rowCount = rows.getLength();
+ int columnCount = columns.getLength();
+ boolean[] visibleColumns = new boolean[columnCount];
+ boolean[] visibleRows = new boolean[rowCount];
+
+ // calculate the maximum preferred cellWidth and cellHeight
+ int preferredCellHeight = 0;
+ int preferredCellWidth = 0;
+ for (int i = 0; i < rowCount; i++) {
+ GridPane.Row row = rows.get(i);
+
+ for (int j = 0, n = row.getLength(); j < n && j < columnCount; j++) {
+ Component component = row.get(j);
+
+ if (component != null
+ && component.isVisible()) {
+ visibleColumns[j] = true;
+ visibleRows[i] = true;
+ Dimensions d = component.getPreferredSize();
+ preferredCellHeight = Math.max(preferredCellHeight, d.height);
+ preferredCellWidth = Math.max(preferredCellWidth, d.width);
+ }
+ }
+ }
+
+ // The preferred width of the grid pane is the sum of the column
+ // widths, plus padding and spacing
+
+ int visibleColumnCount = 0;
+ int preferredWidth = padding.left + padding.right;
+
+ for (int j = 0; j < columnCount; j++) {
+ if (visibleColumns[j]) {
+ preferredWidth += preferredCellWidth;
+ visibleColumnCount++;
+ }
+ }
+
+ if (visibleColumnCount > 1) {
+ preferredWidth += (visibleColumnCount - 1) * horizontalSpacing;
+ }
+
+ // The preferred height of the grid pane is the sum of the row
+ // heights, plus padding and spacing
+
+ int visibleRowCount = 0;
+ int preferredHeight = padding.top + padding.bottom;
+ for (int i = 0; i < rowCount; i++) {
+ if (visibleRows[i]) {
+ visibleRowCount++;
+ }
+ }
+
+ if (visibleRowCount > 1) {
+ preferredHeight += (visibleRowCount - 1) * verticalSpacing;
+ }
+
+ return new Dimensions(preferredWidth, preferredHeight);
+ }
+
+ @Override
+ public int getBaseline(int width, int height) {
+ int baseline = -1;
+
+ // TODO Return the first available baseline by traversing cells top left to bottom right
+
+ // Include top padding value
+ if (baseline != -1) {
+ baseline += padding.top;
+ }
+
+ return baseline;
+ }
+
+ @Override
+ public void layout() {
+ GridPane gridPane = (GridPane)getComponent();
+
+ GridPane.RowSequence rows = gridPane.getRows();
+ GridPane.ColumnSequence columns = gridPane.getColumns();
+
+ int rowCount = rows.getLength();
+ int columnCount = columns.getLength();
+
+ int width = getWidth();
+ int height = getHeight();
+
+ // Determine which rows and column should be visible so we know which
+ // ones should be collapsed
+ boolean[] visibleRows = new boolean[rowCount];
+ boolean[] visibleColumns = new boolean[columnCount];
+ int cellPreferredHeight = 0;
+ int cellPreferredWidth = 0;
+
+ for (int i = 0; i < rowCount; i++) {
+ GridPane.Row row = rows.get(i);
+
+ for (int j = 0, n = row.getLength(); j < n && j < columnCount; j++) {
+ Component child = row.get(j);
+
+ if (child != null
+ && child.isVisible()) {
+ visibleRows[i] = true;
+ visibleColumns[j] = true;
+ Dimensions d = child.getPreferredSize();
+ cellPreferredHeight = Math.max(cellPreferredHeight, d.height);
+ cellPreferredWidth = Math.max(cellPreferredWidth, d.width);
+ }
+ }
+ }
+
+
+ // Calculate cell width
+
+ int visibleColumnCount = 0;
+ int clientWidth = width - padding.left - padding.right;
+ for (int i = 0; i < columnCount; i++) {
+ if (visibleColumns[i]) {
+ visibleColumnCount++;
+ }
+ }
+
+ if (visibleColumnCount > 1) {
+ clientWidth -= (visibleColumnCount - 1) * horizontalSpacing;
+ }
+ cellWidth = 0;
+ if (visibleColumnCount > 0) {
+ cellWidth = clientWidth / visibleColumnCount;
+ }
+
+
+ // Calculate cell height
+
+ int visibleRowCount = 0;
+ int clientHeight = height - padding.top - padding.bottom;
+ for (int i = 0; i < rowCount; i++) {
+ if (visibleRows[i]) {
+ visibleRowCount++;
+ }
+ }
+
+ if (visibleRowCount > 1) {
+ clientHeight -= (visibleRowCount - 1) * verticalSpacing;
+ }
+ cellHeight = 0;
+ if (visibleRowCount > 0) {
+ cellHeight = clientHeight / visibleRowCount;
+ }
+
+ int componentY = padding.top;
+ for (int i = 0; i < rowCount; i++) {
+ GridPane.Row row = rows.get(i);
+
+ int componentX = padding.left;
+ for (int j = 0, n = row.getLength(); j < n && j < columnCount; j++) {
+ Component child = row.get(j);
+
+ if (child != null
+ && child.isVisible()) {
+ child.setLocation(componentX, componentY);
+
+ child.setSize(cellWidth, cellHeight);
+ }
+
+ if (visibleColumns[j]) {
+ componentX += (cellWidth + horizontalSpacing);
+ }
+ }
+
+ if (visibleRows[i]) {
+ componentY += (cellHeight + verticalSpacing);
+ }
+ }
+ }
+
+ @Override
+ public void paint(Graphics2D graphics) {
+ super.paint(graphics);
+
+ GridPane gridPane = (GridPane)getComponent();
+
+ GridPane.RowSequence rows = gridPane.getRows();
+ GridPane.ColumnSequence columns = gridPane.getColumns();
+
+ int rowCount = rows.getLength();
+ int columnCount = columns.getLength();
+
+ int width = getWidth();
+ int height = getHeight();
+
+ graphics.setPaint(highlightBackgroundColor);
+
+ // Paint the highlighted rows
+ for (int i = 0, rowY = padding.top; i < rowCount; i++) {
+ GridPane.Row row = rows.get(i);
+
+ if (row.isHighlighted()) {
+ graphics.fillRect(0, rowY, width, cellHeight);
+ }
+
+ rowY += cellHeight + verticalSpacing;
+ }
+
+ // Paint the highlighted columns
+ for (int j = 0, columnX = padding.left; j < columnCount; j++) {
+ GridPane.Column column = columns.get(j);
+
+ if (column.isHighlighted()) {
+ graphics.fillRect(columnX, 0, cellWidth, height);
+ }
+
+ columnX += cellWidth + horizontalSpacing;
+ }
+
+ // Paint the grid lines
+ if ((showHorizontalGridLines && verticalSpacing > 0)
+ || (showVerticalGridLines && horizontalSpacing > 0)) {
+ Graphics2D gridGraphics = (Graphics2D)graphics.create();
+
+ gridGraphics.setStroke(new BasicStroke());
+ gridGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+
+ if (showHorizontalGridLines
+ && verticalSpacing > 0
+ && rowCount > 1) {
+ gridGraphics.setPaint(horizontalGridColor);
+
+ int rowY = padding.top + (cellHeight + verticalSpacing);
+
+ for (int i = 1; i < rowCount; i++) {
+ int gridY = Math.max(rowY - (int)Math.ceil(verticalSpacing * 0.5f), 0);
+ GraphicsUtilities.drawLine(gridGraphics, 0, gridY,
+ width, Orientation.HORIZONTAL);
+
+ rowY += (cellHeight + verticalSpacing);
+ }
+ }
+
+ if (showVerticalGridLines
+ && horizontalSpacing > 0
+ && columnCount > 1) {
+ gridGraphics.setPaint(verticalGridColor);
+
+ int columnX = padding.left + (cellWidth + horizontalSpacing);
+
+ for (int j = 1; j < columnCount; j++) {
+ int gridX = Math.max(columnX - (int)Math.ceil(horizontalSpacing * 0.5), 0);
+ GraphicsUtilities.drawLine(gridGraphics, gridX, 0,
+ height, Orientation.VERTICAL);
+
+ columnX += (cellWidth + horizontalSpacing);
+ }
+ }
+
+ gridGraphics.dispose();
+ }
+ }
+
+ /**
+ * Gets the padding that will be reserved around the grid pane during
+ * layout.
+ */
+ public Insets getPadding() {
+ return padding;
+ }
+
+ /**
+ * Sets the padding that will be reserved around the grid pane during
+ * layout.
+ */
+ public void setPadding(Insets padding) {
+ if (padding == null) {
+ throw new IllegalArgumentException("padding is null.");
+ }
+
+ this.padding = padding;
+ invalidateComponent();
+ }
+
+ /**
+ * Sets the padding that will be reserved around the grid pane during
+ * layout.
+ */
+ public final void setPadding(int padding) {
+ setPadding(new Insets(padding));
+ }
+
+ /**
+ * Sets the padding that will be reserved around the grid pane during
+ * layout.
+ */
+ public final void setPadding(Dictionary<String, ?> padding) {
+ if (padding == null) {
+ throw new IllegalArgumentException("padding is null.");
+ }
+
+ setPadding(new Insets(padding));
+ }
+
+ /**
+ * Sets the padding that will be reserved around the grid pane during
+ * layout.
+ */
+ public final void setPadding(String padding) {
+ if (padding == null) {
+ throw new IllegalArgumentException("padding is null.");
+ }
+
+ setPadding(Insets.decode(padding));
+ }
+
+ /**
+ * Gets the spacing that will be applied in between the grid pane's
+ * columns during layout.
+ */
+ public int getHorizontalSpacing() {
+ return horizontalSpacing;
+ }
+
+ /**
+ * Sets the spacing that will be applied in between the grid pane's
+ * columns during layout.
+ */
+ public void setHorizontalSpacing(int horizontalSpacing) {
+ if (horizontalSpacing < 0) {
+ throw new IllegalArgumentException("horizontalSpacing is negative");
+ }
+
+ this.horizontalSpacing = horizontalSpacing;
+ invalidateComponent();
+ }
+
+ /**
+ * Gets the spacing that will be applied in between the grid pane's rows
+ * during layout.
+ */
+ public int getVerticalSpacing() {
+ return verticalSpacing;
+ }
+
+ /**
+ * Sets the spacing that will be applied in between the grid pane's rows
+ * during layout.
+ */
+ public void setVerticalSpacing(int verticalSpacing) {
+ if (verticalSpacing < 0) {
+ throw new IllegalArgumentException("verticalSpacing is negative");
+ }
+
+ this.verticalSpacing = verticalSpacing;
+ invalidateComponent();
+ }
+
+ /**
+ * Tells whether or not horizontal grid lines will be painted in between
+ * the grid pane's rows.
+ */
+ public boolean getShowHorizontalGridLines() {
+ return showHorizontalGridLines;
+ }
+
+ /**
+ * Sets whether or not horizontal grid lines will be painted in between
+ * the grid pane's rows.
+ */
+ public void setShowHorizontalGridLines(boolean showHorizontalGridLines) {
+ this.showHorizontalGridLines = showHorizontalGridLines;
+ repaintComponent();
+ }
+
+ /**
+ * Tells whether or not vertical grid lines will be painted in between
+ * the grid pane's columns.
+ */
+ public boolean getShowVerticalGridLines() {
+ return showVerticalGridLines;
+ }
+
+ /**
+ * Sets whether or not vertical grid lines will be painted in between
+ * the grid pane's columns.
+ */
+ public void setShowVerticalGridLines(boolean showVerticalGridLines) {
+ this.showVerticalGridLines = showVerticalGridLines;
+ repaintComponent();
+ }
+
+ /**
+ * Gets the color used to paint the grid pane's horizontal grid lines.
+ */
+ public Color getHorizontalGridColor() {
+ return horizontalGridColor;
+ }
+
+ /**
+ * Sets the color used to paint the grid pane's horizontal grid lines.
+ */
+ public void setHorizontalGridColor(Color horizontalGridColor) {
+ if (horizontalGridColor == null) {
+ throw new IllegalArgumentException("horizontalGridColor is null.");
+ }
+
+ this.horizontalGridColor = horizontalGridColor;
+
+ if (showHorizontalGridLines || showVerticalGridLines) {
+ repaintComponent();
+ }
+ }
+
+ /**
+ * Sets the color used to paint the grid pane's horizontal grid lines.
+ */
+ public final void setHorizontalGridColor(String horizontalGridColor) {
+ if (horizontalGridColor == null) {
+ throw new IllegalArgumentException("horizontalGridColor is null.");
+ }
+
+ setHorizontalGridColor(GraphicsUtilities.decodeColor(horizontalGridColor));
+ }
+
+ /**
+ * Gets the color used to paint the grid pane's vertical grid lines.
+ */
+ public Color getVerticalGridColor() {
+ return verticalGridColor;
+ }
+
+ /**
+ * Sets the color used to paint the grid pane's vertical grid lines.
+ */
+ public void setVerticalGridColor(Color verticalGridColor) {
+ if (verticalGridColor == null) {
+ throw new IllegalArgumentException("verticalGridColor is null.");
+ }
+
+ this.verticalGridColor = verticalGridColor;
+
+ if (showHorizontalGridLines || showVerticalGridLines) {
+ repaintComponent();
+ }
+ }
+
+ /**
+ * Sets the color used to paint the grid pane's vertical grid lines.
+ */
+ public final void setVerticalGridColor(String verticalGridColor) {
+ if (verticalGridColor == null) {
+ throw new IllegalArgumentException("verticalGridColor is null.");
+ }
+
+ setVerticalGridColor(GraphicsUtilities.decodeColor(verticalGridColor));
+ }
+
+ /**
+ * Gets the background color used to paint the highlighted rows and columns.
+ */
+ public Color getHighlightBackgroundColor() {
+ return highlightBackgroundColor;
+ }
+
+ /**
+ * Sets the background color used to paint the highlighted rows and columns.
+ */
+ public void setHighlightBackgroundColor(Color highlightBackgroundColor) {
+ if (highlightBackgroundColor == null) {
+ throw new IllegalArgumentException("highlightBackgroundColor is null.");
+ }
+
+ this.highlightBackgroundColor = highlightBackgroundColor;
+ repaintComponent();
+ }
+
+ /**
+ * Sets the background color used to paint the highlighted rows and columns.
+ */
+ public final void setHighlightBackgroundColor(String highlightBackgroundColor) {
+ if (highlightBackgroundColor == null) {
+ throw new IllegalArgumentException("highlightBackgroundColor is null.");
+ }
+
+ setHighlightBackgroundColor(GraphicsUtilities.decodeColor(highlightBackgroundColor));
+ }
+
+ // GridPane.Skin methods
+
+ @Override
+ public int getRowAt(int y) {
+ GridPane gridPane = (GridPane)getComponent();
+ GridPane.RowSequence rows = gridPane.getRows();
+
+ int rowCount = rows.getLength();
+
+ int rowIndex = -1;
+ int rowY = padding.top;
+
+ for (int i = 0; rowY <= y && i < rowCount; i++) {
+
+ if (y < rowY + cellHeight) {
+ rowIndex = i;
+ break;
+ }
+
+ rowY += cellHeight + verticalSpacing;
+ }
+
+ return rowIndex;
+ }
+
+ @Override
+ public Bounds getRowBounds(int row) {
+ GridPane gridPane = (GridPane)getComponent();
+ GridPane.RowSequence rows = gridPane.getRows();
+
+ int rowCount = rows.getLength();
+
+ if (row < 0
+ || row >= rowCount) {
+ throw new IndexOutOfBoundsException(String.valueOf(row));
+ }
+
+ int rowY = padding.top;
+
+ for (int i = 0; i < row; i++) {
+ rowY += cellHeight + verticalSpacing;
+ }
+
+ return new Bounds(0, rowY, getWidth(), cellHeight);
+ }
+
+ @Override
+ public int getColumnAt(int x) {
+ GridPane gridPane = (GridPane)getComponent();
+ GridPane.ColumnSequence columns = gridPane.getColumns();
+
+ int columnCount = columns.getLength();
+
+ int columnIndex = -1;
+
+ for (int j = 0, columnX = padding.left; columnX <= x && j < columnCount; j++) {
+
+ if (x < columnX + cellWidth) {
+ columnIndex = j;
+ break;
+ }
+
+ columnX += cellWidth + horizontalSpacing;
+ }
+
+ return columnIndex;
+ }
+
+ @Override
+ public Bounds getColumnBounds(int column) {
+ GridPane gridPane = (GridPane)getComponent();
+ GridPane.ColumnSequence columns = gridPane.getColumns();
+
+ int columnCount = columns.getLength();
+
+ if (column < 0
+ || column >= columnCount) {
+ throw new IndexOutOfBoundsException(String.valueOf(column));
+ }
+
+ int columnX = padding.left;
+
+ for (int j = 0; j < column; j++) {
+ columnX += cellWidth + horizontalSpacing;
+ }
+
+ return new Bounds(columnX, 0, cellWidth, getHeight());
+ }
+
+ // GridPaneListener methods
+
+ @Override
+ public void rowInserted(GridPane gridPane, int index) {
+ invalidateComponent();
+ }
+
+ @Override
+ public void rowsRemoved(GridPane gridPane, int index, Sequence<GridPane.Row> rows) {
+ invalidateComponent();
+ }
+
+ @Override
+ public void rowHighlightedChanged(GridPane.Row row) {
+ GridPane gridPane = row.getGridPane();
+ repaintComponent(getRowBounds(gridPane.getRows().indexOf(row)));
+ }
+
+ @Override
+ public void columnInserted(GridPane gridPane, int index) {
+ invalidateComponent();
+ }
+
+ @Override
+ public void columnsRemoved(GridPane gridPane, int index,
+ Sequence<GridPane.Column> columns) {
+ invalidateComponent();
+ }
+
+ @Override
+ public void columnHighlightedChanged(GridPane.Column column) {
+ GridPane gridPane = column.getGridPane();
+ repaintComponent(getColumnBounds(gridPane.getColumns().indexOf(column)));
+ }
+
+ @Override
+ public void cellInserted(GridPane.Row row, int column) {
+ invalidateComponent();
+ }
+
+ @Override
+ public void cellsRemoved(GridPane.Row row, int column,
+ Sequence<Component> removed) {
+ invalidateComponent();
+ }
+
+ @Override
+ public void cellUpdated(GridPane.Row row, int column,
+ Component previousComponent) {
+ invalidateComponent();
+ }
+
+}
Added: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraGridPaneSkin.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraGridPaneSkin.java?rev=835809&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraGridPaneSkin.java (added)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraGridPaneSkin.java Fri Nov 13 11:01:02 2009
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 org.apache.pivot.wtk.skin.terra;
+
+import org.apache.pivot.wtk.Theme;
+import org.apache.pivot.wtk.skin.GridPaneSkin;
+
+/**
+ * Terra grid pane skin.
+ */
+public class TerraGridPaneSkin extends GridPaneSkin {
+ public TerraGridPaneSkin() {
+ setHorizontalGridColor(7);
+ setVerticalGridColor(7);
+ setHighlightBackgroundColor(10);
+ }
+
+ public final void setBackgroundColor(int backgroundColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setBackgroundColor(theme.getColor(backgroundColor));
+ }
+
+ public final void setHorizontalGridColor(int horizontalGridColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setHorizontalGridColor(theme.getColor(horizontalGridColor));
+ }
+
+ public final void setVerticalGridColor(int verticalGridColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setVerticalGridColor(theme.getColor(verticalGridColor));
+ }
+
+ public final void setHighlightBackgroundColor(int highlightBackgroundColor) {
+ TerraTheme theme = (TerraTheme)Theme.getTheme();
+ setHighlightBackgroundColor(theme.getColor(highlightBackgroundColor));
+ }
+}
Modified: incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraTheme.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraTheme.java?rev=835809&r1=835808&r2=835809&view=diff
==============================================================================
--- incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraTheme.java (original)
+++ incubator/pivot/trunk/wtk/src/org/apache/pivot/wtk/skin/terra/TerraTheme.java Fri Nov 13 11:01:02 2009
@@ -18,8 +18,8 @@
import java.awt.Color;
import java.awt.Font;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import org.apache.pivot.collections.List;
@@ -33,6 +33,7 @@
import org.apache.pivot.wtk.Alert;
import org.apache.pivot.wtk.ApplicationContext;
import org.apache.pivot.wtk.Border;
+import org.apache.pivot.wtk.BoxPane;
import org.apache.pivot.wtk.Calendar;
import org.apache.pivot.wtk.CalendarButton;
import org.apache.pivot.wtk.Checkbox;
@@ -40,11 +41,11 @@
import org.apache.pivot.wtk.ColorChooserButton;
import org.apache.pivot.wtk.Dialog;
import org.apache.pivot.wtk.Expander;
-import org.apache.pivot.wtk.BoxPane;
import org.apache.pivot.wtk.FileBrowser;
import org.apache.pivot.wtk.FileBrowserSheet;
import org.apache.pivot.wtk.Form;
import org.apache.pivot.wtk.Frame;
+import org.apache.pivot.wtk.GridPane;
import org.apache.pivot.wtk.Label;
import org.apache.pivot.wtk.LinkButton;
import org.apache.pivot.wtk.ListButton;
@@ -105,6 +106,7 @@
componentSkinMap.put(Form.class, TerraFormSkin.class);
componentSkinMap.put(BoxPane.class, TerraBoxPaneSkin.class);
componentSkinMap.put(Frame.class, TerraFrameSkin.class);
+ componentSkinMap.put(GridPane.class, TerraGridPaneSkin.class);
componentSkinMap.put(Label.class, TerraLabelSkin.class);
componentSkinMap.put(LinkButton.class, TerraLinkButtonSkin.class);
componentSkinMap.put(ListButton.class, TerraListButtonSkin.class);
Added: incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/GridPaneTest.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/GridPaneTest.java?rev=835809&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/GridPaneTest.java (added)
+++ incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/GridPaneTest.java Fri Nov 13 11:01:02 2009
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you 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 org.apache.pivot.wtk.test;
+
+import org.apache.pivot.collections.Map;
+import org.apache.pivot.wtk.Application;
+import org.apache.pivot.wtk.DesktopApplicationContext;
+import org.apache.pivot.wtk.Display;
+import org.apache.pivot.wtk.Window;
+import org.apache.pivot.wtkx.WTKXSerializer;
+
+public class GridPaneTest implements Application {
+ private Window window = null;
+
+ @Override
+ public void startup(Display display, Map<String, String> properties)
+ throws Exception {
+ WTKXSerializer wtkxSerializer = new WTKXSerializer();
+ window = (Window)wtkxSerializer.readObject(this, "gridpane_test.wtkx");
+ window.open(display);
+ }
+
+ @Override
+ public boolean shutdown(boolean optional) {
+ if (window != null) {
+ window.close();
+ }
+
+ return false;
+ }
+
+ @Override
+ public void suspend() {
+ }
+
+ @Override
+ public void resume() {
+ }
+
+ public static void main(String[] args) {
+ DesktopApplicationContext.main(GridPaneTest.class, args);
+ }
+}
Added: incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/gridpane_test.wtkx
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/gridpane_test.wtkx?rev=835809&view=auto
==============================================================================
--- incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/gridpane_test.wtkx (added)
+++ incubator/pivot/trunk/wtk/test/org/apache/pivot/wtk/test/gridpane_test.wtkx Fri Nov 13 11:01:02 2009
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to you 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.
+-->
+
+<Window title="GridPane Test" maximized="true"
+ xmlns:wtkx="http://pivot.apache.org/wtkx"
+ xmlns="org.apache.pivot.wtk">
+ <content>
+ <GridPane styles="{padding:6, verticalSpacing:8, horizontalSpacing:4, showHorizontalGridLines:true, showVerticalGridLines:true}">
+ <columns>
+ <GridPane.Column/>
+ <GridPane.Column/>
+ </columns>
+ <rows>
+ <GridPane.Row>
+ <PushButton buttonData="One"/>
+ <GridPane.Filler preferredHeight="20"/>
+ </GridPane.Row>
+ <GridPane.Row>
+ <GridPane.Filler preferredHeight="20"/>
+ <PushButton buttonData="Two"/>
+ </GridPane.Row>
+ <GridPane.Row>
+ <PushButton buttonData="Three" visible="false"/>
+ </GridPane.Row>
+ <GridPane.Row>
+ <PushButton buttonData="Four"/>
+ </GridPane.Row>
+ </rows>
+ </GridPane>
+ </content>
+</Window>