Google Tag Manager

2010/11/30

JTable CellEditor PopupMenu

Code

public static JPopupMenu installTextComponentPopupMenu(final JTextComponent tc) {
  final UndoManager manager = new UndoManager();
  final Action undoAction   = new UndoAction(manager);
  final Action redoAction   = new RedoAction(manager);
  final Action cutAction    = new DefaultEditorKit.CutAction();
  final Action copyAction   = new DefaultEditorKit.CopyAction();
  final Action pasteAction  = new DefaultEditorKit.PasteAction();
  final Action deleteAction = new AbstractAction("delete") {
    public void actionPerformed(ActionEvent e) {
      JPopupMenu pop = (JPopupMenu)e.getSource();
      ((JTextComponent)pop.getInvoker()).replaceSelection(null);
    }
  };
  tc.addAncestorListener(new AncestorListener() {
    public void ancestorAdded(AncestorEvent e) {
      manager.discardAllEdits();
      tc.requestFocusInWindow();
    }
    public void ancestorMoved(AncestorEvent e) {}
    public void ancestorRemoved(AncestorEvent e) {}
  });
  tc.getDocument().addUndoableEditListener(manager);
  tc.getActionMap().put("undo", undoAction);
  tc.getActionMap().put("redo", redoAction);
  InputMap imap = tc.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
  imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Event.CTRL_MASK), "undo");
  imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Event.CTRL_MASK), "redo");

  JPopupMenu popup = new JPopupMenu();
  popup.add(cutAction);
  popup.add(copyAction);
  popup.add(pasteAction);
  popup.add(deleteAction);
  popup.addSeparator();
  popup.add(undoAction);
  popup.add(redoAction);

  popup.addPopupMenuListener(new PopupMenuListener() {
    public void popupMenuCanceled(PopupMenuEvent e) {}
    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
      undoAction.setEnabled(true);
      redoAction.setEnabled(true);
    }
    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
      JPopupMenu pop = (JPopupMenu)e.getSource();
      JTextField field = (JTextField)pop.getInvoker();
      boolean flg = field.getSelectedText()!=null;
      cutAction.setEnabled(flg);
      copyAction.setEnabled(flg);
      deleteAction.setEnabled(flg);
      undoAction.setEnabled(manager.canUndo());
      redoAction.setEnabled(manager.canRedo());
    }
  });
  tc.setComponentPopupMenu(popup);
  return popup;
}

References

2010/10/26

JTree node highlight search

Code

class HighlightTreeCellRenderer extends DefaultTreeCellRenderer {
  private static final Color rollOverRowColor = new Color(220, 240, 255);
  private final TreeCellRenderer renderer;
  public String q;
  public HighlightTreeCellRenderer(TreeCellRenderer renderer) {
    this.renderer = renderer;
  }

  @Override public Component getTreeCellRendererComponent(JTree tree, Object value,
        boolean isSelected, boolean expanded,
        boolean leaf, int row, boolean hasFocus) {
    JComponent c = (JComponent) renderer.getTreeCellRendererComponent(
        tree, value, isSelected, expanded, leaf, row, hasFocus);
    if (isSelected) {
      c.setOpaque(false);
      c.setForeground(getTextSelectionColor());
      // c.setBackground(Color.BLUE); // getBackgroundSelectionColor());
    } else {
      c.setOpaque(true);
      if (q != null && !q.isEmpty() && value.toString().startsWith(q)) {
        c.setForeground(getTextNonSelectionColor());
        c.setBackground(rollOverRowColor);
      } else {
        c.setForeground(getTextNonSelectionColor());
        c.setBackground(getBackgroundNonSelectionColor());
      }
    }
    return c;
  }
}

References

2010/09/21

SearchBar JComboBox

Code

public class BasicSearchBarComboBoxUI extends SearchBarComboBoxUI {
  protected boolean isEditable = true;
  public static javax.swing.plaf.ComponentUI createUI(JComponent c) {
    return new BasicSearchBarComboBoxUI();
  }

  @Override protected void installDefaults() {
    super.installDefaults();
    // comboBox.setEditable(true);
    comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
    // comboBox.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
  }

