unmarshaller.setEventHandler(
new ValidationEventHandler() {
public boolean handleEvent(ValidationEvent event ) {
ValidationEventLocator locator = event.getLocator();
String errorMessage = "Line:Column[" + locator.getLineNumber() + ":" + locator.getColumnNumber() + "]:" + event.getMessage();
throw new RuntimeException(errorMessage, event.getLinkedException());
}
});
Thursday, 14 March 2013
How to make JAXB marshal/unmarshal show errors
JAXB by default silently ignores errors. Try adding this code to throw an exception if something goes wrong.
Wednesday, 3 October 2012
Java Swing PDF Viewer
I'll use pdf-renderer to create an pdf viewer in java swing application.
PDF Viewer
Tester
screen shots
- Dependencies
org.swinglabs pdf-renderer 1.0.5 com.google.guava guava 13.0.1
import com.google.common.base.CharMatcher;
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
import com.sun.pdfview.PagePanel;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import static com.google.common.base.Strings.isNullOrEmpty;
public class PdfViewer extends JPanel {
private static enum Navigation {GO_FIRST_PAGE, FORWARD, BACKWARD, GO_LAST_PAGE, GO_N_PAGE}
private static final CharMatcher POSITIVE_DIGITAL = CharMatcher.anyOf("0123456789");
private static final String GO_PAGE_TEMPLATE = "%s of %s";
private static final int FIRST_PAGE = 1;
private int currentPage = FIRST_PAGE;
private JButton btnFirstPage;
private JButton btnPreviousPage;
private JTextField txtGoPage;
private JButton btnNextPage;
private JButton btnLastPage;
private PagePanel pagePanel;
private PDFFile pdfFile;
public PdfViewer() {
initial();
}
private void initial() {
setLayout(new BorderLayout(0, 0));
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
add(topPanel, BorderLayout.NORTH);
btnFirstPage = createButton("|<<");
topPanel.add(btnFirstPage);
btnPreviousPage = createButton("<<");
topPanel.add(btnPreviousPage);
txtGoPage = new JTextField(10);
txtGoPage.setHorizontalAlignment(JTextField.CENTER);
topPanel.add(txtGoPage);
btnNextPage = createButton(">>");
topPanel.add(btnNextPage);
btnLastPage = createButton(">>|");
topPanel.add(btnLastPage);
JScrollPane scrollPane = new JScrollPane();
add(scrollPane, BorderLayout.CENTER);
JPanel viewPanel = new JPanel(new BorderLayout(0, 0));
scrollPane.setViewportView(viewPanel);
pagePanel = new PagePanel();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
pagePanel.setPreferredSize(screenSize);
viewPanel.add(pagePanel, BorderLayout.CENTER);
disableAllNavigationButton();
btnFirstPage.addActionListener(new PageNavigationListener(Navigation.GO_FIRST_PAGE));
btnPreviousPage.addActionListener(new PageNavigationListener(Navigation.BACKWARD));
btnNextPage.addActionListener(new PageNavigationListener(Navigation.FORWARD));
btnLastPage.addActionListener(new PageNavigationListener(Navigation.GO_LAST_PAGE));
txtGoPage.addActionListener(new PageNavigationListener(Navigation.GO_N_PAGE));
}
private JButton createButton(String text) {
JButton button = new JButton(text);
button.setPreferredSize(new Dimension(55, 20));
return button;
}
private void disableAllNavigationButton() {
btnFirstPage.setEnabled(false);
btnPreviousPage.setEnabled(false);
btnNextPage.setEnabled(false);
btnLastPage.setEnabled(false);
}
private boolean isMoreThanOnePage(PDFFile pdfFile) {
return pdfFile.getNumPages() > 1;
}
private class PageNavigationListener implements ActionListener {
private final Navigation navigation;
private PageNavigationListener(Navigation navigation) {
this.navigation = navigation;
}
public void actionPerformed(ActionEvent e) {
if (pdfFile == null) {
return;
}
int numPages = pdfFile.getNumPages();
if (numPages <= 1) {
disableAllNavigationButton();
} else {
if (navigation == Navigation.FORWARD && hasNextPage(numPages)) {
goPage(currentPage, numPages);
}
if (navigation == Navigation.GO_LAST_PAGE) {
goPage(numPages, numPages);
}
if (navigation == Navigation.BACKWARD && hasPreviousPage()) {
goPage(currentPage, numPages);
}
if (navigation == Navigation.GO_FIRST_PAGE) {
goPage(FIRST_PAGE, numPages);
}
if (navigation == Navigation.GO_N_PAGE) {
String text = txtGoPage.getText();
boolean isValid = false;
if (!isNullOrEmpty(text)) {
boolean isNumber = POSITIVE_DIGITAL.matchesAllOf(text);
if (isNumber) {
int pageNumber = Integer.valueOf(text);
if (pageNumber >= 1 && pageNumber <= numPages) {
goPage(Integer.valueOf(text), numPages);
isValid = true;
}
}
}
if (!isValid) {
JOptionPane.showMessageDialog(PdfViewer.this, format("Invalid page number '%s' in this document", text));
txtGoPage.setText(format(GO_PAGE_TEMPLATE, currentPage, numPages));
}
}
}
}
private void goPage(int pageNumber, int numPages) {
currentPage = pageNumber;
PDFPage page = pdfFile.getPage(currentPage);
pagePanel.showPage(page);
boolean notFirstPage = isNotFirstPage();
btnFirstPage.setEnabled(notFirstPage);
btnPreviousPage.setEnabled(notFirstPage);
txtGoPage.setText(format(GO_PAGE_TEMPLATE, currentPage, numPages));
boolean notLastPage = isNotLastPage(numPages);
btnNextPage.setEnabled(notLastPage);
btnLastPage.setEnabled(notLastPage);
}
private boolean hasNextPage(int numPages) {
return (++currentPage) <= numPages;
}
private boolean hasPreviousPage() {
return (--currentPage) >= FIRST_PAGE;
}
private boolean isNotLastPage(int numPages) {
return currentPage != numPages;
}
private boolean isNotFirstPage() {
return currentPage != FIRST_PAGE;
}
}
public PagePanel getPagePanel() {
return pagePanel;
}
public void setPDFFile(PDFFile pdfFile) {
this.pdfFile = pdfFile;
currentPage = FIRST_PAGE;
disableAllNavigationButton();
txtGoPage.setText(format(GO_PAGE_TEMPLATE, FIRST_PAGE, pdfFile.getNumPages()));
boolean moreThanOnePage = isMoreThanOnePage(pdfFile);
btnNextPage.setEnabled(moreThanOnePage);
btnLastPage.setEnabled(moreThanOnePage);
}
}
Line:58-59 automatically match the current screen resolution. The default is 800*600. The utility method "format" is here: format
public static void main(String[] args) {
try {
long heapSize = Runtime.getRuntime().totalMemory();
System.out.println("Heap Size = " + heapSize);
JFrame frame = new JFrame("PDF Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//load a pdf from a byte buffer
File file = new File("/Users/Sean/Documents/test-pdf.pdf");
RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
final PDFFile pdffile = new PDFFile(buf);
PdfViewer pdfViewer = new PdfViewer();
pdfViewer.setPDFFile(pdffile);
frame.add(pdfViewer);
frame.pack();
frame.setVisible(true);
PDFPage page = pdffile.getPage(0);
pdfViewer.getPagePanel().showPage(page);
} catch (IOException e) {
e.printStackTrace();
}
}
Wednesday, 19 September 2012
How to create or initialize Generic Type Array
Limitation: It's not work if input array is null.
public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive) {
if (array == null) {
return null;
}
if (startIndexInclusive < 0) {
startIndexInclusive = 0;
}
if (endIndexExclusive > array.length) {
endIndexExclusive = array.length;
}
Class<?> type = array.getClass().getComponentType();
int newSize = endIndexExclusive - startIndexInclusive;
if (newSize < 0) {
final T[] emptyArray = (T[]) Array.newInstance(type, 0);
return emptyArray;
}
T[] subarray = (T[]) Array.newInstance(type, newSize);
System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
return subarray;
}
public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive, Class<T>> clazz) {
T[] emptyArray = (T[]) Array.newInstance(clazz, 0);
if (array == null) {
return emptyArray;
}
if (startIndexInclusive < 0) {
startIndexInclusive = 0;
}
if (endIndexExclusive > array.length) {
endIndexExclusive = array.length;
}
if (newSize < 0) {
return emptyArray;
}
T[] subarray = (T[]) Array.newInstance(clazz, newSize);
System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
return subarray;
}
Tuesday, 18 September 2012
Java Swing JTextField: Number only and give length
Solution 1
Simple but It can't work for "CTRL + V" scenario
private class NumberOnlyAdapter extends KeyAdapter {
private final int maxLength;
private NumberOnlyAdapter(int maxLength) {
this.maxLength = maxLength;
}
@Override
public void keyTyped(KeyEvent e) {
char typed = e.getKeyChar();
CharMatcher notDigit = noneOf("0123456789").and(isNot((char) VK_BACK_SPACE)).and(isNot((char) VK_DELETE));
JTextField textField = (JTextField) e.getComponent();
if (notDigit.apply(typed) || textField.getText().length() >= maxLength) {
e.consume();
}
}
}
...
int maxLength = 8;
JTextField textField = new JTextField();
textField.addKeyListener(new NumberOnlyAdapter(maxLength));
It's work for all conditions
import static org.apache.commons.lang3.StringUtils.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
public class NumericOnlyAndMaxLengthFilter extends DocumentFilter {
private int maxLength = 0;
public NumericOnlyAndMaxLengthFilter() {
// allow any length of numeric
}
public NumericOnlyAndMaxLengthFilter(int maxLength) {
this.maxLength = maxLength;
}
@Override
public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
if (isNumeric(string)) {
if (isExceedMaxLength(fb, string)) {
return;
}
super.insertString(fb, offset, string, attr);
}
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
if (isNumeric(text)) {
if (isExceedMaxLength(fb, text)) {
return;
}
super.insertString(fb, offset, text, attrs);
}
}
private boolean isExceedMaxLength(FilterBypass fb, String text) {
return maxLength > 0 && (fb.getDocument().getLength() + text.length()) > maxLength;
}
}
...
int maxLength = 8;
JTextField textField = new JTextField();
((AbstractDocument)textField .getDocument()).setDocumentFilter(new NumericOnlyAndMaxLengthFilter(maxLength));
Thursday, 13 September 2012
Maven generate HTML Junit report
- add to pom.xml
org.apache.maven.plugins maven-surefire-plugin true org.jvnet.maven-antrun-extended-plugin maven-antrun-extended-plugin test-reports test run org.apache.ant ant-junit 1.8.4 org.apache.ant ant-trax 1.8.0
$mvn test -Dmaven.test.failure.ignore=true
Wednesday, 5 September 2012
Java - better performance String formatter
/**
* Substitutes each {@code %s} in {@code template} with an argument. These
* are matched by position - the first {@code %s} gets {@code args[0]}, etc.
* If there are more arguments than placeholders, the unmatched arguments will
* be appended to the end of the formatted message in square braces.
*
* @param template a non-null string containing 0 or more {@code %s}
* placeholders.
* @param args the arguments to be substituted into the message
* template. Arguments are converted to strings using
* {@link String#valueOf(Object)}. Arguments can be null.
*/
public static String format(String template, Object... args) {
template = String.valueOf(template); // null -> "null"
// start substituting the arguments into the '%s' placeholders
StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
int templateStart = 0;
int i = 0;
while (i < args.length) {
int placeholderStart = template.indexOf("%s", templateStart);
if (placeholderStart == -1) {
break;
}
builder.append(template.substring(templateStart, placeholderStart));
builder.append(args[i++]);
templateStart = placeholderStart + 2;
}
builder.append(template.substring(templateStart));
// if we run out of placeholders, append the extra args in square braces
if (i < args.length) {
builder.append(" [");
builder.append(args[i++]);
while (i < args.length) {
builder.append(", ");
builder.append(args[i++]);
}
builder.append(']');
}
return builder.toString();
}
public static void main(String[] args) {
Stopwatch stopwatch = new Stopwatch();
stopwatch.start();
String result = Formatter.format("My name is: %s. I was start from: %s. ", "Sean", "25/05/2012", "another value here");
stopwatch.stop();
System.out.println(stopwatch.elapsedTime(TimeUnit.NANOSECONDS));
System.out.println(result);
stopwatch.reset();
stopwatch.start();
result = String.format("My name is: %s. I was start from: %s.", "Sean", "25/05/2012", "another value here");
stopwatch.stop();
System.out.println(stopwatch.elapsedTime(TimeUnit.NANOSECONDS));
System.out.println(result);
}
Tuesday, 14 August 2012
Read line (or get line count) from JTextArea with wrap enabled
public class Demo {
JTextArea textArea = new JTextArea(text, 5, 50);
textArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
textArea.setEditable(false);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
private static String[] readLinesFromTextArea(JTextArea textArea, int limitRows) {
String content = textArea.getText();
String[] lines = new String[limitRows];
Arrays.fill(lines, "");
try {
int count = 0;
int offs = 0;
while (offs < content.length() && count < limitRows ) {
int end = Utilities.getRowEnd(textArea, offs);
String line = StringUtils.substring(content, offs, end);
lines[count++] = line;
offs = end + 1;
}
} catch (BadLocationException e) {
log.error("Read line from 'Other' text area failed. Cause:\n", Throwables.getStackTraceAsString(e));
}
return lines;
}
}
Subscribe to:
Posts (Atom)
