Printing Issue for Unicode Devnagari Script in Java - swing

I am creating a Java application in Hindi Language, National Language of India for which Devanagari Script is used.
I need to print some text in Hindi Language using Java Printing API.
But, I am facing some problems and can't able to figure out what is wrong!
Here is some screenshots that will state the problem.
When I show the text preview to user in my Java Application (Using Mangal Font):
But When I print the same using Java Printing Support (Using Mangal Font):
This is the problem. Notice some diacritics (matras) are shifted to the right!
However, MS Word seems to print it correctly using same Mangal Font:
And when I use Arial Unicode font in my Java Application, it works fine, too:
That's why, I am forced to use Arial Unicode Font! But, it's size is 22MB compared to 200KB size of Mangal Font. This makes my build (jar) very big in size. Application this big in size, cannot be used in production.
I don't even know where to start to know the cause of this problem. The shifted diacritics problem when printing Devnagari Unicode Text
Update:
Here is the code:
(Make sure both font files are on classpath! Both fonts are available on Windows named "Arial Unicode MS Regular" & "Mangal".)
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.IOException;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class DevnagariTest {
private static Font createFont(String url) throws FontFormatException, IOException {
return Font.createFont(
Font.TRUETYPE_FONT,
DevnagariTest.class.getClassLoader().getResourceAsStream(url))
.deriveFont(30f);
}
private static JLabel getLabel(String text, Font font) {
JLabel label = new JLabel(text);
label.setFont(font);
return label;
}
public static void main(String[] args) throws FontFormatException, IOException {
Font mangal = createFont("mangal.ttf");
Font arial = createFont("ARIALUNI.TTF");
JFrame frame = new JFrame();
final Box box = Box.createVerticalBox();
box.add(getLabel("गणेश वार्ड रमेश सुरेश पप्पू पृथ्वी", mangal));
box.add(getLabel("गणेश वार्ड रमेश सुरेश पप्पू पृथ्वी", arial));
JButton print = new JButton("Print");
print.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new Printable() {
#Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
if (pageIndex > 0) {
return NO_SUCH_PAGE;
}
Graphics2D g2 = (Graphics2D) graphics;
g2.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
box.printAll(g2);
g2.dispose();
return PAGE_EXISTS;
}
});
try {
job.print();
} catch (PrinterException ex) {
ex.printStackTrace();
}
}
});
frame.add(box, BorderLayout.CENTER);
frame.add(print, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}

Related

how to create an emoji image with graphics2d and google noto color font