  @Override protected LayoutManager createLayoutManager() {
    return new LayoutManager() {
      @Override public void addLayoutComponent(String name, Component comp) {
        /* not needed */
      }

      @Override public void removeLayoutComponent(Component comp) {
        /* not needed */
      }

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

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

      @Override public void layoutContainer(Container parent) {
        if (!(parent instanceof JComboBox)) {
          return;
        }
        JComboBox<?> cb = (JComboBox<?>) parent;
        Rectangle r = SwingUtilities.calculateInnerArea(cb, null);

        int arrowSize = 0;
        JButton arrowButton = (JButton) cb.getComponent(0);
        if (Objects.nonNull(arrowButton)) {
          Insets arrowInsets = arrowButton.getInsets();
          int bw = arrowButton.getPreferredSize().width + arrowInsets.left + arrowInsets.right;
          arrowButton.setBounds(r.x, r.y, bw, r.height);
          arrowSize = bw;
        }
        JButton loupeButton = null;
        for (Component c : cb.getComponents()) {
          if ("ComboBox.loupeButton".equals(c.getName())) {
            loupeButton = (JButton) c;
            break;
          }
        }
        int loupeSize = 0;
        if (Objects.nonNull(loupeButton)) {
          loupeSize = r.height;
          loupeButton.setBounds(r.x + r.width - loupeSize, r.y, loupeSize, r.height);
        }
        JTextField editor = (JTextField) cb.getEditor().getEditorComponent();
        if (Objects.nonNull(editor)) {
          editor.setBounds(r.x + arrowSize, r.y, r.width - arrowSize - loupeSize, r.height);
        }
      }
    };
  }
  // ...

References

2010/09/13

Placeholder for an empty JTable

Code

JEditorPane hint = new JEditorPane("text/html", ">html<>a href='dummy'<No data!>/a<>/html<");

table.setFillsViewportHeight(true);
table.setLayout(new GridBagLayout());
table.add(hint);

model.addTableModelListener(new TableModelListener() {
  @Override public void tableChanged(TableModelEvent e) {
    DefaultTableModel model = (DefaultTableModel) e.getSource();
    hint.setVisible(model.getRowCount() == 0);
  }
});

References

2010/08/16

Kinetic Scrolling JScrollPane

Code

class KineticScrollingListener2 extends MouseAdapter implements HierarchyListener {
  protected static final int SPEED = 4;
  protected static final int DELAY = 10;
  protected static final double D = .8;
  protected final JComponent label;
  protected final Point startPt = new Point();
  protected final Point delta = new Point();
  protected final Cursor dc;
  protected final Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
  protected final Timer inside = new Timer(DELAY, null);
  protected final Timer outside = new Timer(DELAY, null);

  protected static boolean isInside(JViewport viewport, JComponent comp) {
    Point vp = viewport.getViewPosition();
    return vp.x >= 0 && vp.x + viewport.getWidth() - comp.getWidth() <= 0
        && vp.y >= 0 && vp.y + viewport.getHeight() - comp.getHeight() <= 0;
  }

  protected KineticScrollingListener2(JComponent comp) {
    super();
    this.label = comp;
    this.dc = comp.getCursor();
    inside.addActionListener(e -> dragInside());
    outside.addActionListener(e -> dragOutside());
  }

  private void dragInside() {
    JViewport viewport = (JViewport) SwingUtilities.getUnwrappedParent(label);
    Point vp = viewport.getViewPosition();
    // System.out.format("s: %s, %s%n", delta, vp);
    vp.translate(-delta.x, -delta.y);
    viewport.setViewPosition(vp);
    if (Math.abs(delta.x) > 0 || Math.abs(delta.y) > 0) {
      delta.setLocation((int) (delta.x * D), (int) (delta.y * D));
      // Outside
      if (vp.x < 0 || vp.x + viewport.getWidth() - label.getWidth() > 0) {
        delta.x = (int) (delta.x * D);
      }
      if (vp.y < 0 || vp.y + viewport.getHeight() - label.getHeight() > 0) {
        delta.y = (int) (delta.y * D);
      }
    } else {
      inside.stop();
      if (!isInside(viewport, label)) {
        outside.start();
      }
    }
  }

