(function ($) { $.fn.forceNumeric = function () { return this.each(function () { // bind handler of 'paste' event $(this).bind( { paste: function (e) { var content = e.originalEvent.clipboardData.getData('text/plain'); var regExp = /^\d+$/; if (!regExp.test($.trim(content))) { e.preventDefault(); } } }); $(this).keydown(function (e) { var key = e.which || e.keyCode; if (!e.shiftKey && !e.altKey) { if ((key >= 48 && key <= 57 || // Numeric keypad key >= 96 && key <= 105 || // comma, period and minus, . on keypad key == 190 || key == 188 || key == 109 || key == 110 || // Backspace and Tab and Enter key == 8 || key == 9 || key == 13 || // Home and End key == 35 || key == 36 || // left and right arrows key == 37 || key == 39 || // Del and Ins key == 46 || key == 45) && !e.ctrlKey) { return true; } // Allow: Ctrl+C, Ctrl+V, Ctrl+X if ((e.keyCode == 67 || e.keyCode == 86 || e.keyCode == 88) && (e.ctrlKey === true || e.metaKey === true)) { return true; } } return e.preventDefault(); }); }); }; }(jQuery));
Wednesday, 11 September 2013
create own support Ctrl+v, Ctrl+c, Ctrl+X and 'Numeric only' jquery plugin
Labels:
javascript,
JQuery
Monday, 26 August 2013
tips of jqgrid
- Define own date formatter
$.extend($.fn.fmatter , { dateFormatter : function(cellvalue, options, rowObject) { if (cellvalue) { // parseExact just returns 'null' if the date you are trying to // format is not in the exact format specified var parsedDate = Date.parseExact(cellvalue, "yyyy-MM-ddTHH:mm:ss"); if(parsedDate == null ) parsedDate = new Date(cellvalue); // if parsed date is null, just used the passed cell value; otherwise, // transform the date to desired format var formattedDate = parsedDate ? parsedDate.toString("yyyy-MM-dd HH:mm:ss") : cellvalue; return formattedDate; } else { return ''; } } });
$.extend($.fn.fmatter , { dynamicLink : function (cellValue, options, rowObject) { return "<a href='#' onclick=\"viewReport('" + rowObject.custodyRefNumber + "', '" + rowObject.docketNumber + "');return false;\">view report</a>"; } });
function resizeJqgridWidth() { if (grid = $('.ui-jqgrid-btable:visible')) { grid.each(function(index) { gridId = $(this).attr('id'); gridParentWidth = $('#gbox_' + gridId).parent().width() - 5; $('#' + gridId).setGridWidth(gridParentWidth); }); } }
function convertDotNotationStringToNestJsonObject(data) { var obj = {}, t, parts, part; for (var k in data) { t = obj; parts = k.split('.'); var key = parts.pop(); while (parts.length) { part = parts.shift(); t = t[part] = t[part] || {}; } t[key] = data[k] } return obj; }
Labels:
javascript,
jqgrid
Thursday, 11 April 2013
Practice of customize JAXB Schema-2-JAVA use xjc
JAXB Marshalling with Custom Namespace Prefixes
Target xsd file
pom.xml
Generated classes by xjc
EmployeeType.java
Payment.java
USAddress.java
ObjectFactory.java
package-info.java
- You have an XML schema with multiple XML namespaces.
- You generate a JAXB model with xjc.
- You build a JAXB document model and use the JAXB Marshaller to create XML from the model.
- You want to override the default namespace prefixes ns1, ns2, ... created by the Marshaller.
- You want use customization java package
- You want use more meanful java property name to replace xml element/attribute, default use element/attribute name
- You want to override the default XmlAdapter Adapter1.java, Adapter2.java... created by xjc.
Target xsd file
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://seanshou.blogspot.com/XMLSchema" targetNamespace="http://seanshou.blogspot.com/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="comment" type="xs:string"/> <xs:element name="employee" type="ns1:EmployeeType"> <xs:annotation> <xs:documentation>Comment describing your root element</xs:documentation> </xs:annotation> </xs:element> <xs:complexType name="USAddress"> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="street" type="xs:string"/> <xs:element name="city" type="xs:string"/> <xs:element name="state" type="xs:string"/> <xs:element name="zip" type="xs:string"/> </xs:sequence> <xs:attribute name="country" type="xs:NMTOKEN" use="required" fixed="US"/> </xs:complexType> <xs:complexType name="EmployeeType"> <xs:sequence> <xs:element name="address" type="ns1:USAddress"/> <xs:element name="paySlip" type="ns1:payment"/> <xs:element ref="ns1:comment"/> </xs:sequence> <xs:attribute name="userId" type="xs:int" use="required"/> </xs:complexType> <xs:complexType name="payment"> <xs:sequence> <xs:element name="baseSalary" type="xs:int"/> <xs:element name="supernation" type="xs:integer" nillable="true" minOccurs="0"/> <xs:element name="bonus" type="xs:integer" nillable="true" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:schema>
- line[5]: The generated classes by xjc will qualified by namespace: http://seanshou.blogspot.com/XMLSchema
- line[33,34]: The customization to use use-defined adapter BigIntegerXmlAdapter for xs:integer
<?xml version="1.0" encoding="UTF-8"?> <jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" xmlns:namespace="http://jaxb2-commons.dev.java.net/namespace-prefix" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd http://jaxb2-commons.dev.java.net/namespace-prefix http://java.net/projects/jaxb2-commons/sources/svn/content/namespace-prefix/trunk/src/main/resources/prefix-namespace-schema.xsd" jxb:extensionBindingPrefixes="xjc" version="2.1"> <jxb:bindings schemaLocation="Employee-Definiation.xsd" node="/xs:schema"> <jxb:globalBindings fixedAttributeAsConstantProperty="false" collectionType="java.util.ArrayList" typesafeEnumBase="xs:NCName" choiceContentProperty="false" typesafeEnumMemberName="generateError" enableFailFastCheck="false" generateIsSetMethod="false" underscoreBinding="asCharInWord"> <xjc:javaType name="java.math.BigInteger" xmlType="xs:integer" adapter="com.blogspot.seanshou.jaxb.adapter.BigIntegerXmlAdapter"/> </jxb:globalBindings> <jxb:schemaBindings> <jxb:package name="com.blogspot.seanshou.jaxb.xml"/> </jxb:schemaBindings> <jxb:bindings> <namespace:prefix name="NS1"/> </jxb:bindings> <jxb:bindings node="//xs:element[@name='employee']"> <jxb:class name="EmployeePojo"/> </jxb:bindings> <jxb:bindings node="//xs:complexType[@name='EmployeeType']"> <jxb:bindings node=".//xs:element[@name='address']"> <jxb:property name="mailAddress"/> </jxb:bindings> </jxb:bindings> </jxb:bindings> </jxb:bindings>
- line[17,18]: customize to special java type use pre-defined 'XmlAdater'
- line[21]: customize to java package name Note that this customization is per namespace. That is, even if your schema is split into multiple schema documents, you cannot put them into different packages if they are all in the same namespace
- line[24]: customize namespace prefix when XJC convert Schema-2-Java, the prefix 'NS1' will be append package-info.java use JAXB Namespace-prefix plugin
- line[26,28]: binding root xml elemment employee to java class EmployeeType
- line[30,32]: binding child xml elemment address of employee to java property mailAddress of class EmployeeType
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.blogspot.seanshou.jaxb</groupId> <artifactId>JAXB-Schema-to-Java-showcase</artifactId> <version>1.0</version> <build> <plugins> <plugin> <!-- jaxb plugin --> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <version>0.8.3</version> <configuration> <!-- <generatePackage>com.blogspot.seanshou.jaxb.xml</generatePackage> <catalog>src/main/resources/catalog.xml</catalog> --> <schemaDirectory>src/main/resources</schemaDirectory> <schemaIncludes> <include>*.xsd</include> </schemaIncludes> <bindingDirectory>src/main/resources</bindingDirectory> <bindingIncludes> <include>bindings.xml</include> </bindingIncludes> <args> <arg>-extension</arg> <arg>-Xnamespace-prefix</arg> </args> <removeOldOutput>true</removeOldOutput> </configuration> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-namespace-prefix</artifactId> <version>1.1</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.2.6</version> </dependency> <dependency> <groupId>javax.xml</groupId> <artifactId>jaxb-impl</artifactId> <version>2.1</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.1</version> </dependency> </dependencies> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> </project>Pre-defined BigIntegerXmlApater.java
package com.blogspot.seanshou.jaxb.adapter; import javax.xml.bind.DatatypeConverter; import javax.xml.bind.annotation.adapters.XmlAdapter; import java.math.BigInteger; import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.commons.lang3.StringUtils.isBlank; public class BigIntegerXmlAdapter extends XmlAdapter<String, BigInteger> { @Override public BigInteger unmarshal(String value) throws Exception { if (isBlank(value)) { return BigInteger.ZERO; } return DatatypeConverter.parseInteger(value); } @Override public String marshal(BigInteger value) throws Exception { if (value == null) { return EMPTY; } return DatatypeConverter.printInteger(value); } }
Generated classes by xjc
- EmployeePojo.java
package com.blogspot.seanshou.jaxb.xml; import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; public class EmployeePojo extends JAXBElement<EmployeeType> { protected final static QName NAME = new QName("http://seanshou.blogspot.com/XMLSchema", "employee"); public EmployeePojo(EmployeeType value) { super(NAME, ((Class) EmployeeType.class), null, value); } public EmployeePojo() { super(NAME, ((Class) EmployeeType.class), null, null); } }
- line[6]: Customized by line[26-28] in bindings.xml
package com.blogspot.seanshou.jaxb.xml; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "EmployeeType", propOrder = { "mailAddress", "paySlip", "comment" }) public class EmployeeType { @XmlElement(name = "address", required = true) protected USAddress mailAddress; @XmlElement(required = true) protected Payment paySlip; @XmlElement(required = true) protected String comment; @XmlAttribute(name = "userId", required = true) protected int userId; public USAddress getMailAddress() { return mailAddress; } public void setMailAddress(USAddress value) { this.mailAddress = value; } public Payment getPaySlip() { return paySlip; } public void setPaySlip(Payment value) { this.paySlip = value; } public String getComment() { return comment; } public void setComment(String value) { this.comment = value; } public int getUserId() { return userId; } public void setUserId(int value) { this.userId = value; } }
- line[18,19]: Customized by line[30-32] in bindings.xml
package com.blogspot.seanshou.jaxb.xml; import java.math.BigInteger; import javax.xml.bind.JAXBElement; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "payment", propOrder = { "baseSalary", "supernation", "bonus" }) public class Payment { protected int baseSalary; @XmlElementRef(name = "supernation", namespace = "http://seanshou.blogspot.com/XMLSchema", type = JAXBElement.class) protected JAXBElement<BigInteger> supernation; @XmlElementRef(name = "bonus", namespace = "http://seanshou.blogspot.com/XMLSchema", type = JAXBElement.class) protected JAXBElement<BigInteger> bonus; public int getBaseSalary() { return baseSalary; } public void setBaseSalary(int value) { this.baseSalary = value; } public JAXBElement<BigInteger> getSupernation() { return supernation; } public void setSupernation(JAXBElement<BigInteger> value) { this.supernation = value; } public JAXBElement<BigInteger> getBonus() { return bonus; } public void setBonus(JAXBElement<BigInteger> value) { this.bonus = value; } }
package com.blogspot.seanshou.jaxb.xml; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlSchemaType; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "USAddress", propOrder = { "name", "street", "city", "state", "zip" }) public class USAddress { @XmlElement(required = true) protected String name; @XmlElement(required = true) protected String street; @XmlElement(required = true) protected String city; @XmlElement(required = true) protected String state; @XmlElement(required = true) protected String zip; @XmlAttribute(name = "country", required = true) @XmlJavaTypeAdapter(CollapsedStringAdapter.class) @XmlSchemaType(name = "NMTOKEN") protected String country; public String getName() { return name; } public void setName(String value) { this.name = value; } public String getStreet() { return street; } public void setStreet(String value) { this.street = value; } public String getCity() { return city; } public void setCity(String value) { this.city = value; } public String getState() { return state; } public void setState(String value) { this.state = value; } public String getZip() { return zip; } public void setZip(String value) { this.zip = value; } public String getCountry() { if (country == null) { return "US"; } else { return country; } } public void setCountry(String value) { this.country = value; } }
package com.blogspot.seanshou.jaxb.xml; import java.math.BigInteger; import javax.xml.bind.JAXBElement; import javax.xml.bind.annotation.XmlElementDecl; import javax.xml.bind.annotation.XmlRegistry; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.namespace.QName; import com.blogspot.seanshou.jaxb.adapter.BigIntegerXmlAdapter; @XmlRegistry public class ObjectFactory { private final static QName _Comment_QNAME = new QName("http://seanshou.blogspot.com/XMLSchema", "comment"); private final static QName _PaymentSupernation_QNAME = new QName("http://seanshou.blogspot.com/XMLSchema", "supernation"); private final static QName _PaymentBonus_QNAME = new QName("http://seanshou.blogspot.com/XMLSchema", "bonus"); public ObjectFactory() { } public EmployeeType createEmployeeType() { return new EmployeeType(); } public Payment createPayment() { return new Payment(); } public USAddress createUSAddress() { return new USAddress(); } @XmlElementDecl(namespace = "http://seanshou.blogspot.com/XMLSchema", name = "comment") public JAXBElement<String> createComment(String value) { return new JAXBElement<String>(_Comment_QNAME, String.class, null, value); } @XmlElementDecl(namespace = "http://seanshou.blogspot.com/XMLSchema", name = "employee") public EmployeePojo createEmployeePojo(EmployeeType value) { return new EmployeePojo(value); } @XmlElementDecl(namespace = "http://seanshou.blogspot.com/XMLSchema", name = "supernation", scope = Payment.class) @XmlJavaTypeAdapter(BigIntegerXmlAdapter.class) public JAXBElement<BigInteger> createPaymentSupernation(BigInteger value) { return new JAXBElement<BigInteger>(_PaymentSupernation_QNAME, BigInteger.class, Payment.class, value); } @XmlElementDecl(namespace = "http://seanshou.blogspot.com/XMLSchema", name = "bonus", scope = Payment.class) @XmlJavaTypeAdapter(BigIntegerXmlAdapter.class) public JAXBElement<BigInteger> createPaymentBonus(BigInteger value) { return new JAXBElement<BigInteger>(_PaymentBonus_QNAME, BigInteger.class, Payment.class, value); } }
- line[44,50]: Customized by line[17-18] in bindings.xml
@javax.xml.bind.annotation.XmlSchema(namespace = "http://seanshou.blogspot.com/XMLSchema", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = { @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://seanshou.blogspot.com/XMLSchema", prefix = "NS1") }) package com.blogspot.seanshou.jaxb.xml;
- line[2]: Customized by line[24] in bindings.xml
- JAXB plugins: http://java.net/projects/jaxb2-commons/pages/Home
- JAXB Vendor Customizations http://jaxb.java.net/nonav/2.2.1/docs/vendorCustomizations.html#javaType
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.
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()); } });
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));
Subscribe to:
Posts (Atom)