I wrote a java program to render an emoji and create a local image file with it. To do that I downloaded Google's "Noto Color Emoji" font from google website.
This is mi code:
package com.test;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
String string = "😄";
BufferedImage image;
Font font = null;
try {
font = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream("/home/sandra/.fonts/NotoColorEmoji.ttf"));
} catch (FontFormatException e) {
e.printStackTrace();
}
image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
g2.setFont(font);
g2.drawString(string, 0, g2.getFontMetrics().getAscent());
g2.dispose();
File f = new File("image.png");
if (!f.exists()) {
if (!f.createNewFile()) {
System.err.println("Can't create image file.");
}
}
try {
ImageIO.write(image, "png", f);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I tried to run it in both mac and linux (ubuntu) and the output in both cases is a black square.
Am I missing anything obvious? I also tried these commands mentioned at the end of this post (https://github.com/notwaldorf/ama/issues/53) but there is no difference on the output image.
I would appreciate any help on this as I'm quite new on emoji display.
Thanks in advance,
Sandra
Change:
image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
to:
image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
It needs TYPE_INT_ARGB.
And add this before drawString():
g2.setPaint(Color.WHITE)

How can I use DJNativeSwing JWebBrowser as the browser for the jupyter notebook?

I am using chrriis.dj.nativeswing.swtimpl.components.JWebBrowser in my swing application to open web page of a jupyter-notebook. Now my problem is when I click New->Python 3 button JWebBrowser to new a file, it always return the 404 page.
New a notebook in DJNativeSwing JWebBrowser
DJNativeSwing JWebBrowser got the 404 page
I think maybe it did not execute the javascript api in jupyter-notebook, can anyone help me make the DJNativeSwing JWebBrowser work under jupyter notebook?
The code I used:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import chrriis.common.UIUtils;
import chrriis.dj.nativeswing.swtimpl.NativeInterface;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowserWindow;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserAdapter;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserNavigationEvent;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserWindowFactory;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserWindowWillOpenEvent;
/**
* #author Christopher Deckers
*/
public class NavigationControl extends JPanel {
protected static final String LS = System.getProperty("line.separator");
public NavigationControl() {
super(new BorderLayout());
final JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
final JWebBrowser webBrowser = new JWebBrowser();
webBrowser.setBarsVisible(false);
webBrowser.setStatusBarVisible(true);
webBrowser.navigate("https://try.jupyter.org/");
tabbedPane.addTab("Controled Browser", webBrowser);
add(tabbedPane, BorderLayout.CENTER);
}
/* Standard main method to try that test as a standalone application. */
public static void main(String[] args) {
UIUtils.setPreferredLookAndFeel();
NativeInterface.open();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("DJ Native Swing Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new NavigationControl(), BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
NativeInterface.runEventPump();
}
}
Thanks Thomas K. I changed the engine of jwebbrowser to Xulrunner-24.0.en-US and the problem disappeared.

Swing - Could not reserve enough space for object heap

I tried some swing today for a GUI in java. When I want to launch the application, this error appears. Here is my source code:
package de.hoffmann;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainApplication extends javax.swing.JFrame {
private static final long serialVersionUID = 1L;
public MainApplication() {
JFrame mainFrame = new JFrame("Buchstaben-Häufigkeit");
mainFrame.setSize(600,400);
JPanel panel = new JPanel();
panel.setBackground(Color.red);
mainFrame.add(panel);
pack();
}
public static void main(String[] args) {
new MainApplication().setVisible(true);
}
}
Where's the problem
The code works fine. I suggest you to set the dimension of panel object:
panel.setSize(600,400);
and set the mainFrame to visible: mainFrame.setVisible(true);. If you have a Java heap space problem, which I find strange however, have a look in here

Updating Layout of Panel after changing label icon

I have created a project that will download the thumbnails of the images from a ftp server and display it in a panel using JLabel.
The images are being displayed but the layout of the panel only works if i call the panel once more (i.e using a button on the frame) then the layout corrects itself automatically. What am i doing wrong? Here is the code
EDIT- Updated the code with sscce
1. sscce.java
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
/**
*
* #author Rohn
*/
public class Sscce implements Interface{
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
JFrame frame=new JFrame();
frame.setVisible(true);
//frame.add(sci.);
Container c=frame.getContentPane();
JButton button=new JButton("Recall ShowCategoryImagesFunction");
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
sci.ShowCategoryImagesFunction("\\Nature\\Black And White"); //for testing purpose only
// if button is pressed then we get right layout and image load
}
});
c.setLayout(new FlowLayout());
c.add(button);
c.add(sci.ShowCategoryImagesFunction("\\Nature\\Black And White")); // default path for image load for first time
// problem in correctly loading images and text with layout
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
2. ShowCategoryImages.java
package sscce;
import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPFile;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class ShowCategoryImages{
//FTPClient client=null;
JPanel panel=new JPanel();
JLabel label=new JLabel();
FTPClient client=new FTPConnection().FTPConnection();
FTPFile[] list;
File thumbnails;
File[] files;
ImageIcon icon;
public JPanel ShowCategoryImagesFunction(String path){
// delete all the components on reload
if(panel.getComponents().length>0){
System.out.println(panel.getComponents().length);
panel.removeAll();
panel.revalidate();
panel.repaint();
}
//panel.setLayout(new GridLayout(0,4,2,2));
//panel.setLayout(new BoxLayout(panel,BoxLayout.X_AXIS));
panel.setLayout(new FlowLayout());
panel.revalidate();
panel.repaint();
panel.updateUI();
try{
//images in /wallpapers/nature/black and white/thumb
client.changeDirectory("\\Wallpapers"+path+"\\thumb"); //path of thumbnails
//temporary folder for holding images
thumbnails=new File("Thumbnails");
list=client.list();
if(thumbnails.exists()){
files = thumbnails.listFiles();
if(files!=null) { //some JVMs return null for empty dirs
for(File f: files) {
f.delete();
}
}
}
else
thumbnails.mkdir();
for(int i=0;i<list.length;i++){
System.out.println("running");
icon=new ImageIcon(thumbnails.getAbsolutePath()+"\\"+list[i].getName());
icon.getImage().flush();
client.download(client.currentDirectory()+"\\"+list[i].getName(), new java.io.File(thumbnails.getAbsolutePath()+"\\"+list[i].getName()));
label=new JLabel(list[i].getName());
label.setIcon(icon);
label.setVerticalTextPosition(SwingConstants.BOTTOM);
label.setHorizontalTextPosition(SwingConstants.CENTER);
panel.add(label);
panel.revalidate();
panel.repaint();
label.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
JLabel la=(JLabel)e.getSource();
System.out.println(la.getIcon());
}
});
}
//client.disconnect(true);
}catch(Exception e){
System.out.println(e.getMessage());
}
return panel;
}
}
3. FTPConnection.java
import it.sauronsoftware.ftp4j.FTPClient;
public class FTPConnection {
//ftp connection on local host
public static FTPClient FTPConnection(){
String ftphost="127.0.0.1";
String ftpuser="newuser";
String ftppassword="wampp";
int ftpport=21;
FTPClient client=new FTPClient();
try{
if(client.isConnected()==true){
client.disconnect(true);
};
client.connect(ftphost, ftpport);
client.login(ftpuser, ftppassword);
}
catch(Exception e){
System.out.println(e.getMessage());
}
return client;
}
}
not entirely sure what you mean with not layout, but your code is missing a revalidate/repaint after adding the labels:
// adding all labels
forEach (thumb....) {
JLabel label = new JLabel(thumb);
panel.add(label);
}
panel.revalidate();
panel.repaint();

Setting an icon for a jFrame in Netbeans swing gui builder

I've been trying to set up a window in Netbean's GUI builder, without success. I've tried accessing the JFrame, from my main class as:
public void run(){
JFrame frame = new JFrame("Title of Frame");
frame.setIconImage(Toolkit.getDefaultToolkit().getImage("org/icon.png"));
}
Which creates a new frame apart from my main window with my icon.png. I'd like to know if there is some way to gain access to the JFrame that contains the rest of my UI elements, and set that icon.
I've also tried
new SearchAppUI().setIconImage(null);
which doesn't do anything of note.
Setting the icon directly:
JFrame.setIconImage("org/icon.png");
gives me the error, non-static method setIconImage(java.awt.Image) cannot be referenced from a static context.
Is there any way to set the main JFrame's icon from either Netbean's swing desinger preview, or from my run() method?
The OP is a bit dated but just for the record, try this:
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("org/icon.png")));
NVM, I found a solution on: http://www.youtube.com/watch?v=o_35iro4b7M
Describing how to set the icon and title of a jFrame. Basically, it requires
the libraries
import javax.swing.JFrame;
import java.awt.image.BufferedImage;
import java.io.File;
import java.awt.Image;
import javax.imageio.ImageIO;
I pretty much wanted to stick with using Netbean's guibuilder for now, at least for prototyping.
First of all. It's worth to read How to Make Frames.
You can use the following example.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class FrameWithIcon extends JFrame {
public static void main(String[] args) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
FrameWithIcon myFrame = new FrameWithIcon();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setTitle("Frame with Icon");
myFrame.setLayout(new BorderLayout());
myFrame.setIconImage(
loadImageIcon("org/icon.png").getImage());
Dimension size = new Dimension(250, 100);
JPanel panel = new JPanel();
panel.setPreferredSize(size);
myFrame.add(panel, BorderLayout.LINE_START);
myFrame.setVisible(true);
myFrame.pack();
}
});
} catch (InterruptedException ex) {
} catch (InvocationTargetException ex) {
}
}
/** Returns an ImageIcon, or null if the path was invalid. */
private static ImageIcon loadImageIcon(String path) {
URL imgURL = FrameWithIcon.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
}