Package org.dyno.visual.swing.widgets.editors

Source Code of org.dyno.visual.swing.widgets.editors.TableModelPanel$InnerTableModel

/************************************************************************************
* Copyright (c) 2008 William Chen.                                                 *
*                                                                                  *
* All rights reserved. This program and the accompanying materials are made        *
* available under the terms of the Eclipse Public License v1.0 which accompanies   *
* this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html *
*                                                                                  *
* Use is subject to the terms of Eclipse Public License v1.0.                      *
*                                                                                  *
* Contributors:                                                                    *
*     William Chen - initial API and implementation.                               *
************************************************************************************/

package org.dyno.visual.swing.widgets.editors;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputListener;
import javax.swing.event.TableModelListener;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;

import org.dyno.visual.swing.plugin.spi.WidgetAdapter;
import org.eclipse.albireo.core.Platform;
import org.eclipse.albireo.core.SwtPopupRegistry;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;

@SuppressWarnings("unchecked")
public class TableModelPanel extends JLayeredPane implements ActionListener {
  private static final long serialVersionUID = 1L;
  private JScrollPane scrollPane;
  private JTable table;
  private TableColumnHeaderGlass columnHeader;
  private TableRowHeaderGlass rowHeader;
  private JTextField textField;
  private Color designFieldBackground;
  private Color designFieldBorder;
  private WidgetAdapter adapter;

  public TableModelPanel(WidgetAdapter adapter, JScrollPane jsp) {
    this.adapter = adapter;
    setOpaque(false);
    setLayout(new GlassLayout());
    setLayer(jsp, 0);
    add(jsp);
    jsp.setToolTipText(Messages.TableModelPanel_Adjust_View);
    jsp.getHorizontalScrollBar().setToolTipText(
        Messages.TableModelPanel_Drag_Adjust_View);
    jsp.getVerticalScrollBar().setToolTipText(
        Messages.TableModelPanel_Drag_Adjust_View);
    TableColumnHeaderGlass columnHeader = new TableColumnHeaderGlass();
    TableRowHeaderGlass rowHeader = new TableRowHeaderGlass();
    setLayer(columnHeader, 1);
    add(columnHeader);
    setLayer(rowHeader, 2);
    add(rowHeader);
    this.scrollPane = jsp;
    this.table = (JTable) jsp.getViewport().getView();
    this.table.setToolTipText(Messages.TableModelPanel_Click_Edit);
    this.columnHeader = columnHeader;
    this.columnHeader.addActionListener(this);
    this.rowHeader = rowHeader;
    this.rowHeader.addActionListener(this);
    this.listeners = new ArrayList<TableModelListener>();
    this.textField = new JTextField();
    this.columnHeader.add(textField);
    this.textField.setVisible(false);
    designFieldBackground = Color.orange.brighter();
    designFieldBorder = Color.green.darker();
  }

  private Composite getEmbeddedParent() {
    return adapter.getEditorSite();
  }

 
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() == columnHeader) {
      int action = columnHeader.icon;
      int column = columnHeader.column;
      switch (action) {
      case NO_OP:
        break;
      case COLUMN_LEFT_INSERT:
        doLeftInsert(column);
        break;
      case COLUMN_LEFT_MOVE:
        doMoveLeft(column);
        break;
      case COLUMN_RIGHT_MOVE:
        doMoveRight(column);
        break;
      case COLUMN_RIGHT_INSERT:
        doRightInsert(column);
        break;
      case COLUMN_DELETE:
        doDeleteColumn(column);
        break;
      case COLUMN_EDIT_TEXT:
        doEditText(column);
        break;
      case COLUMN_EDIT_TYPE:
        doEditType(column);
        break;
      }
    } else if (e.getSource() == rowHeader) {
      int action = rowHeader.icon;
      int row = rowHeader.row;
      switch (action) {
      case ROW_DELETE:
        doDeleteRow(row);
        break;
      case ROW_UP_INSERT:
        doUpInsert(row);
        break;
      case ROW_UP_MOVE:
        doUpMove(row);
        break;
      case ROW_DOWN_INSERT:
        doDownInsert(row);
        break;
      case ROW_DOWN_MOVE:
        doDownMove(row);
        break;
      }
    }
  }

  private void doDownMove(int row) {
    if (row < data.size() - 1) {
      int next = row + 1;
      List<Object> nextRow = data.get(next);
      data.set(next, data.get(row));
      data.set(row, nextRow);
      table.setModel(new InnerTableModel());
    }
  }

  private void doDownInsert(int row) {
    List<Object> rowList = new ArrayList<Object>();
    for (int i = 0; i < columnNames.size(); i++) {
      Object value = getDefaultClassValue(columnClass.get(i));
      if (value == null)
        value = "" + row + "x" + i; //$NON-NLS-1$ //$NON-NLS-2$
      rowList.add(value);
    }
    data.add(row + 1, rowList);
    table.setModel(new InnerTableModel());
  }

  private Object getDefaultClassValue(Class<?> clazz) {
    TypeAction action = getTypeAction(clazz);
    if (action == null)
      return null;
    return action.defaultValue;
  }

  private void doUpInsert(int row) {
    List<Object> rowList = new ArrayList<Object>();
    for (int i = 0; i < columnNames.size(); i++) {
      Object value = getDefaultClassValue(columnClass.get(i));
      if (value == null)
        value = "" + row + "x" + i; //$NON-NLS-1$ //$NON-NLS-2$
      rowList.add(value);
    }
    data.add(row, rowList);
    table.setModel(new InnerTableModel());
  }

  private void doUpMove(int row) {
    if (row > 0) {
      int prev = row - 1;
      List<Object> prevRow = data.get(prev);
      data.set(prev, data.get(row));
      data.set(row, prevRow);
      table.setModel(new InnerTableModel());
    }
  }

  private void doDeleteRow(int row) {
    data.remove(row);
    table.setModel(new InnerTableModel());
  }

  private void doMoveRight(int column) {
    int count = columnNames.size();
    if (column < count - 1) {
      int next = column + 1;
      swap(columnNames, column, next);
      swap(columnClass, column, next);
      for (List<Object> row : data) {
        swap(row, column, next);
      }
      table.setModel(new InnerTableModel());
    }
  }

  private void swap(List list, int i, int j) {
    Object temp = list.get(i);
    list.set(i, list.get(j));
    list.set(j, temp);
  }

  private void doMoveLeft(int column) {
    if (column > 0) {
      int prev = column - 1;
      swap(columnNames, column, prev);
      swap(columnClass, column, prev);
      for (List<Object> row : data) {
        swap(row, column, prev);
      }
      table.setModel(new InnerTableModel());
    }
  }

  private TypeAction[] actions = new TypeAction[] {
      new TypeAction(Object.class, "Object", null), new TypeAction(String.class, "String", null), //$NON-NLS-1$ //$NON-NLS-2$
      new TypeAction(Boolean.class, "Boolean", new Boolean(false)), new TypeAction(Integer.class, "Integer", (int) 0), //$NON-NLS-1$ //$NON-NLS-2$
      new TypeAction(Byte.class, "Byte", (byte) 0), new TypeAction(Short.class, "Short", (short) 0), new TypeAction(Long.class, "Long", 0l), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      new TypeAction(Float.class, "Float", 0f), new TypeAction(Double.class, "Double", 0d) }; //$NON-NLS-1$ //$NON-NLS-2$

  private TypeAction getTypeAction(Class<?> clazz) {
    for (TypeAction action : actions) {
      if (action.clazz == clazz)
        return action;
    }
    return null;
  }

  private void doEditType(final int column) {
    getEmbeddedParent().getDisplay().asyncExec(new Runnable() {
     
      public void run() {
        popupMenu(column);
      }
    });
  }

  private void popupMenu(int column) {
    MenuManager popup = new MenuManager("#TABLE_MODEL_TYPE_POPUP"); //$NON-NLS-1$
    for (TypeAction action : actions) {
      action.setColumn(column);
      popup.add(action);
    }
    Point p = columnHeader.getPopupLocation();
    Composite parent = getEmbeddedParent();
    final Menu menu = popup.createContextMenu(parent);
    Point loc = columnHeader.getLocationOnScreen();
    menu.setLocation(loc.x + p.x, loc.y + p.y);
    if (Platform.isGtk()) {
      SwtPopupRegistry.getInstance().setMenu(columnHeader, false, menu);
      adapter.showComponentPopup(columnHeader, p.x, p.y);
    } else{
      menu.setVisible(true);
    }
  }

  class TypeAction extends Action {
    private Class<?> clazz;
    private int column;
    private Object defaultValue;

    public void setColumn(int column) {
      this.column = column;
      super.setChecked(columnClass.get(column) == clazz);
    }

    public TypeAction(Class<?> clazz, String name, Object defaultValue) {
      super(name, SWT.RADIO);
      this.clazz = clazz;
      this.defaultValue = defaultValue;
    }

    public Object getDefaultValue() {
      return defaultValue;
    }

   
    public void run() {
      Class<?> prevClass = columnClass.get(column);
      if (prevClass != clazz) {
        columnClass.set(column, clazz);
        for (int r = 0; r < data.size(); r++) {
          List<Object> row = data.get(r);
          if (defaultValue == null) {
            row.set(column, "" + r + "x" + column); //$NON-NLS-1$ //$NON-NLS-2$
          } else {
            row.set(column, defaultValue);
          }
        }
        table.setModel(new InnerTableModel());
      }
    }
  }

  private void doEditText(int column) {
    columnHeader.startEditing();
  }

  private void doDeleteColumn(int column) {
    columnClass.remove(column);
    columnNames.remove(column);
    for (List<Object> row : data) {
      row.remove(column);
    }
    table.setModel(new InnerTableModel());
  }

  private void doRightInsert(int column) {
    int i = column + 1;
    columnClass.add(i, String.class);
    columnNames.add(i, Messages.TableModelPanel_Title + i);
    for (int r = 0; r < data.size(); r++) {
      List<Object> row = data.get(r);
      row.add(i, "" + r + "x" + i); //$NON-NLS-1$ //$NON-NLS-2$
    }
    table.setModel(new InnerTableModel());
  }

  private void doLeftInsert(int column) {
    columnClass.add(column, String.class);
    columnNames.add(column, Messages.TableModelPanel_Title + column);
    for (int r = 0; r < data.size(); r++) {
      List<Object> row = data.get(r);
      row.add(column, "" + r + "x" + column); //$NON-NLS-1$ //$NON-NLS-2$
    }
    table.setModel(new InnerTableModel());
  }

  class GlassLayout implements LayoutManager {
   
    public void addLayoutComponent(String name, Component comp) {
    }

   
    public void layoutContainer(Container parent) {
      int w = parent.getWidth();
      int h = parent.getHeight();
      scrollPane.setBounds(0, 0, w, h);
      scrollPane.doLayout();
      Rectangle rect = scrollPane.getViewportBorderBounds();
      columnHeader.setBounds(0, 0, rect.x + rect.width, rect.y);
      rowHeader.setBounds(0, rect.y, 64, rect.height);
    }

   
    public Dimension minimumLayoutSize(Container parent) {
      return scrollPane.getMinimumSize();
    }

   
    public Dimension preferredLayoutSize(Container parent) {
      return scrollPane.getPreferredSize();
    }

   
    public void removeLayoutComponent(Component comp) {
    }
  }

  private static final int PRESSED = 0;
  private static final int RELEASED = 1;

  private static final int NO_OP = -1;
  private static final int COLUMN_LEFT_INSERT = 0;
  private static final int ROW_UP_INSERT = 0;
  private static final int COLUMN_LEFT_MOVE = 1;
  private static final int ROW_UP_MOVE = 1;
  private static final int COLUMN_DELETE = 2;
  private static final int ROW_DELETE = 2;
  private static final int COLUMN_EDIT_TEXT = 3;
  private static final int COLUMN_EDIT_TYPE = 4;
  private static final int COLUMN_RIGHT_MOVE = 5;
  private static final int ROW_DOWN_MOVE = 3;
  private static final int COLUMN_RIGHT_INSERT = 6;
  private static final int ROW_DOWN_INSERT = 4;

  private static Icon COLUMN_LEFT_INSERT_ICON;
  private static Icon ROW_UP_INSERT_ICON;
  private static Icon COLUMN_LEFT_MOVE_ICON;
  private static Icon ROW_UP_MOVE_ICON;
  private static Icon COLUMN_DELETE_ICON;
  private static Icon ROW_DELETE_ICON;
  private static Icon COLUMN_EDIT_TEXT_ICON;
  private static Icon COLUMN_EDIT_TYPE_ICON;
  private static Icon COLUMN_RIGHT_MOVE_ICON;
  private static Icon ROW_DOWN_MOVE_ICON;
  private static Icon COLUMN_RIGHT_INSERT_ICON;
  private static Icon ROW_DOWN_INSERT_ICON;
  static {
    COLUMN_LEFT_INSERT_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/insert.png")); //$NON-NLS-1$
    ROW_UP_INSERT_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/insert.png")); //$NON-NLS-1$
    COLUMN_LEFT_MOVE_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/left_move.png")); //$NON-NLS-1$
    ROW_UP_MOVE_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/up_move.png")); //$NON-NLS-1$
    COLUMN_RIGHT_INSERT_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/insert.png")); //$NON-NLS-1$
    ROW_DOWN_INSERT_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/insert.png")); //$NON-NLS-1$
    COLUMN_RIGHT_MOVE_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/right_move.png")); //$NON-NLS-1$
    ROW_DOWN_MOVE_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/down_move.png")); //$NON-NLS-1$
    COLUMN_DELETE_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/delete.png")); //$NON-NLS-1$
    ROW_DELETE_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/delete.png")); //$NON-NLS-1$
    COLUMN_EDIT_TEXT_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/edit_text.png")); //$NON-NLS-1$
    COLUMN_EDIT_TYPE_ICON = new ImageIcon(TableModelPanel.class
        .getResource("/icons/edit_type.png")); //$NON-NLS-1$
  }

  class ColumnNameAction implements ActionListener {
    private int column;

    public ColumnNameAction(int c) {
      column = c;
    }

   
    public void actionPerformed(ActionEvent e) {
      String title = textField.getText();
      columnNames.set(column, title);
      columnHeader.stopEditing();
      table.setModel(new InnerTableModel());
    }

  }

  class TableRowHeaderGlass extends JComponent implements MouseInputListener,
      MouseWheelListener {
    private static final long serialVersionUID = 1L;
    private int status;
    private int icon = -1;
    private int row = -1;
    private List<ActionListener> listeners;

    public TableRowHeaderGlass() {
      listeners = new ArrayList<ActionListener>();
      addMouseListener(this);
      addMouseMotionListener(this);
      addMouseWheelListener(this);
    }

    public void addActionListener(ActionListener l) {
      if (!listeners.contains(l))
        listeners.add(l);
    }

    public void removeActionListener(ActionListener l) {
      if (listeners.contains(l))
        listeners.remove(l);
    }

    private void fireActionPerformed() {
      ActionEvent event = new ActionEvent(this, 0, "action"); //$NON-NLS-1$
      for (ActionListener l : listeners)
        l.actionPerformed(event);
    }

    private int getXoffset() {
      switch (icon) {
      case ROW_UP_INSERT:
        return 0;
      case ROW_UP_MOVE:
        return 32;
      case ROW_DOWN_INSERT:
        return 0;
      case ROW_DOWN_MOVE:
        return 48;
      case ROW_DELETE:
        return 16;
      }
      return 0;
    }

    private int getYoffset() {
      switch (icon) {
      case ROW_UP_INSERT:
        return -8;
      case ROW_UP_MOVE:
        return 0;
      case ROW_DOWN_INSERT:
        return 8;
      case ROW_DOWN_MOVE:
        return 0;
      case ROW_DELETE:
        return 0;
      }
      return 0;
    }

   
    protected void paintComponent(Graphics g) {
      paintBackground(g);
      if (row != -1) {
        Rectangle rect = table.getCellRect(row, 0, true);
        rect.width = 64;
        rect = SwingUtilities.convertRectangle(table, rect,
            TableModelPanel.this);
        rect = SwingUtilities.convertRectangle(TableModelPanel.this,
            rect, rowHeader);
        rect.x = 0;
        int x = rect.x;
        int y = rect.y;
        int w = 16;
        int h = 16;
        if (icon != NO_OP) {
          Icon iCon = getIcon();
          if (iCon != null) {
            x += getXoffset();
            y += getYoffset();
            w = iCon.getIconWidth();
            h = iCon.getIconHeight();
            iCon.paintIcon(this, g, x, y);
          }
        }
        g.setColor(Color.LIGHT_GRAY);
        if (status == PRESSED) {
          g.draw3DRect(x, y, w, h, false);
        } else if (status == RELEASED) {
          g.draw3DRect(x, y, w, h, true);
        }
      }
      g.setColor(designFieldBorder);
      int width = getWidth();
      int height = getHeight();
      g.drawLine(0, 0, 0, height - 1);
      g.drawLine(0, height - 1, width - 1, height - 1);
      g.drawLine(width - 1, 0, width - 1, height - 1);
    }

    private void paintBackground(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
      java.awt.Composite old = g2d.getComposite();
      AlphaComposite pha = AlphaComposite.getInstance(
          AlphaComposite.SRC_OVER, 0.2f);
      g2d.setComposite(pha);
      g2d.setColor(designFieldBackground);
      int width = getWidth();
      int height = getHeight();
      g2d.fillRect(0, 0, width, height);
      g2d.setComposite(old);
    }

    private Icon getIcon() {
      switch (icon) {
      case NO_OP:
        return null;
      case ROW_UP_INSERT:
        return ROW_UP_INSERT_ICON;
      case ROW_UP_MOVE:
        return ROW_UP_MOVE_ICON;
      case ROW_DOWN_INSERT:
        return ROW_DOWN_INSERT_ICON;
      case ROW_DOWN_MOVE:
        return ROW_DOWN_MOVE_ICON;
      case ROW_DELETE:
        return ROW_DELETE_ICON;
      }
      return null;
    }

    private Rectangle getIconBounds() {
      switch (icon) {
      case NO_OP:
        return null;
      case ROW_UP_INSERT:
        return new Rectangle(0, -8, 16, 16);
      case ROW_UP_MOVE:
        return new Rectangle(32, 0, 16, 16);
      case ROW_DOWN_INSERT:
        return new Rectangle(0, 8, 16, 16);
      case ROW_DOWN_MOVE:
        return new Rectangle(48, 0, 16, 16);
      case ROW_DELETE:
        return new Rectangle(16, 0, 16, 16);
      }
      return null;
    }

   
    public void mouseClicked(MouseEvent e) {
    }

   
    public void mouseEntered(MouseEvent e) {
    }

   
    public void mouseExited(MouseEvent e) {
      row = -1;
      repaint();
    }

   
    public void mousePressed(MouseEvent e) {
      Point p = e.getPoint();
      int count = table.getRowCount();
      for (int i = 0; i < count; i++) {
        Rectangle rect = table.getCellRect(i, 0, true);
        rect.width = 64;
        rect = SwingUtilities.convertRectangle(table, rect,
            TableModelPanel.this);
        rect = SwingUtilities.convertRectangle(TableModelPanel.this,
            rect, rowHeader);
        rect.x = 0;
        if (p.x >= rect.x && p.x < rect.x + rect.width) {
          icon = getIconPlace(p, rect);
          Icon iCon = getIcon();
          if (iCon != null) {
            Rectangle iconBounds = getIconBounds();
            iconBounds.x += rect.x;
            iconBounds.y += rect.y;
            if (p.x >= iconBounds.x
                && p.x < iconBounds.x + iconBounds.width
                && p.y >= iconBounds.y
                && p.y < iconBounds.y + iconBounds.height) {
              row = i;
              status = PRESSED;
              repaint();
              return;
            }
          }
        }
      }
      setToolTipText(null);
      row = -1;
      repaint();
    }

   
    public void mouseReleased(MouseEvent e) {
      Point p = e.getPoint();
      int count = table.getRowCount();
      for (int i = 0; i < count; i++) {
        Rectangle rect = table.getCellRect(i, 0, true);
        rect.width = 64;
        rect = SwingUtilities.convertRectangle(table, rect,
            TableModelPanel.this);
        rect = SwingUtilities.convertRectangle(TableModelPanel.this,
            rect, rowHeader);
        rect.x = 0;
        if (p.x >= rect.x && p.x < rect.x + rect.width) {
          icon = getIconPlace(p, rect);
          Icon iCon = getIcon();
          if (iCon != null) {
            Rectangle iconBounds = getIconBounds();
            iconBounds.x += rect.x;
            iconBounds.y += rect.y;
            if (p.x >= iconBounds.x
                && p.x < iconBounds.x + iconBounds.width
                && p.y >= iconBounds.y
                && p.y < iconBounds.y + iconBounds.height) {
              row = i;
              status = RELEASED;
              repaint();
              fireActionPerformed();
              return;
            }
          }
        }
      }
      setToolTipText(null);
      row = -1;
      repaint();
    }

   
    public void mouseDragged(MouseEvent e) {
    }

    private int getIconPlace(Point p, Rectangle rect) {
      if (p.x > rect.x && p.x < rect.x + 16 && p.y < rect.y + 8
          && p.y > rect.y - 8)
        return ROW_UP_INSERT;
      else if (p.x > rect.x && p.x < rect.x + 16 && p.y > rect.y + 8
          && p.y < rect.y + 24)
        return ROW_DOWN_INSERT;
      else if (p.x > rect.x + 16 && p.x < rect.x + 32 && p.y > rect.y
          && p.y < rect.y + 16) {
        return ROW_DELETE;
      } else if (p.x > rect.x + 32 && p.x < rect.x + 48 && p.y > rect.y
          && p.y < rect.y + 16)
        return ROW_UP_MOVE;
      else if (p.x > rect.x + 48 && p.x < rect.x + 64 && p.y > rect.y
          && p.y < rect.y + 16)
        return ROW_DOWN_MOVE;
      else
        return NO_OP;
    }

   
    public void mouseMoved(MouseEvent e) {
      Point p = e.getPoint();
      int count = table.getRowCount();
      for (int i = 0; i < count; i++) {
        Rectangle rect = table.getCellRect(i, 0, true);
        rect.width = 64;
        rect = SwingUtilities.convertRectangle(table, rect,
            TableModelPanel.this);
        rect = SwingUtilities.convertRectangle(TableModelPanel.this,
            rect, rowHeader);
        rect.x = 0;
        if (p.x >= rect.x && p.x < rect.x + rect.width) {
          int lastIcon = icon;
          icon = getIconPlace(p, rect);
          Icon iCon = getIcon();
          if (iCon != null) {
            Rectangle iconBounds = getIconBounds();
            iconBounds.x += rect.x;
            iconBounds.y += rect.y;
            if (p.x >= iconBounds.x
                && p.x < iconBounds.x + iconBounds.width
                && p.y >= iconBounds.y
                && p.y < iconBounds.y + iconBounds.height) {
              if (row != i || lastIcon != icon) {
                row = i;
                status = RELEASED;
                repaint();
                setToolTipText(getCurrentText());
              }
              return;
            }
          }
        }
      }
      setToolTipText(null);
      row = -1;
      repaint();
    }

    private String getCurrentText() {
      switch (icon) {
      case NO_OP:
        return null;
      case ROW_UP_INSERT:
        return Messages.TableModelPanel_Insert_Row;
      case ROW_UP_MOVE:
        return Messages.TableModelPanel_Move_Upward;
      case ROW_DOWN_INSERT:
        return Messages.TableModelPanel_Append_Row;
      case ROW_DOWN_MOVE:
        return Messages.TableModelPanel_Move_Downward;
      case ROW_DELETE:
        return Messages.TableModelPanel_Delete_Row;
      }
      return null;
    }

   
    public void mouseWheelMoved(MouseWheelEvent e) {
    }

  }

  class TableColumnHeaderGlass extends JComponent implements
      MouseInputListener, MouseWheelListener {
    private static final long serialVersionUID = 1L;
    private int status;
    private int icon = -1;
    private int column = -1;
    private List<ActionListener> listeners;
    private ActionListener action;

    private Icon getIcon() {
      switch (icon) {
      case NO_OP:
        return null;
      case COLUMN_LEFT_INSERT:
        return COLUMN_LEFT_INSERT_ICON;
      case COLUMN_LEFT_MOVE:
        return COLUMN_LEFT_MOVE_ICON;
      case COLUMN_RIGHT_INSERT:
        return COLUMN_RIGHT_INSERT_ICON;
      case COLUMN_RIGHT_MOVE:
        return COLUMN_RIGHT_MOVE_ICON;
      case COLUMN_DELETE:
        return COLUMN_DELETE_ICON;
      case COLUMN_EDIT_TEXT:
        return COLUMN_EDIT_TEXT_ICON;
      case COLUMN_EDIT_TYPE:
        return COLUMN_EDIT_TYPE_ICON;
      }
      return null;
    }

    void startEditing() {
      if (column == -1)
        return;
      Rectangle rect = table.getTableHeader().getHeaderRect(column);
      action = new ColumnNameAction(column);
      textField.addActionListener(action);
      textField.setVisible(true);
      textField.setBounds(rect);
      textField.setText(columnNames.get(column));
      textField.selectAll();
      textField.requestFocus();
    }

    Point getPopupLocation() {
      Rectangle rect = table.getTableHeader().getHeaderRect(column);
      rect = SwingUtilities.convertRectangle(table, rect,
          TableModelPanel.this);
      int x = rect.x;
      int y = rect.y;
      if (icon != NO_OP) {
        Icon iCon = getIcon();
        if (iCon != null) {
          x += icon * rect.width / 6 - iCon.getIconWidth() / 2;
        }
      }
      return new Point(x, y);
    }

    void stopEditing() {
      textField.removeActionListener(action);
      textField.setVisible(false);
    }

    public TableColumnHeaderGlass() {
      setLayout(null);
      setOpaque(false);
      addMouseListener(this);
      addMouseMotionListener(this);
      addMouseWheelListener(this);
      listeners = new ArrayList<ActionListener>();
    }

    public void addActionListener(ActionListener l) {
      if (!listeners.contains(l))
        listeners.add(l);
    }

    public void removeActionListener(ActionListener l) {
      if (listeners.contains(l))
        listeners.remove(l);
    }

    private void fireActionPerformed() {
      ActionEvent event = new ActionEvent(this, 0, "action"); //$NON-NLS-1$
      for (ActionListener l : listeners)
        l.actionPerformed(event);
    }

    private void paintBackground(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
      java.awt.Composite old = g2d.getComposite();
      AlphaComposite pha = AlphaComposite.getInstance(
          AlphaComposite.SRC_OVER, 0.2f);
      g2d.setComposite(pha);
      g2d.setColor(designFieldBackground);
      int width = getWidth();
      int height = getHeight();
      g2d.fillRect(0, 0, width, height);
      g2d.setComposite(old);
    }

   
    protected void paintComponent(Graphics g) {
      paintBackground(g);
      if (column != -1) {
        Rectangle rect = table.getTableHeader().getHeaderRect(column);
        rect = SwingUtilities.convertRectangle(table, rect,
            TableModelPanel.this);
        int x = rect.x;
        int y = 0;
        int w = 16;
        int h = 16;
        if (icon != NO_OP) {
          Icon iCon = getIcon();
          if (iCon != null) {
            x += icon * rect.width / 6 - iCon.getIconWidth() / 2;
            y += (rect.height - iCon.getIconHeight()) / 2;
            w = iCon.getIconWidth();
            h = iCon.getIconHeight();
            iCon.paintIcon(this, g, x, y);
          }
        }
        g.setColor(Color.LIGHT_GRAY);
        if (status == PRESSED) {
          g.draw3DRect(x, y, w, h, false);
        } else if (status == RELEASED) {
          g.draw3DRect(x, y, w, h, true);
        }
      }
      g.setColor(designFieldBorder);
      int width = getWidth();
      int height = getHeight();
      g.drawLine(0, 0, 0, height - 1);
      g.drawLine(0, 0, width - 1, 0);
      g.drawLine(width - 1, 0, width - 1, height - 1);
      g.drawLine(63, height - 1, width - 1, height - 1);
    }

   
    public void mouseClicked(MouseEvent e) {
    }

   
    public void mouseEntered(MouseEvent e) {
    }

   
    public void mouseExited(MouseEvent e) {
      column = -1;
      repaint();
    }

   
    public void mousePressed(MouseEvent e) {
      Point p = SwingUtilities.convertPoint(TableModelPanel.this, e
          .getPoint(), table);
      JTableHeader header = table.getTableHeader();
      int count = table.getColumnCount();
      for (int i = 0; i < count; i++) {
        Rectangle rect = header.getHeaderRect(i);
        icon = (p.x - rect.x + 8) / (rect.width / 6);
        Icon iCon = getIcon();
        if (iCon != null) {
          int x = rect.x + icon * rect.width / 6
              - iCon.getIconWidth() / 2;
          if (p.x >= x && p.x < x + iCon.getIconWidth()) {
            column = i;
            status = PRESSED;
            repaint();
            return;
          }
        }
      }
      column = -1;
      repaint();
    }

   
    public void mouseReleased(MouseEvent e) {
      Point p = SwingUtilities.convertPoint(TableModelPanel.this, e
          .getPoint(), table);
      JTableHeader header = table.getTableHeader();
      int count = table.getColumnCount();
      for (int i = 0; i < count; i++) {
        Rectangle rect = header.getHeaderRect(i);
        if (p.x >= rect.x && p.x < rect.x + rect.width) {
          icon = (p.x - rect.x) / (rect.width / 6);
          Icon iCon = getIcon();
          if (iCon != null) {
            int x = rect.x + icon * rect.width / 6
                - iCon.getIconWidth() / 2;
            if (p.x >= x && p.x < x + iCon.getIconWidth()) {
              column = i;
              status = RELEASED;
              repaint();
              fireActionPerformed();
              return;
            }
          }
        }
      }
      column = -1;
      repaint();
    }

   
    public void mouseDragged(MouseEvent e) {
    }

   
    public void mouseMoved(MouseEvent e) {
      Point p = SwingUtilities.convertPoint(TableModelPanel.this, e
          .getPoint(), table);
      JTableHeader header = table.getTableHeader();
      int count = table.getColumnCount();
      for (int i = 0; i < count; i++) {
        Rectangle rect = header.getHeaderRect(i);
        if (p.x >= rect.x && p.x < rect.x + rect.width) {
          int lastIcon = icon;
          icon = (p.x - rect.x) / (rect.width / 6);
          Icon iCon = getIcon();
          if (iCon != null) {
            int x = rect.x + icon * rect.width / 6
                - iCon.getIconWidth() / 2;
            if (p.x >= x && p.x < x + iCon.getIconWidth()) {
              if (column != i || lastIcon != icon) {
                column = i;
                status = RELEASED;
                repaint();
                setToolTipText(getCurrentText());
              }
              return;
            }
          }
        }
      }
      setToolTipText(null);
      column = -1;
      repaint();
    }

    private String getCurrentText() {
      switch (icon) {
      case NO_OP:
        return null;
      case COLUMN_LEFT_INSERT:
        return Messages.TableModelPanel_Insert_Column;
      case COLUMN_LEFT_MOVE:
        return Messages.TableModelPanel_Move_Leftward;
      case COLUMN_RIGHT_INSERT:
        return Messages.TableModelPanel_Append_Column;
      case COLUMN_RIGHT_MOVE:
        return Messages.TableModelPanel_Move_Rightward;
      case COLUMN_DELETE:
        return Messages.TableModelPanel_Delete_Column;
      case COLUMN_EDIT_TEXT:
        return Messages.TableModelPanel_Edit_Col_Title;
      case COLUMN_EDIT_TYPE:
        return Messages.TableModelPanel_Edit_Col_Type;
      }
      return null;
    }

   
    public void mouseWheelMoved(MouseWheelEvent e) {
    }
  }

  public TableModel getTableModel() {
    Object[][] d = new Object[data.size()][];
    Object[] n = new Object[columnNames.size()];
    Class<?>[] c = new Class[columnClass.size()];
    for (int i = 0; i < columnNames.size(); i++)
      n[i] = columnNames.get(i);
    for (int i = 0; i < columnClass.size(); i++)
      c[i] = columnClass.get(i);
    for (int row = 0; row < data.size(); row++) {
      List<Object> rowList = data.get(row);
      d[row] = new Object[rowList.size()];
      for (int col = 0; col < rowList.size(); col++) {
        d[row][col] = rowList.get(col);
      }
    }
    return new TypedTableModel(d, n, c);
  }

  public void setFocus() {
    table.requestFocus();
  }

  public void setTableModel(TableModel v) {
    columnClass = new ArrayList<Class<?>>();
    columnNames = new ArrayList<String>();
    for (int i = 0; i < v.getColumnCount(); i++) {
      Class<?> type = v.getColumnClass(i);
      if (type == null)
        columnClass.add(String.class);
      else
        columnClass.add(type);
      columnNames.add(v.getColumnName(i));
    }
    data = new ArrayList<List<Object>>();
    for (int r = 0; r < v.getRowCount(); r++) {
      List<Object> row = new ArrayList<Object>();
      for (int c = 0; c < v.getColumnCount(); c++) {
        row.add(v.getValueAt(r, c));
      }
      data.add(row);
    }
    table.setModel(new InnerTableModel());
  }

 
  public void setFont(Font font) {
    table.setFont(font);
    super.setFont(font);
  }

  private List<TableModelListener> listeners;
  private List<Class<?>> columnClass;
  private List<String> columnNames;
  private List<List<Object>> data;

  class InnerTableModel implements TableModel {
   
    public void addTableModelListener(TableModelListener l) {
      if (!listeners.contains(l))
        listeners.add(l);
    }

   
    public Class<?> getColumnClass(int columnIndex) {
      return columnClass.get(columnIndex);
    }

   
    public int getColumnCount() {
      return columnNames.size();
    }

   
    public String getColumnName(int columnIndex) {
      return columnNames.get(columnIndex);
    }

   
    public int getRowCount() {
      return data.size();
    }

   
    public Object getValueAt(int rowIndex, int columnIndex) {
      return data.get(rowIndex).get(columnIndex);
    }

   
    public boolean isCellEditable(int rowIndex, int columnIndex) {
      return true;
    }

   
    public void removeTableModelListener(TableModelListener l) {
      if (listeners.contains(l))
        listeners.remove(l);
    }

   
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
      data.get(rowIndex).set(columnIndex, value);
    }
  }

  public Color getDesignFieldBackground() {
    return designFieldBackground;
  }

  public void setDesignFieldBackground(Color designFieldBackground) {
    this.designFieldBackground = designFieldBackground;
  }
}
TOP

Related Classes of org.dyno.visual.swing.widgets.editors.TableModelPanel$InnerTableModel

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.