  private void dragOutside() {
    JViewport viewport = (JViewport) SwingUtilities.getUnwrappedParent(label);
    Point vp = viewport.getViewPosition();
    // System.out.format("r: %s%n", vp);
    if (vp.x < 0) {
      vp.x = (int) (vp.x * D);
    }
    if (vp.y < 0) {
      vp.y = (int) (vp.y * D);
    }
    if (vp.x + viewport.getWidth() - label.getWidth() > 0) {
      vp.x = (int) (vp.x - (vp.x + viewport.getWidth() - label.getWidth()) * (1d - D));
    }
    if (vp.y + viewport.getHeight() > label.getHeight()) {
      vp.y = (int) (vp.y - (vp.y + viewport.getHeight() - label.getHeight()) * (1d - D));
    }
    viewport.setViewPosition(vp);
    if (isInside(viewport, label)) {
      outside.stop();
    }
  }

  @Override public void mousePressed(MouseEvent e) {
    e.getComponent().setCursor(hc);
    startPt.setLocation(e.getPoint());
    inside.stop();
    outside.stop();
  }

  @Override public void mouseDragged(MouseEvent e) {
    Point pt = e.getPoint();
    JViewport viewport = (JViewport) SwingUtilities.getUnwrappedParent(label);
    Point vp = viewport.getViewPosition();
    vp.translate(startPt.x - pt.x, startPt.y - pt.y);
    viewport.setViewPosition(vp);
    delta.setLocation(SPEED * (pt.x - startPt.x), SPEED * (pt.y - startPt.y));
    startPt.setLocation(pt);
  }

  @Override public void mouseReleased(MouseEvent e) {
    e.getComponent().setCursor(dc);
    JViewport viewport = (JViewport) SwingUtilities.getUnwrappedParent(label);
    if (isInside(viewport, label)) {
      inside.start();
    } else {
      outside.start();
    }
  }

  @Override public void hierarchyChanged(HierarchyEvent e) {
    Component c = e.getComponent();
    if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0
        && !c.isDisplayable()) {
      inside.stop();
      outside.stop();
    }
  }
}

References

2010/08/09

Drag and Drop between JLists

Code

class ListItemTransferHandler extends TransferHandler {
  protected final DataFlavor localObjectFlavor;
  protected JList<?> source;
  protected int[] indices;
  protected int addIndex = -1;
  protected int addCount;

  protected ListItemTransferHandler() {
    super();
    localObjectFlavor = new DataFlavor(List.class, "List of items");
  }

  @Override protected Transferable createTransferable(JComponent c) {
    source = (JList<?>) c;
    indices = source.getSelectedIndices();
    List<?> transferredObjects = source.getSelectedValuesList();
    return new Transferable() {
      @Override public DataFlavor[] getTransferDataFlavors() {
        return new DataFlavor[] {localObjectFlavor};
      }

      @Override public boolean isDataFlavorSupported(DataFlavor flavor) {
        return Objects.equals(localObjectFlavor, flavor);
      }

      @Override public Object getTransferData(DataFlavor flavor)
          throws UnsupportedFlavorException, IOException {
        if (isDataFlavorSupported(flavor)) {
          return transferredObjects;
        } else {
          throw new UnsupportedFlavorException(flavor);
        }
      }
    };
  }

  @Override public boolean canImport(TransferHandler.TransferSupport info) {
    return info.isDrop() && info.isDataFlavorSupported(localObjectFlavor);
  }

  @Override public int getSourceActions(JComponent c) {
    return TransferHandler.MOVE;
  }

  @SuppressWarnings("unchecked")
  @Override public boolean importData(TransferHandler.TransferSupport info) {
    TransferHandler.DropLocation tdl = info.getDropLocation();
    if (!(tdl instanceof JList.DropLocation)) {
      return false;
    }
    JList.DropLocation dl = (JList.DropLocation) tdl;
    JList<?> target = (JList<?>) info.getComponent();
    DefaultListModel listModel = (DefaultListModel) target.getModel();
    int max = listModel.getSize();
    int index = dl.getIndex();
    index = index < 0 ? max : index;
    index = Math.min(index, max);
    addIndex = index;
    try {
      List<?> values = (List<?>) info.getTransferable().getTransferData(
        localObjectFlavor);
      for (Object o : values) {
        int i = index++;
        listModel.add(i, o);
        target.addSelectionInterval(i, i);
      }
      // ---->
      addCount = target.equals(source) ? values.size() : 0;
      // <----
      return true;
    } catch (UnsupportedFlavorException | IOException ex) {
      ex.printStackTrace();
    }
    return false;
  }
  // ...

References

2010/08/02

Transparent, Translucent JTable

Code

JScrollPane scroll = new JScrollPane(table) {
  private final TexturePaint texture = makeImageTexture();
  @Override protected JViewport createViewport() {
    return new JViewport() {
      @Override protected void paintComponent(Graphics g) {
        if (texture != null) {
          Graphics2D g2 = (Graphics2D) g;
          g2.setPaint(texture);
          g2.fillRect(0, 0, getWidth(), getHeight());
        }
        super.paintComponent(g);
      }
    };
  }
};
Color alphaZero = new Color(0x0, true);
table.setOpaque(false);
table.setBackground(alphaZero);
scroll.getViewport().setOpaque(false);
scroll.getViewport().setBackground(alphaZero);

References

2010/07/20

create a JCheckBox rollover effect in a JTable

Code

class RolloverBooleanRenderer extends JCheckBox implements TableCellRenderer, UIResource {
  private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
  private final HighlightListener highlighter;

  public RolloverBooleanRenderer(HighlightListener highlighter) {
    super();
    this.highlighter = highlighter;
    setHorizontalAlignment(SwingConstants.CENTER);
    setBorderPainted(true);
    setRolloverEnabled(true);
    setOpaque(true);
  }

  @Override public Component getTableCellRendererComponent(JTable table, Object value,
        boolean isSelected, boolean hasFocus, int row, int column) {
    if (highlighter.isHighlightableCell(row, column)) {
      getModel().setRollover(true);
    } else {
      getModel().setRollover(false);
    }
    if (isSelected) {
      setForeground(table.getSelectionForeground());
      super.setBackground(table.getSelectionBackground());
    } else {
      setForeground(table.getForeground());
      setBackground(table.getBackground());
    }
    setSelected((value != null && ((Boolean) value).booleanValue()));
    if (hasFocus) {
      setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
    } else {
      setBorder(noFocusBorder);
    }
    return this;
  }
}

References

2010/06/15

Translucent JFrame

Code

JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame();
// com.sun.awt.AWTUtilities.setWindowOpacity(frame, .5f);
com.sun.awt.AWTUtilities.setWindowOpaque(frame, false); // 6u14
// 1.7.0 frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel p = new JPanel();
p.add(new JButton("JButton"));
p.setBackground(new Color(.5f, .8f, .5f, .5f));
frame.getContentPane().add(p);
frame.setSize(320, 240);
frame.setLocationRelativeTo(null);
frame.setVisible(true);

References

2010/05/10

Custom Decorated TitleBar JFrame

Code

class ResizeWindowListener extends MouseAdapter {
  private Rectangle startSide = null;
  private final JFrame frame;
  public ResizeWindowListener(JFrame frame) {
    this.frame = frame;
  }

  @Override public void mousePressed(MouseEvent e) {
    startSide = frame.getBounds();
  }

  @Override public void mouseDragged(MouseEvent e) {
    if (startSide == null) return;
    Component c = e.getComponent();
    if (c == topleft) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
      startSide.x += e.getX();
      startSide.width -= e.getX();
    } else if (c == top) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
    } else if (c == topright) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
      startSide.width += e.getX();
    } else if (c == left) {
      startSide.x += e.getX();
      startSide.width -= e.getX();
    } else if (c == right) {
      startSide.width += e.getX();
    } else if (c == bottomleft) {
      startSide.height += e.getY();
      startSide.x += e.getX();
      startSide.width -= e.getX();
    } else if (c == bottom) {
      startSide.height += e.getY();
    } else if (c == bottomright) {
      startSide.height += e.getY();
      startSide.width += e.getX();
    }
    frame.setBounds(startSide);
  }
}

References

2010/04/05

JTabbedPane selected tab height

Code

class WindowsTabHeightTabbedPaneUI extends WindowsTabbedPaneUI {
  private static final int TAB_AREA_HEIGHT = 32;
  @Override protected int calculateTabHeight(
      int tabPlacement, int tabIndex, int fontHeight) {
    return TAB_AREA_HEIGHT;
  }
  @Override protected void paintTab(
      Graphics g, int tabPlacement, Rectangle[] rects,
      int tabIndex, Rectangle iconRect, Rectangle textRect) {
    if (tabPane.getSelectedIndex() != tabIndex
        && tabPlacement != JTabbedPane.LEFT
        && tabPlacement != JTabbedPane.RIGHT) {
      int tabHeight = TAB_AREA_HEIGHT / 2 + 3;
      rects[tabIndex].height = tabHeight;
      if (tabPlacement == JTabbedPane.TOP) {
        rects[tabIndex].y = TAB_AREA_HEIGHT - tabHeight + 3;
      }
    }
    super.paintTab(g, tabPlacement, rects, tabIndex, iconRect, textRect);
  }
}

