Skip to content

Instantly share code, notes, and snippets.

@steos
Created December 2, 2011 11:13
Show Gist options
  • Save steos/1422836 to your computer and use it in GitHub Desktop.
Save steos/1422836 to your computer and use it in GitHub Desktop.
swingx: customize jxtable hyperlinkprovider for better ux
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.hyperlink.AbstractHyperlinkAction;
import org.jdesktop.swingx.renderer.AbstractRenderer;
import org.jdesktop.swingx.renderer.CellContext;
import org.jdesktop.swingx.renderer.ComponentProvider;
import org.jdesktop.swingx.renderer.DefaultTableRenderer;
import org.jdesktop.swingx.renderer.HyperlinkProvider;
import org.jdesktop.swingx.rollover.RolloverProducer;
import org.jdesktop.swingx.rollover.RolloverRenderer;
import org.jdesktop.swingx.rollover.TableRolloverController;
import org.jdesktop.swingx.rollover.TableRolloverProducer;
import com.sun.org.apache.xerces.internal.util.URI;
public class Testing {
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JFrame f = new JFrame("asdf");
Object[][] data = new Object[][] {
{ "foobar.com", "asdf" },
{ "lorem.com", "qwer" },
{ "ipsum.com", "yxcv" },
{ null, "wertwetw" }
};
DefaultTableModel model = new DefaultTableModel(data, new Object[] {"url", "foo"}) {
@Override public Class<?> getColumnClass(int columnIndex) {
return columnIndex == 0 ? URI.class : super.getColumnClass(columnIndex);
}
};
final JXTable table = new JXTable(model) {
@Override protected RolloverProducer createRolloverProducer() {
return new TableRolloverProducer() {
@Override public void mouseMoved(MouseEvent e) {
updateRollover(e, ROLLOVER_KEY, true);
}
};
}
@Override protected TableRolloverController<JXTable> createLinkController() {
return new TableRolloverController<JXTable>() {
@Override protected RolloverRenderer getRolloverRenderer(
Point location, boolean prepare) {
if (!isRolloverText(component, location.y, location.x)) {
return null;
}
return super.getRolloverRenderer(location, prepare);
}
};
}
};
table.setEditable(false);
table.setDefaultRenderer(URI.class, new DefaultTableRenderer(new CustomHyperlinkProvider(new AbstractHyperlinkAction<String>() {
@Override public void actionPerformed(ActionEvent e) {
System.out.println(target);
}
})));
f.getContentPane().add(table);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400, 400);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
static boolean isRolloverText(JTable table, int row, int col) {
Rectangle cell = table.getCellRect(row, col, true);
Point pos = table.getMousePosition();
Object value = table.getModel().getValueAt(row, col);
TableCellRenderer cellRenderer = table.getCellRenderer(row, col);
if (cellRenderer instanceof AbstractRenderer) {
AbstractRenderer tableRenderer = (AbstractRenderer)cellRenderer;
ComponentProvider<? extends JComponent> cprov = tableRenderer.getComponentProvider();
Component comp = cprov.getRendererComponent(null);
String text = tableRenderer.getString(value);
if (text.length() == 0) {
return false;
}
int strWidth = comp.getFontMetrics(comp.getFont()).stringWidth(text);
Rectangle textBounds = new Rectangle(cell.x, cell.y, strWidth, cell.height);
return textBounds.contains(pos);
}
return false;
}
private static class CustomHyperlinkProvider extends HyperlinkProvider {
public CustomHyperlinkProvider() {
super();
}
public CustomHyperlinkProvider(AbstractHyperlinkAction linkAction) {
super(linkAction);
}
@Override protected void configureState(CellContext context) {
if (context.getComponent() != null) {
Point p = (Point) context.getComponent()
.getClientProperty(RolloverProducer.ROLLOVER_KEY);
if (p != null && (p.x >= 0) &&
(p.x == context.getColumn()) && (p.y == context.getRow()) && isRolloverText((JTable)context.getComponent(), p.y, p.x)) {
if (!rendererComponent.getModel().isRollover())
rendererComponent.getModel().setRollover(true);
} else {
if (rendererComponent.getModel().isRollover())
rendererComponent.getModel().setRollover(false);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment