Showing posts with label SwingX. Show all posts
Showing posts with label SwingX. Show all posts

Sunday, September 6, 2009

Fancy JLabels With JHLabs Filters

Recently I was looking for a way to create "fancy" text for some title panes and I stumbled over JHLabs Image Filters.





Over at JHLabs there are examples of how to create e.g., glowing text:



Or chrome like text:



To get a simmlar effect on a JLabel just replace the JLabel with a JHLabsLabel e.g.;

JLabel label = new JHLabsLabel("Hello World", new ChromeFilter(), new ShadowFilter(5, 5, 2, .7f));


Here is the code for JHLabsLabel:

/**
* Notice that this is not perfect wrt alignment to see just uncomment super.paintComponent(g)
* Maybe somebody with BasicLabelUI knowledge could help?
*
*/
public static final class JHLabsLabel extends JLabel {

private int textX;

private int textY;

private AbstractBufferedImageOp[] filters;

public JHLabsLabel(String string, AbstractBufferedImageOp... filters) {
super(string);
this.filters = filters;
}

@Override
public void paintComponent(Graphics g) {

// super.paintComponent(g);

BufferedImage img = createTextImage(getText(), getFont());

for (AbstractBufferedImageOp f : filters) {
img = f.filter(img, null);
}

// g.drawImage(f.filter(img, null), textX, textY, null);
g.drawImage(img, textX, textY, null);
}

private BufferedImage createTextImage(String text, Font font) {

Rectangle paintIconR = new Rectangle();
Rectangle paintTextR = new Rectangle();
Rectangle paintViewR = new Rectangle();
Insets paintViewInsets = new Insets(0, 0, 0, 0);

paintViewInsets = getInsets(paintViewInsets);
paintViewR.x = paintViewInsets.left;
paintViewR.y = paintViewInsets.top;
paintViewR.width = getWidth()
- (paintViewInsets.left + paintViewInsets.right);
paintViewR.height = getHeight()
- (paintViewInsets.top + paintViewInsets.bottom);

String clippedText = SwingUtilities.layoutCompoundLabel(
(JComponent) this, getFontMetrics(getFont()), text,
getIcon(), getVerticalAlignment(),
getHorizontalAlignment(), getVerticalTextPosition(),
getHorizontalTextPosition(), paintViewR, paintIconR,
paintTextR, getIconTextGap());

boolean isAntiAliased = true;
boolean usesFractionalMetrics = false;
FontRenderContext frc = new FontRenderContext(null, isAntiAliased,
usesFractionalMetrics);
TextLayout layout = new TextLayout(clippedText, font, frc);
Rectangle2D bounds = layout.getBounds();
int w = (int) Math.ceil(bounds.getWidth());
int h = (int) Math.ceil(bounds.getHeight());
BufferedImage image = new BufferedImage(w, h,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
g.setColor(new Color(0, 0, 0, 0));
g.fillRect(0, 0, w, h);
g.setColor(getForeground());
g.setFont(font);
Object antiAliased = isAntiAliased ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON
: RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
antiAliased);
Object fractionalMetrics = usesFractionalMetrics ? RenderingHints.VALUE_FRACTIONALMETRICS_ON
: RenderingHints.VALUE_FRACTIONALMETRICS_OFF;
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
fractionalMetrics);
g.drawString(clippedText, (float) -bounds.getX(), (float) -bounds
.getY());
// g.drawString(clippedText, (float) 0, (float) 0);
g.dispose();

textX = paintTextR.x;
textY = paintTextR.y;// + getFontMetrics(font).getAscent() / 2;
System.out.println(String.format("X=%d Y=%d, w=%d h=%d", textX,
textY, w, h));

return image;
}

}


I also could not resist to play to the JHLabs texture filters as background painters e.g.,

JXPanel woodPanel = new JXPanel();
woodPanel.setBackgroundPainter(new JHTexturePainter<JXPanel>(new CausticsFilter(), new SparkleFilter()));

Creates the initial background for the demo.

Here is the code for JHTexturePainter:

/**
*
* Paint the background using a combination of the JHLabs image filters
*
* @param <T>
*/
static final class JHTexturePainter<T> implements Painter<T> {

private AbstractBufferedImageOp[] filters;

public JHTexturePainter(AbstractBufferedImageOp... filters) {
this.filters = filters;
}

@Override
public void paint(Graphics2D g2d, T arg1, int w, int h) {
BufferedImage image = new BufferedImage(w, h,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
g.setColor(new Color(0, 0, 0, 0));
g.fillRect(0, 0, w, h);

for (AbstractBufferedImageOp f : filters) {
image = f.filter(image, null);
}
g.dispose();
g2d.drawImage(image, 0, 0, null);
}

}

Friday, August 21, 2009

Persisting JXTable's Column Control Settings

Here is how to persist (save/restore) the users settings (ordering of columns, visbility etc) of a JXTable using the Swing Application Framework aka SAF (JSR-296). You will need to download the jar for SAF to get the stuff below working.

(Notice that all of this is inspirede by NetBeans Platform meets Swing Application Framework: SessionStorage but without all the NetBeans clutter.)

/**
*
* @See http://puces-blog.blogspot.com/2009/04/netbeans-platform-meets-swing.html
*/

public class ModuleApplicationContext extends ApplicationContext {

private String storageDirectoryPath = "";

static {

// download from https://jdnc-incubator.dev.java.net/source/browse/jdnc-incubator/trunk/src/kleopatra/java/org/jdesktop/appframework/swingx/XProperties.java?rev=3198&view=markup
new XProperties().registerPersistenceDelegates();
}

public ModuleApplicationContext(String path) {
// Needed due to issue
// https://appframework.dev.java.net/issues/show_bug.cgi?id=112
setLocalStorage(new ModuleLocalStorage(this));
// getLocalStorage().setDirectory(getModuleSessionStorageDir(moduleInfo));
storageDirectoryPath = path;
getLocalStorage().setDirectory(new File(storageDirectoryPath));
getSessionStorage().putProperty(JXTable.class,
new XProperties.XTableProperty());
}

}



/**
* A LocalStorage for modules. It respects the direcory property in JNLP mode.

*

* Needed due to issue * HREF="https://appframework.dev.java.net/issues/show_bug.cgi?id=112">
* https://appframework.dev.java.net/issues/show_bug.cgi?id=112
*
* @author puce
*/

public class ModuleLocalStorage extends LocalStorage {

public ModuleLocalStorage(ApplicationContext context) {
super(context);
}

@Override
public boolean deleteFile(String fileName) throws IOException {
File path = new File(getDirectory(), fileName);
return path.delete();
}

@Override
public InputStream openInputFile(String fileName) throws IOException {
File path = new File(getDirectory(), fileName);
return new BufferedInputStream(new FileInputStream(path));
}

@Override
public OutputStream openOutputFile(String fileName) throws IOException {
File path = new File(getDirectory(), fileName);
return new BufferedOutputStream(new FileOutputStream(path));
}
}


Then you can use the ModuleApplicationContext to save the column control settings of a JXTable doing something like below:


public class TestJXTable extends JFrame {

String data[][] = { { "John", "Sutherland", "Student" },
{ "George", "Davies", "Student" },
{ "Melissa", "Anderson", "Associate" },
{ "Stergios", "Maglaras", "Developer" }, };

String fields[] = { "Name", "Surname", "Status" };

ModuleApplicationContext mac;

JXTable jt;

JScrollPane pane;

public static void main(String[] argv) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TestJXTable myExample = new TestJXTable(
"JXTable Example");
}
});
}

public TestJXTable(String title) {
super(title);
// save settings in users home dir
mac = new ModuleApplicationContext(System.getProperty("user.home"));
setSize(150, 150);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
dispose();
try {
jt.getParent().remove(jt);
mac.getSessionStorage().save(jt, "testTable.xml");
} catch (IOException e) {
e.printStackTrace();
}
System.exit(0);
}
});
init();
pack();
setVisible(true);
}

private void init() {
jt = new JXTable(data, fields);
jt.setColumnControlVisible(true);
jt.setName("testTable");
pane = new JScrollPane(jt);
pane.setName("testPane");
try {
mac.getSessionStorage().restore(jt, "testTable.xml");
} catch (IOException e) {
e.printStackTrace();
}
getContentPane().add(pane);
}
}

Tuesday, August 18, 2009

JXTable Striping with Substance 5.2

Here is how I got table striping to work on JXTable with Substance 5.2.


public class DefaultTableFactory implements TableFactory {

public JTable createTable() {
JXTable result = new JXTable();
return configureTable(result);
}

public JTable createTable(TableModel model) {
JXTable result = new JXTable(model);
return configureTable(result);
}

private JXTable configureTable(JXTable result) {
result.getSelectionMapper().setEnabled(false);
result.setColumnControlVisible(true);
result.setHighlighters(createHighlighter(result), new ColorHighlighter(
HighlightPredicate.ROLLOVER_ROW, null, Color.BLUE));
result.setRolloverEnabled(true);
result.setHorizontalScrollEnabled(true);
return result;
}

public CompoundHighlighter createHighlighter(JXTable t) {
ColorHighlighter first = new SubstanceHighLighter(HighlightPredicate.EVEN, t);
ColorHighlighter hl = new SubstanceHighLighter(HighlightPredicate.ODD,t);
return new CompoundHighlighter(first, hl);
}

// get striping on jxtable to work with substance
public class SubstanceHighLighter extends ColorHighlighter {

private JXTable comp;

SubstanceHighLighter(HighlightPredicate pred, JXTable t) {
setHighlightPredicate(pred);
comp = t;
}

@Override
public Color getBackground() {
return SubstanceColorUtilities.getStripedBackground(comp,
getHighlightPredicate() == HighlightPredicate.EVEN ? 1 : 0);
}

}

There is still a problem with some of the cell renders installed by JXTable...

Live Traffic Map