References

2010/03/11

Non Selectable JComboBox Items

Code

class DisableItemComboBox<E> extends JComboBox<E> {
  private final Set<Integer> disableIndexSet = new HashSet<>();
  private boolean isDisableIndex;
  private final Action up = new AbstractAction() {
    @Override public void actionPerformed(ActionEvent e) {
      int si = getSelectedIndex();
      for (int i = si - 1; i >= 0; i--) {
        if (!disableIndexSet.contains(i)) {
          setSelectedIndex(i);
          break;
        }
      }
    }
  };
  private final Action down = new AbstractAction() {
    @Override public void actionPerformed(ActionEvent e) {
      int si = getSelectedIndex();
      for (int i = si + 1; i < getModel().getSize(); i++) {
        if (!disableIndexSet.contains(i)) {
          setSelectedIndex(i);
          break;
        }
      }
    }
  };

  public DisableItemComboBox() {
    super();
  }

  public DisableItemComboBox(ComboBoxModel<E> aModel) {
    super(aModel);
  }

  public DisableItemComboBox(E[] items) {
    super(items);
  }

  @Override public void updateUI() {
    super.updateUI();
    setRenderer(new DefaultListCellRenderer() {
      @Override public Component getListCellRendererComponent(
          JList list, Object value, int index,
          boolean isSelected, boolean cellHasFocus) {
        Component c;
        if (disableIndexSet.contains(index)) {
          c = super.getListCellRendererComponent(
              list, value, index, false, false);
          c.setEnabled(false);
        } else {
          c = super.getListCellRendererComponent(
              list, value, index, isSelected, cellHasFocus);
          c.setEnabled(true);
        }
        return c;
      }
    });
    ActionMap am = getActionMap();
    am.put("selectPrevious3", up);
    am.put("selectNext3", down);
    InputMap im = getInputMap();
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "selectPrevious3");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP, 0), "selectPrevious3");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "selectNext3");
    im.put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_DOWN, 0), "selectNext3");
  }

  public void setDisableIndex(Set<Integer> set) {
    disableIndexSet.clear();
    for (Integer i: set) {
      disableIndexSet.add(i);
    }
  }

  @Override public void setPopupVisible(boolean v) {
    if (!v && isDisableIndex) {
      isDisableIndex = false;
    } else {
      super.setPopupVisible(v);
    }
  }

  @Override public void setSelectedIndex(int index) {
    if (disableIndexSet.contains(index)) {
      isDisableIndex = true;
    } else {
      // isDisableIndex = false;
      super.setSelectedIndex(index);
    }
  }
}

References

2010/02/25

TabTransferHandler

Code

class TabTransferHandler extends TransferHandler {
  private final DataFlavor localObjectFlavor = new DataFlavor(DnDTabData.class, "DnDTabData");
  private DnDTabbedPane source = null;

  @Override protected Transferable createTransferable(JComponent c) {
    System.out.println("createTransferable");
    if (c instanceof DnDTabbedPane) source = (DnDTabbedPane) c;
    return new Transferable() {
      @Override public DataFlavor[] getTransferDataFlavors() {
        return new DataFlavor[] {localObjectFlavor};
      }

      @Override public boolean isDataFlavorSupported(DataFlavor flavor) {
        return Objects.equals(localObjectFlavor, flavor);
      }

      @Override public Object getTransferData(DataFlavor flavor) 
            throws UnsupportedFlavorException, IOException {
        if (isDataFlavorSupported(flavor)) {
          return new DnDTabData(source);
        } else {
           throw new UnsupportedFlavorException(flavor);
        }
      }
    };
  }

