Package com.cburch.logisim.gui.generic

Source Code of com.cburch.logisim.gui.generic.AttrTable$TableModelAdapter

/* Copyright (c) 2011, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.gui.generic;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Window;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.FocusListener;
import java.awt.event.FocusEvent;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JPanel;
import javax.swing.JComboBox;
import javax.swing.SwingConstants;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;

import com.cburch.logisim.util.JDialogOk;
import com.cburch.logisim.util.JInputComponent;
import com.cburch.logisim.util.LocaleListener;
import com.cburch.logisim.util.LocaleManager;

import java.util.ArrayList;
import java.util.EventObject;
import java.util.LinkedList;

public class AttrTable extends JPanel implements LocaleListener {
  private static final AttrTableModel NULL_ATTR_MODEL = new NullAttrModel();
 
  private static class NullAttrModel implements AttrTableModel {
    public void addAttrTableModelListener(AttrTableModelListener listener) { }
    public void removeAttrTableModelListener(AttrTableModelListener listener) { }
   
    public String getTitle() { return null; }
    public int getRowCount() { return 0; }
    public AttrTableModelRow getRow(int rowIndex) { return null; }
  }
 
  private static class TitleLabel extends JLabel {
    @Override
    public Dimension getMinimumSize() {
      Dimension ret = super.getMinimumSize();
      return new Dimension(1, ret.height);
    }
  }

  private static class MyDialog extends JDialogOk {
    JInputComponent input;
    Object value;

    public MyDialog(Dialog parent, JInputComponent input) {
      super(parent, Strings.get("attributeDialogTitle"), true);
      configure(input);
    }

    public MyDialog(Frame parent, JInputComponent input) {
      super(parent, Strings.get("attributeDialogTitle"), true);
      configure(input);
    }

    private void configure(JInputComponent input) {
      this.input = input;
      this.value = input.getValue();
     
      // Thanks to Christophe Jacquet, who contributed a fix to this
      // so that when the dialog is resized, the component within it
      // is resized as well. (Tracker #2024479)
      JPanel p = new JPanel(new BorderLayout());
      p.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
      p.add((JComponent) input, BorderLayout.CENTER);
      getContentPane().add(p, BorderLayout.CENTER);

      pack();
    }

    @Override
    public void okClicked() {
      value = input.getValue();
    }

    public Object getValue() {
      return value;
    }
  }

  private class TableModelAdapter
      implements TableModel, AttrTableModelListener {
    Window parent;
    LinkedList<TableModelListener> listeners;
    AttrTableModel attrModel;
   
    TableModelAdapter(Window parent, AttrTableModel attrModel) {
      this.parent = parent;
      this.listeners = new LinkedList<TableModelListener>();
      this.attrModel = attrModel;
    }
   
    void setAttrTableModel(AttrTableModel value) {
      if (attrModel != value) {
        TableCellEditor editor = table.getCellEditor();
        if (editor != null) editor.cancelCellEditing();
        attrModel.removeAttrTableModelListener(this);
        attrModel = value;
        attrModel.addAttrTableModelListener(this);
        fireTableChanged();
      }
    }

    public void addTableModelListener(TableModelListener l) {
      listeners.add(l);
    }

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

    void fireTableChanged() {
      TableModelEvent e = new TableModelEvent(this);
      for (TableModelListener l : new ArrayList<TableModelListener>(listeners)) {
        l.tableChanged(e);
      }
    }

    public int getColumnCount() {
      return 2;
    }

    public String getColumnName(int columnIndex) {
      if (columnIndex == 0) return "Attribute";
      else                  return "Value";
    }

    public Class<?> getColumnClass(int columnIndex) {
      return String.class;
    }

    public int getRowCount() {
      return attrModel.getRowCount();
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
      if (columnIndex == 0) {
        return attrModel.getRow(rowIndex).getLabel();
      } else {
        return attrModel.getRow(rowIndex).getValue();
      }
    }

    public boolean isCellEditable(int rowIndex, int columnIndex) {
      return columnIndex > 0 && attrModel.getRow(rowIndex).isValueEditable();
    }

    public void setValueAt(Object value, int rowIndex,
        int columnIndex) {
      if (columnIndex > 0) {
        try {
          attrModel.getRow(rowIndex).setValue(value);
        } catch (AttrTableSetException e) {
          JOptionPane.showMessageDialog(parent, e.getMessage(),
              Strings.get("attributeChangeInvalidTitle"),
              JOptionPane.WARNING_MESSAGE);
        }
      }
    }
   
    //
    // AttrTableModelListener methods
    //
    public void attrTitleChanged(AttrTableModelEvent e) {
      if (e.getSource() != attrModel) {
        attrModel.removeAttrTableModelListener(this);
        return;
      }
      updateTitle();
    }
   
    public void attrStructureChanged(AttrTableModelEvent e) {
      if (e.getSource() != attrModel) {
        attrModel.removeAttrTableModelListener(this);
        return;
      }
      fireTableChanged();
    }
   
    public void attrValueChanged(AttrTableModelEvent e) {
      if (e.getSource() != attrModel) {
        attrModel.removeAttrTableModelListener(this);
        return;
      }
      fireTableChanged();
    }
  }

  private class CellEditor
      implements TableCellEditor, FocusListener, ActionListener {
    LinkedList<CellEditorListener> listeners = new LinkedList<CellEditorListener>();
    AttrTableModelRow currentRow;
    Component currentEditor;

    //
    // TableCellListener management
    //
    public void addCellEditorListener(CellEditorListener l) {
      // Adds a listener to the list that's notified when the
      // editor stops, or cancels editing.
      listeners.add(l);
    }

    public void removeCellEditorListener(CellEditorListener l) {
      // Removes a listener from the list that's notified
      listeners.remove(l);
    }

    public void fireEditingCanceled() {
      ChangeEvent e = new ChangeEvent(AttrTable.this);
      for (CellEditorListener l : new ArrayList<CellEditorListener>(listeners)) {
        l.editingCanceled(e);
      }
    }

    public void fireEditingStopped() {
      ChangeEvent e = new ChangeEvent(AttrTable.this);
      for (CellEditorListener l : new ArrayList<CellEditorListener>(listeners)) {
        l.editingStopped(e);
      }
    }

    //
    // other TableCellEditor methods
    //
    public void cancelCellEditing() {
      // Tells the editor to cancel editing and not accept any
      // partially edited value.
      fireEditingCanceled();
    }

    public boolean stopCellEditing() {
      // Tells the editor to stop editing and accept any partially
      // edited value as the value of the editor.
      fireEditingStopped();
      return true;
    }

    public Object getCellEditorValue() {
      // Returns the value contained in the editor.
      Component comp = currentEditor;
      if (comp instanceof JTextField) {
        return ((JTextField) comp).getText();
      } else if (comp instanceof JComboBox) {
        return ((JComboBox) comp).getSelectedItem();
      } else {
        return null;
      }
    }

    public boolean isCellEditable(EventObject anEvent) {
      // Asks the editor if it can start editing using anEvent.
      return true;
    }

    public boolean shouldSelectCell(EventObject anEvent) {
      // Returns true if the editing cell should be selected,
      // false otherwise.
      return true;
    }

    public Component getTableCellEditorComponent(JTable table, Object value,
        boolean isSelected, int rowIndex, int columnIndex) {
      AttrTableModel attrModel = tableModel.attrModel;
      AttrTableModelRow row = attrModel.getRow(rowIndex);
     
      if (columnIndex == 0) {
        return new JLabel(row.getLabel());
      } else {
        if (currentEditor != null) currentEditor.transferFocus();

        Component editor = row.getEditor(parent);
        if (editor instanceof JComboBox) {
          ((JComboBox) editor).addActionListener(this);
          editor.addFocusListener(this);
        } else if (editor instanceof JInputComponent) {
          JInputComponent input = (JInputComponent) editor;
          MyDialog dlog;
          Window parent = AttrTable.this.parent;
          if (parent instanceof Frame) {
            dlog = new MyDialog((Frame) parent, input);
          } else {
            dlog = new MyDialog((Dialog) parent, input);
          }
          dlog.setVisible(true);
          Object retval = dlog.getValue();
          try {
            row.setValue(retval);
          } catch (AttrTableSetException e) {
            JOptionPane.showMessageDialog(parent, e.getMessage(),
                Strings.get("attributeChangeInvalidTitle"),
                JOptionPane.WARNING_MESSAGE);
          }
          editor = new JLabel(row.getValue());
        } else {
          editor.addFocusListener(this);
        }
        currentRow = row;
        currentEditor = editor;
        return editor;
      }
    }

    //
    // FocusListener methods
    //
    public void focusLost(FocusEvent e) {
      Object dst = e.getOppositeComponent();
      if (dst instanceof Component) {
        Component p = (Component) dst;
        while (p != null && !(p instanceof Window)) {
          if (p == AttrTable.this) {
            // switch to another place in this table,
            // no problem
            return;
          }
          p = p.getParent();
        }
        // focus transferred outside table; stop editing
        editor.stopCellEditing();
      }
    }

    public void focusGained(FocusEvent e) { }

    //
    // ActionListener methods
    //
    public void actionPerformed(ActionEvent e) {
      stopCellEditing();
    }

  }

  private Window parent;
  private boolean titleEnabled;
  private JLabel title;
  private JTable table;
  private TableModelAdapter tableModel;
  private CellEditor editor = new CellEditor();

  public AttrTable(Window parent) {
    super(new BorderLayout());
    this.parent = parent;
   
    titleEnabled = true;
    title = new TitleLabel();
    title.setHorizontalAlignment(SwingConstants.CENTER);
    title.setVerticalAlignment(SwingConstants.CENTER);
    tableModel = new TableModelAdapter(parent, NULL_ATTR_MODEL);
    table = new JTable(tableModel);
    table.setDefaultEditor(Object.class, editor);
    table.setTableHeader(null);
    table.setRowHeight(20);
   
    Font baseFont = title.getFont();
    int titleSize = Math.round(baseFont.getSize() * 1.2f);
    Font titleFont = baseFont.deriveFont((float) titleSize).deriveFont(Font.BOLD);
    title.setFont(titleFont);
    Color bgColor = new Color(240, 240, 240);
    setBackground(bgColor);
    table.setBackground(bgColor);
    Object renderer = table.getDefaultRenderer(String.class);
    if (renderer instanceof JComponent) {
      ((JComponent) renderer).setBackground(Color.WHITE);
    }
   
    JScrollPane tableScroll = new JScrollPane(table);
   
    this.add(title, BorderLayout.PAGE_START);
    this.add(tableScroll, BorderLayout.CENTER);
    LocaleManager.addLocaleListener(this);
    localeChanged();
  }
 
  public void setTitleEnabled(boolean value) {
    titleEnabled = value;
    updateTitle();
  }
 
  public boolean getTitleEnabled() {
    return titleEnabled;
  }
 
  public void setAttrTableModel(AttrTableModel value) {
    tableModel.setAttrTableModel(value == null ? NULL_ATTR_MODEL : value);
    updateTitle();
  }
 
  public AttrTableModel getAttrTableModel() {
    return tableModel.attrModel;
  }

  public void localeChanged() {
    updateTitle();
    tableModel.fireTableChanged();
  }
 
  private void updateTitle() {
    if (titleEnabled) {
      String text = tableModel.attrModel.getTitle();
      if (text == null) {
        title.setVisible(false);
      } else {
        title.setText(text);
        title.setVisible(true);
      }
    } else {
      title.setVisible(false);
    }
  }
}
TOP

Related Classes of com.cburch.logisim.gui.generic.AttrTable$TableModelAdapter

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.