Swing Components Java

// Example from http://www.crionics.com/products/opensource/faq/swing_ex/SwingExamples.html
/* (swing1.1) */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
/**
 * @version 1.0 3/06/99
 */
public class CellBorderTableExample extends JFrame {
  public CellBorderTableExample() {
    super("Cell Border Example");
    final Color color = UIManager.getColor("Table.gridColor");
    DefaultTableModel dm = new DefaultTableModel(12, 6) {
      public void setValueAt(Object obj, int row, int col) {
        if (obj instanceof MyData) {
          super.setValueAt(obj, row, col);
        } else {
          MyData myData = null;
          Object oldObject = getValueAt(row, col);
          if (oldObject == null) {
            myData = new MyData(obj, new LinesBorder(color, 0));
          } else if (oldObject instanceof MyData) {
            myData = (MyData) oldObject;
          } else {
            System.out.println("error");
            return;
          }
          myData.setObject(obj);
          super.setValueAt(myData, row, col);
        }
      }
    };
    JTable table = new JTable(dm);
    table.setIntercellSpacing(new Dimension(0, 0));
    table.setCellSelectionEnabled(true);
    table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
    table.setDefaultRenderer(Object.class, new BorderCellRenderer());
    JScrollPane scroll = new JScrollPane(table);
    ThicknessPanel thicknessPanel = new ThicknessPanel();
    Box box = new Box(BoxLayout.Y_AXIS);
    box.add(thicknessPanel);
    box.add(new ButtonPanel(table, thicknessPanel));
    getContentPane().add(scroll, BorderLayout.CENTER);
    getContentPane().add(box, BorderLayout.EAST);
  }
  public static void main(String[] args) {
    CellBorderTableExample frame = new CellBorderTableExample();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(400, 240);
    frame.setVisible(true);
  }
  class ThicknessPanel extends JPanel {
    JComboBox[] combos;
    ThicknessPanel() {
      String[] str = { "top", "left", "bottom", "right" };
      int n = str.length;
      setLayout(new GridLayout(n, 2));
      setBorder(new TitledBorder("Thickness"));
      combos = new JComboBox[n];
      for (int i = 0; i < n; i++) {
        combos[i] = new JComboBox(new Object[] { "0", "1", "2", "3" });
        add(new JLabel(str[i]));
        add(combos[i]);
      }
    }
    public Insets getThickness() {
      Insets insets = new Insets(0, 0, 0, 0);
      insets.top = combos[0].getSelectedIndex();
      insets.left = combos[1].getSelectedIndex();
      insets.bottom = combos[2].getSelectedIndex();
      insets.right = combos[3].getSelectedIndex();
      return insets;
    }
  }
  class ButtonPanel extends JPanel {
    JTable table;
    ThicknessPanel thicknessPanel;
    Color color = UIManager.getColor("Table.gridColor");
    ButtonPanel(JTable table, ThicknessPanel thicknessPanel) {
      this.table = table;
      this.thicknessPanel = thicknessPanel;
      setLayout(new GridLayout(3, 1));
      setBorder(new TitledBorder("Append Lines"));
      final JCheckBox oneBlock = new JCheckBox("Block");
      JButton b_and = new JButton("REPLACE");
      JButton b_or = new JButton("OR");
      add(oneBlock);
      add(b_and);
      add(b_or);
      b_and.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          setCellBorder(true, oneBlock.isSelected());
        }
      });
      b_or.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          setCellBorder(false, oneBlock.isSelected());
        }
      });
    }
    private void setCellBorder(boolean isReplace, boolean isBlock) {
      boolean isTop, isLeft, isBottom, isRight;
      Insets insets = thicknessPanel.getThickness();
      int[] columns = table.getSelectedColumns();
      int[] rows = table.getSelectedRows();
      int rowMax = rows.length;
      int columnMax = columns.length;
      for (int i = 0; i < rowMax; i++) {
        int row = rows[i];
        isTop = (i == 0) ? true : false;
        isBottom = (i == rowMax - 1) ? true : false;
        for (int j = 0; j < columnMax; j++) {
          int column = columns[j];
          isLeft = (j == 0) ? true : false;
          isRight = (j == columnMax - 1) ? true : false;
          MyData myData = (MyData) table.getValueAt(row, column);
          if (myData == null) {
            myData = new MyData("", new LinesBorder(color, 0));
          }
          LinesBorder border = (LinesBorder) myData.getBorder();
          if (isBlock) {
            Insets tmp = new Insets(0, 0, 0, 0);
            if (isTop)
              tmp.top = Math.max(tmp.top, insets.top);
            if (isLeft)
              tmp.left = Math.max(tmp.left, insets.left);
            if (isBottom)
              tmp.bottom = Math.max(tmp.bottom, insets.bottom);
            if (isRight)
              tmp.right = Math.max(tmp.right, insets.right);
            border.append(tmp, isReplace);
          } else {
            border.append(insets, isReplace);
          }
          table.setValueAt(myData, row, column);
        }
      }
      table.clearSelection();
      table.revalidate();
      table.repaint();
    }
  }
  class MyData implements CellBorder {
    private Border border;
    private Object obj;
    public MyData(Object obj, Border border) {
      this.obj = obj;
      this.border = border;
    }
    public void setObject(Object obj) {
      this.obj = obj;
    }
    public String toString() {
      return obj.toString();
    }
    // CellBorder
    public void setBorder(Border border) {
      this.border = border;
    }
    public Border getBorder() {
      return border;
    }
    public void setBorder(Border border, int row, int col) {
    }
    public Border getBorder(int row, int col) {
      return null;
    }
  }
}
class BorderCellRenderer extends JLabel implements TableCellRenderer {
  protected Border noFocusBorder;
  protected Border columnBorder;
  public BorderCellRenderer() {
    noFocusBorder = new EmptyBorder(1, 2, 1, 2);
    setOpaque(true);
  }
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    if (isSelected) {
      setForeground(table.getSelectionForeground());
      setBackground(table.getSelectionBackground());
    } else {
      setForeground(table.getForeground());
      setBackground(table.getBackground());
    }
    setFont(table.getFont());
    if (hasFocus) {
      setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
      if (table.isCellEditable(row, column)) {
        setForeground(UIManager.getColor("Table.focusCellForeground"));
        setBackground(UIManager.getColor("Table.focusCellBackground"));
      }
    } else {
      if (value instanceof CellBorder) {
        Border border = ((CellBorder) value).getBorder();
        setBorder(border);
      } else {
        if (columnBorder != null) {
          setBorder(columnBorder);
        } else {
          setBorder(noFocusBorder);
        }
      }
    }
    setText((value == null) ? "" : value.toString());
    return this;
  }
  public void setColumnBorder(Border border) {
    columnBorder = border;
  }
  public Border getColumnBorder() {
    return columnBorder;
  }
}
interface CellBorder {
  public Border getBorder();
  public Border getBorder(int row, int column);
  public void setBorder(Border border);
  public void setBorder(Border border, int row, int column);
}
class LinesBorder extends AbstractBorder implements SwingConstants {
  protected int northThickness;
  protected int southThickness;
  protected int eastThickness;
  protected int westThickness;
  protected Color northColor;
  protected Color southColor;
  protected Color eastColor;
  protected Color westColor;
  public LinesBorder(Color color) {
    this(color, 1);
  }
  public LinesBorder(Color color, int thickness) {
    setColor(color);
    setThickness(thickness);
  }
  public LinesBorder(Color color, Insets insets) {
    setColor(color);
    setThickness(insets);
  }
  public void paintBorder(Component c, Graphics g, int x, int y, int width,
      int height) {
    Color oldColor = g.getColor();
    g.setColor(northColor);
    for (int i = 0; i < northThickness; i++) {
      g.drawLine(x, y + i, x + width - 1, y + i);
    }
    g.setColor(southColor);
    for (int i = 0; i < southThickness; i++) {
      g
          .drawLine(x, y + height - i - 1, x + width - 1, y + height
              - i - 1);
    }
    g.setColor(eastColor);
    for (int i = 0; i < westThickness; i++) {
      g.drawLine(x + i, y, x + i, y + height - 1);
    }
    g.setColor(westColor);
    for (int i = 0; i < eastThickness; i++) {
      g.drawLine(x + width - i - 1, y, x + width - i - 1, y + height - 1);
    }
    g.setColor(oldColor);
  }
  public Insets getBorderInsets(Component c) {
    return new Insets(northThickness, westThickness, southThickness,
        eastThickness);
  }
  public Insets getBorderInsets(Component c, Insets insets) {
    return new Insets(northThickness, westThickness, southThickness,
        eastThickness);
  }
  public boolean isBorderOpaque() {
    return true;
  }
  public void setColor(Color c) {
    northColor = c;
    southColor = c;
    eastColor = c;
    westColor = c;
  }
  public void setColor(Color c, int direction) {
    switch (direction) {
    case NORTH:
      northColor = c;
      break;
    case SOUTH:
      southColor = c;
      break;
    case EAST:
      eastColor = c;
      break;
    case WEST:
      westColor = c;
      break;
    default:
    }
  }
  public void setThickness(int n) {
    northThickness = n;
    southThickness = n;
    eastThickness = n;
    westThickness = n;
  }
  public void setThickness(Insets insets) {
    northThickness = insets.top;
    southThickness = insets.bottom;
    eastThickness = insets.right;
    westThickness = insets.left;
  }
  public void setThickness(int n, int direction) {
    switch (direction) {
    case NORTH:
      northThickness = n;
      break;
    case SOUTH:
      southThickness = n;
      break;
    case EAST:
      eastThickness = n;
      break;
    case WEST:
      westThickness = n;
      break;
    default:
    }
  }
  public void append(LinesBorder b, boolean isReplace) {
    if (isReplace) {
      northThickness = b.northThickness;
      southThickness = b.southThickness;
      eastThickness = b.eastThickness;
      westThickness = b.westThickness;
    } else {
      northThickness = Math.max(northThickness, b.northThickness);
      southThickness = Math.max(southThickness, b.southThickness);
      eastThickness = Math.max(eastThickness, b.eastThickness);
      westThickness = Math.max(westThickness, b.westThickness);
    }
  }
  public void append(Insets insets, boolean isReplace) {
    if (isReplace) {
      northThickness = insets.top;
      southThickness = insets.bottom;
      eastThickness = insets.right;
      westThickness = insets.left;
    } else {
      northThickness = Math.max(northThickness, insets.top);
      southThickness = Math.max(southThickness, insets.bottom);
      eastThickness = Math.max(eastThickness, insets.right);
      westThickness = Math.max(westThickness, insets.left);
    }
  }
}