  @Override public boolean canImport(TransferSupport support) {
    // System.out.println("canImport");
    if (!support.isDrop() || !support.isDataFlavorSupported(localObjectFlavor)) {
      return false;
    }
    support.setDropAction(TransferHandler.MOVE);
    DropLocation tdl = support.getDropLocation();
    Point pt = tdl.getDropPoint();
    DnDTabbedPane target = (DnDTabbedPane) support.getComponent();
    target.autoScrollTest(pt);
    DnDTabbedPane.DropLocation dl =
      (DnDTabbedPane.DropLocation) target.dropLocationForPoint(pt);
    int idx = dl.getIndex();
    boolean isDroppable = false;

    if (target == source) {
      isDroppable = target.getTabAreaBounds().contains(pt) && idx >= 0 &&
                   idx != target.dragTabIndex && idx != target.dragTabIndex + 1;
    } else {
      if (source != null && target != source.getComponentAt(source.dragTabIndex)) {
        isDroppable = target.getTabAreaBounds().contains(pt) && idx >= 0;
      }
    }

    Component c = target.getRootPane().getGlassPane();
    c.setCursor(isDroppable?DragSource.DefaultMoveDrop:DragSource.DefaultMoveNoDrop);
    if (isDroppable) {
      support.setShowDropLocation(true);
      dl.setDroppable(true);
      target.setDropLocation(dl, null, true);
      return true;
    } else {
      support.setShowDropLocation(false);
      dl.setDroppable(false);
      target.setDropLocation(dl, null, false);
      return false;
    }
  }

  private BufferedImage makeDragTabImage(DnDTabbedPane tabbedPane) {
    Rectangle rect = tabbedPane.getBoundsAt(tabbedPane.dragTabIndex);
    BufferedImage image = new BufferedImage(
      tabbedPane.getWidth(), tabbedPane.getHeight(), BufferedImage.TYPE_INT_ARGB);
    Graphics g = image.getGraphics();
    tabbedPane.paint(g);
    g.dispose();
    if (rect.x < 0) {
      rect.translate(-rect.x, 0);
    }
    if (rect.y < 0) {
      rect.translate(0, -rect.y);
    }
    if (rect.x + rect.width > image.getWidth()) {
      rect.width = image.getWidth() - rect.x;
    }
    if (rect.y + rect.height > image.getHeight()) {
      rect.height = image.getHeight() - rect.y;
    }
    return image.getSubimage(rect.x, rect.y, rect.width, rect.height);
  }

  @Override public int getSourceActions(JComponent c) {
    System.out.println("getSourceActions");
    if (c instanceof DnDTabbedPane) {
      DnDTabbedPane src = (DnDTabbedPane) c;
      c.getRootPane().setGlassPane(new GhostGlassPane(src));
      if (src.dragTabIndex < 0) {
        return TransferHandler.NONE;
      }
      setDragImage(makeDragTabImage(src));
      c.getRootPane().getGlassPane().setVisible(true);
      return TransferHandler.MOVE;
    }
    return TransferHandler.NONE;
  }

  @Override public boolean importData(TransferSupport support) {
    System.out.println("importData");

    DnDTabbedPane target = (DnDTabbedPane) support.getComponent();
    DnDTabbedPane.DropLocation dl = target.getDropLocation();
    try {
      DnDTabbedPane source = (DnDTabbedPane) support.getTransferable()
        .getTransferData(localObjectFlavor);
      int index = dl.getIndex(); //boolean insert = dl.isInsert();
      if (target == source) {
        source.convertTab(source.dragTabIndex, index);
      } else {
        source.exportTab(source.dragTabIndex, target, index);
      }
      return true;
    } catch (UnsupportedFlavorException ufe) {
      ufe.printStackTrace();
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }
    return false;
  }

  @Override protected void exportDone(JComponent c, Transferable data, int action) {
    System.out.println("exportDone");
    DnDTabbedPane src = (DnDTabbedPane) c;
    c.getRootPane().getGlassPane().setVisible(false);
    src.setDropLocation(null, null, false);
  }
}

References

2010/01/12

make Explorer like JTable File List

Code

// @see SwingUtilities2.pointOutsidePrefSize(...)
private static Rectangle getCellRect2(JTable table, int row, int col) {
  TableCellRenderer tcr = table.getCellRenderer(row, col);
  Object value = table.getValueAt(row, col);
  Component cell = tcr.getTableCellRendererComponent(
      table, value, false, false, row, col);
  Dimension itemSize = cell.getPreferredSize();
  Rectangle cellBounds = table.getCellRect(row, col, false);
  cellBounds.width = itemSize.width;
  return cellBounds;
  // FontMetrics fm = table.getFontMetrics(table.getFont());
  // Object o = table.getValueAt(row, col);
  // int w = fm.stringWidth(o.toString()) + 16 + 2 + 2;
  // Rectangle rect = table.getCellRect(row, col, true);
  // rect.setSize(w, rect.height);
  // return rect;
}

References