I have Unicode characters for all the European countries and for a few Asian countries like Japan, China, Korean. All the Unicodes are working fine for European countries except for Japan, China, Korean.
Example for Japan:
dear_name=\u30c7\u30a3\u30fc\u30e9\u30fc
Example for China:
dear_name=\u4eb2\u7231\u7684
Example for Korean:
dear_name=\uce5c\uc560\ud558\ub294
Example for Sweden (this one is working fine):
dear_name=Till
Default character encoding is UTF-8.
Template template = VelocityFactory.getTemplate("test.vm", "UTF-8");
String messageText = VelocityFactory.merge(context, template, charset);
While debuging the merge method I found out that the merged result is getting grabled here itself for chinese,Japanese,korean.
public static String merge(VelocityContext context, Template template, String charset) throws Exception {
String newResult = null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
OutputStreamWriter streamWriter;
if(charset != null && charset.length() > 0) {
streamWriter = new OutputStreamWriter(outputStream, charset);
} else {
streamWriter = new OutputStreamWriter(outputStream);
}
template.merge(context, streamWriter);
streamWriter.close();
mergedResult = outputStream.toString();
outputStream.close();
return newResult;
}
}
Below is the mail template and only for header it is displaying in correct format for Japanese, Chinese, and Korean, but not for the body:
<html>
<head>
<meta http-equiv="Content-Type" content="$contentType">
</head>
<body>
<div id="content">
<table border="0" cellpadding="0" cellspacing="0" style="margin-left: 0px;">
<tr>
<td>
<table border="0" cellpadding="0" cellspacing="0" class="textBody" style="margin-bottom: 120px;">
<tr>
<td valign="bottom" class="mainHeader" nowrap>
$velocityUtils.getMessage("test")
</td>
</tr>
<tr>
<td colspan="2">
<img src="$imageBar" class="clipped">
</td>
</tr>
</table>
<div id="info" class="textBody">$velocityUtils.getMessage("test1")<br><br></div>
</td>
</tr>
</table>
</div>
</body>
</html>
Any information how to fix this? How do i encode correctly??
try adding this to the top of your JSP
<%# page language="java" pageEncoding="UTF-8"%>
you need to specify the character sets for japanese, korean and chinese
For japanese try: charset=iso-2022-jp
For korean try: charset=iso-2022-kr
For chinese try: charset=big5
Related
I obviously am missing something here. I have a web app where the input for a form may be in English or, after a keyboard switch, Russian. The meta tag for the page is specifying that the page is UTF-8. That does not seem to matter.
If I type in "вв", two of the unicode character: CYRILLIC SMALL LETTER VE
What do I get? A string. I call getCodePoints().toArray() and I get:
[208, 178, 208, 178]
If I call chars().toArray[], I get the same.
What the heck?
I am completely in control of the web page, but of course there will be different browsers. But how can I get something back from the web page that will let me get the proper cyrillic characters?
This is on java 1.8.0_312. I can upgrade some, but not all the way to the latest java.
The page is this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>Cards</title>
<link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity = "sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin = "anonymous" />
<link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity = "sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin = "anonymous" />
<script src = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity = "sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin = "anonymous">
</script>
<meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" />
<style>.table-nonfluid { width: auto !important; }</style>
</head>
<body>
<div style = "padding: 25px 25px 25px 25px;">
<h2 align = "center">Cards</h2>
<div style = "white-space: nowrap;">
Home
<div>
<form name="f_3_1" method="post" action="/cgi-bin/WebObjects/app.woa/wo/ee67KCNaHEiW1WdpdA8JIM/2.3.1">
<table class = "table" border = "1" style = "max-width: 50%; font-size: 300%; text-align: center;">
<tr>
<td>to go</td>
</tr>
<tr>
<td><input size="25" type="text" name="3.1.5.3.3" /></td>
</tr>
<td>
<input type="submit" value="Submit" name="3.1.5.3.5" /> Skip
</td>
</table>
<input type="hidden" name="wosid" value="ee67KCNaHEiW1WdpdA8JIM" />
</form>
</div>
</div>
</div>
</body>
</html>
Hm. Well, here is at least part of the story.
I have this code:
System.out.println("start: " + start);
int[] points = start.chars().toArray();
byte[] next = new byte[points.length];
int idx = 0;
System.out.print("fixed: ");
for (int p : points) {
next[idx] = (byte)(p & 0xff);
System.out.print(Integer.toHexString(next[idx]) + " ");
idx++;
}
System.out.println("");
The output is:
start: вв
fixed: ffffffd0 ffffffb2 ffffffd0 ffffffb2
And the UTF-8 value for "В", in hex, is d0b2.
So, there it is. The question is, why is this not more easily accessible? Do I really have to put this together byte-pair by byte-pair?
If the string is already in UTF-8, as I think we can see it is, why does the codePoints() method not give us, you know, the codePoints?
Ok, so now I do:
new String(next, StandardCharsets.UTF_8);
and I get the proper string. But it still seems strange that codePoints() gives me an IntStream, but if you use these things as int values, it is broken.
It was a problem with the frameworks I was using. I thought I was setting the request and response content type to utf-8 but I was not.
I am having a problem catching or detecting a new line(\n) insert from my server side(java servlet) in my angular ng-repeat.
server side:
StringBuilder name = new StringBuilder();
name.append(getFirst(id)); //id - #param
name.append("\n"); //new line
name.append(getLast(id)); //id - #param
But on my client side, in my ng-repeat:
{{reporter.name}} //jhon doe
instead of:
jhon
doe
if there is more code needed I will post it.
You can use the css style for your requirement:
white-space: pre|pre-line|pre-wrap;
pre - Whitespace is preserved by the browser. Text will only wrap on line breaks. Acts like the <pre> tag in HTML
pre-line - Sequences of whitespace will collapse into a single whitespace. Text will wrap when necessary, and on line breaks
pre-wrap Whitespace is preserved by the browser. Text will wrap when necessary, and on line breaks
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example111-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-sanitize.js"></script>
<style>
table {
border-collapse: collapse;
}
table, td, th {
border: 1px solid black;
}
</style>
</head>
<body ng-app="sanitizeExample">
<script>
angular.module('sanitizeExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.friends = [
{name:'John\nDoe', age:25, gender:'boy'},
{name:'Jessie\nSimpson', age:30, gender:'girl'},
{name:'Johanna\nLN', age:28, gender:'girl'},
{name:'Joy\nLN', age:15, gender:'girl'},
{name:'Mary\nLN', age:28, gender:'girl'},
{name:'Peter\nLN', age:95, gender:'boy'},
{name:'Sebastian\nLN', age:50, gender:'boy'},
{name:'Erika\nLN', age:27, gender:'girl'},
{name:'Patrick\nLN', age:40, gender:'boy'},
{name:'Samantha\nLN', age:60, gender:'girl'}
];
}]);
</script>
<div ng-controller="ExampleController">
<table
class="table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="friend in friends">
<td style="white-space: pre;">{{friend.name}}</td>
<td>{{friend.age}}</td>
<td>{{friend.gender}}</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Replace all \n with < br>, do something like this
str = str.replace(/(?:\r\n|\r|\n)/g, '<br />');
Wrap it in <pre> tag
<pre>{{reporter.name}}</pre>
I have this html
<td rowspan="3" class="event start"> INFO1<br>DETAIL1 DETAIL2<br>INFO2 </td>
how can I get INFO1 and INFO2 using jsoup??
Try something like that :
Document doc = Jsoup.connect(url).get();
Elements td=doc.select("td.event.start");
Elements a = td.first().getElementsByTag("a");
String [] words = a.text().split(" ");
System.out.println(words[0]+" "+words[3]);
Tested on:
<!doctype html>
<html>
<body>
<td rowspan="3" class="event start">
<a href="/search/1065650;1/note">
INFO1<br>DETAIL1 DETAIL2<br>INFO2
</a>
</td>
</body>
</html>
I tried to save .pdf file using different methods I found on stackoverflow including FileUtils IO, however, I would always get it damaged. As I opened the damaged file using a notepad I got the following stuff:
<HEAD>
<TITLE>
09010b129fasdf558a-
</TITLE>
</HEAD>
<HTML>
<SCRIPT language="javascript" src="./js/windowClose.js"></SCRIPT>
<LINK href="./theme/default.css" rel="stylesheet" type="text/css">
<LINK href="./theme/additions.css" rel="stylesheet" type="text/css">
<BODY leftmargin="0" topmargin="0">
<TABLE cellpadding="0" cellspacing="0" width="100%">
<TR>
<TD class="mainSectionHeader">
<A href="javascript:windowClose()" class="allLinks">
CLOSE
</A>
</TD>
</TR>
</TABLE>
<script language='javaScript'>
alert('Session timed out. Please login again.\n');
window.close();
</script>
</BODY>
</HTML>
Later, I tried to save a .pdf file from a browser using the answer provided by #BalusC. This solution is very helpful: I was able to get rid of the session issues. However, it also produces a damaged .pdf. But as I open it with a notepad, it is completely different. There are no login issues anymore though:
<HTML>
<HEAD>
<TITLE>
Evidence System
</TITLE>
</HEAD>
<LINK href="./theme/default.css" rel="stylesheet" type="text/css">
<TABLE cellpadding="0" cellspacing="0" class="tableWidth760" align="center">
<TR>
<TD class="headerTextCtr">
Evidence System
</TD>
</TR>
<TR>
<TD colspan="2">
<HR size="1" noshade>
</TD>
</TR>
<TR>
<TD colspan="2">
<HTML>
<HEAD>
<link href="./theme/default.css" rel="stylesheet" type="text/css">
<script language="JavaScript">
function trim(str)
{
var trmd_str
if(str != "")
{
trmd_str = str.replace(/\s*/, "")
if (trmd_str != ""){
trmd_str = trmd_str.replace(/\s*$/, "")
}
}else{
trmd_str = str
}
return trmd_str
}
function validate(frm){
//check for User name
var msg="";
if(trim(frm.userName.value)==""){
msg += "Please enter your user id.\n";
frm.userName.focus();
}
if(trim(frm.password.value)==""){
msg += "Please enter your password.\n";
frm.userName.focus();
}
if (trim(msg)==""){
frm.submit();
}else{
alert(msg);
}
}
function numCheck(event,frm){
if( event.keyCode == 13){
validate(frm);
}
}
</script>
</HEAD>
<BODY onLoad="document.frmLogin.userName.focus();">
<FORM name='frmLogin' method='post' action='./ServletVerify'>
<TABLE width="100%" cellspacing="20">
<tr>
<td class="mainTextRt">
Username
<input type="text" name="userName" maxlength="32" tabindex="1" value=""
onKeyPress="numCheck(event,this.form)" class="formTextField120">
</TD>
<td class="mainTextLt">
Password
<input type="password" name="password" maxlength="32" tabindex="2" value=""
onKeyPress="numCheck(event,this.form)" class="formTextField120">
</TD>
</TR>
<tr>
<td colspan="2" class="mainTextCtr" style="color:red">
Unknown Error
</td>
</tr>
<tr>
<td colspan="2" class="mainTextCtr">
<input type="button" tabindex="3" value="Submit" onclick="validate(this.form)" >
</TD>
</TR>
</TABLE>
<INPUT TYPE="hidden" NAME="actionFlag" VALUE="inbox">
</FORM>
</BODY>
</HTML>
</TD>
</TR>
<TR>
<TD height="2"></TD>
</TR>
<TR>
<TD colspan="2">
<HR size="1" noshade>
</TD>
</TR>
<TR>
<TD colspan="2">
<LINK href="./theme/default.css" rel="stylesheet" type="text/css">
<TABLE width="80%" align="center" cellspacing="0" cellpadding="0">
<TR>
<TD class="footerSubtext">
Evidence Management System
</TD>
</TR>
<!-- For development builds, change the date accordingly when sending EAR files out to Wal-Mart -->
<TR>
<TD class="footerSubtext">
Build: v3.1
</TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE>
</HTML>
What other options do I have?
PS: When I try to save the file manually using CTRL+Shift+S , the file gets saved OK.
From the errorneous response which appears to be just a HTML error page:
alert('Session timed out. Please login again.\n');
It thus appears that downloading the PDF file is required to take place in a valid HTTP session. The HTTP session is backed by a cookie. The HTTP session in turn contains in the server side usually information about the currenty active and/or logged-in user.
The Selenium web driver manages cookies all by itself fully transparently. You can obtain them programmatically as follows:
Set<Cookie> cookies = driver.manage().getCookies();
When manually fiddling with java.net.URL outside control of Selenium, you should be making sure yourself that the URL connection is using the same cookies (and thus also maintaining the same HTTP session). You can set cookies on the URL connection as follows:
URLConnection connection = new URL(driver.getCurrentUrl()).openConnection();
for (Cookie cookie : driver.manage().getCookies()) {
String cookieHeader = cookie.getName() + "=" + cookie.getValue();
connection.addRequestProperty("Cookie", cookieHeader);
}
InputStream input = connection.getInputStream(); // Write this to file.
A PDF is considered a Binary File and it gets corrupted because the way that copyUrlToFile() works. By the way, this looks like a duplicate of JAVA - Download Binary File (e.g. PDF) file from Webserver
Try this custom binary download method out -
public void downloadBinaryFile(String path) {
URL u = new URL(path);
URLConnection uc = u.openConnection();
String contentType = uc.getContentType();
int contentLength = uc.getContentLength();
if (contentType.startsWith("text/") || contentLength == -1) {
throw new IOException("This is not a binary file.");
}
InputStream raw = uc.getInputStream();
InputStream in = new BufferedInputStream(raw);
byte[] data = new byte[contentLength];
int bytesRead = 0;
int offset = 0;
while (offset < contentLength) {
bytesRead = in.read(data, offset, data.length - offset);
if (bytesRead == -1)
break;
offset += bytesRead;
}
in.close();
if (offset != contentLength) {
throw new IOException("Only read " + offset + " bytes; Expected " + contentLength + " bytes");
}
String filename = u.getFile().substring(filename.lastIndexOf('/') + 1);
FileOutputStream out = new FileOutputStream(filename);
out.write(data);
out.flush();
out.close();
}
EDIT: It actually sounds as if you are not on the page that you think you are.. instead of doing
driver.getCurrentUrl()
Have your script take the Url from the link to the PDF. Assuming there is a link like <a href='http://mysite.com/my.pdf' /> Instead of clicking it, then getting the url, just take the href from that link, and download it.
String pdfPath = driver.findElement(By.id("someId")).getAttribute("href");
downloadBinaryFile(pdfPath);
The server may be compressing the pdf. You can use this code, stolen from this answer to detect and decompress the response from the server,
InputStream is = driver.getCurrentUrl().openStream();
try {
InputStream decoded = decompressStream(is);
FileOutputStream output = new FileOutputStream(
new File("C:\\Users\\myDocs\\myfolder\\myFile.pdf"));
try {
IOUtils.copy(decoded, output);
}
finally {
output.close();
}
} finally {
is.close();
}
public static InputStream decompressStream(InputStream input) {
PushBackInputStream pb = new PushBackInputStream( input, 2 ); //we need a pushbackstream to look ahead
byte [] signature = new byte[2];
pb.read( signature ); //read the signature
pb.unread( signature ); //push back the signature to the stream
if( signature[ 0 ] == (byte) 0x1f && signature[ 1 ] == (byte) 0x8b ) //check if matches standard gzip maguc number
return new GZIPInputStream( pb );
else
return pb;
}
When I try to save the file manually using CTRL+Shift+S , the file
gets saved OK.
While I advocate using Java to download the file, there is a not-so-recommended workaround that presses Ctrl+Shift+S programatically: The Robot class.
It sucks to use a workaround, but it works reliably as far as I can tell in the browsers and OSes I tried. This code should not get into any serious application. But it's OK for tests if you won't be able to solve your issue the right way.
Robot robot = new Robot();
Press Ctrl+Shift+S
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_S);
robot.keyRelease(KeyEvent.VK_S);
robot.keyRelease(KeyEvent.VK_SHIFT);
robot.keyRelease(KeyEvent.VK_CONTROL);
In browsers and OSes I know, you should be in the Save file dialogue in the File name input. You can type in your absolute path:
robot.keyPress(KeyEvent.VK_C); // C
robot.keyRelease(KeyEvent.VK_C);
robot.keyPress(KeyEvent.VK_COLON); // : (colon)
robot.keyRelease(KeyEvent.VK_COLON);
robot.keyPress(KeyEvent.VK_SLASH); // / (slash)
robot.keyRelease(KeyEvent.VK_SLASH);
// etc. for the whole file path
robot.keyPress(KeyEvent.VK_ENTER); // confirm by pressing Enter in the end
robot.keyRelease(KeyEvent.VK_ENTER);
To get the keycodes, you can use KeyEvent#getExtendedKeyCodeForChar() (Java 7+ only), or How can I make Robot type a `:`? and Convert String to KeyEvents.
that's going to be a long question so bear with me :)
My Application
I'm developing a Java (with JFrame GUI) desktop application that does the following:
Scan (.txt) files.
Parses some numbers from these
files, performs some calculations on
them and finally stores the results
in String variables.
Outputs these numbers in a special
(table) format. (Note: the format
includes some Unicode (Arabic)
Characters.)
Problem
The first two parts went smoothly. However when I came to the 3th part (the formatted output) I didn't know how to display this special format so,
What is the best way to display a special formatted output (table) in Java?
Note: Formatter is not going to help because it has no proper support for tables.
Solution One:
I did my research and found that I could use JEditorPane, since it can display special formats such as "html". So I decided to create an "html" page with the needed (table) format and then display this page on [JEditorPane][4]. I did that and it went smoothly until I wanted to change some html elements' values to the parsed numbers from those (.txt) files.
How can I have an access to an html
element(e.g. <td></td>) and change
its value?
Note that the (.html) is loaded inside JEditorPane using setPage(url).
The Unicode characters are displayed properly but I couldn't change some of the elements values (e.g. I want to change the value of <td> 000,000,000 </td> to <td> MainController.getCurrentTotalPayment() </td>
Solution Two:
I've found a workaround to this which involves using HTMLDocument and HTMLEditorKit, That way I can create the (.html) using HTMLEditorKit from scratch and display it on the JEditorPane using kit.insertHTML.
I have successfully added the content using the above method and I also was able to add the parsed numbers from (.txt) files because I have them stored in my (MainController) class. Unfortunately, the Unicode Arabic characters were not displayed properly.
How can I display these Unicode
characters properly?
So the first solution lacks the access to html elements and the second lacks the Unicode support!
My colleagues advised me to use JSP code in the html document that can have an access to my MainController.java class. Therefore, loading the page into JEditorPane with the html elements changed already. Isn't there a way to do that without the help of JSP?
Some other people recommended the use of JTidy but isn't there a way to do it within Java's JDK?
I'm open to all possible solutions. Please help.
My Code: Some code content were omitted because they are not relevant
MainController.java
class MainController
{
private static String currentTotalPayment;
public static void main(String[] args)
{
CheckBankFilesView cbfView = new CheckBankFilesView();
cbfView.setVisible(true);
}
public static void setCurrentTotalPayment(String totalPayment) {
MainController.currentTotalPayment = totalPayment;
}
public static String getCurrentTotalPayment() {
return currentTotalPayment;
}
}
MyFormattedOuputSolutionOne.java:
public class MyFormattedOuputSolutionOne extends javax.swing.JFrame {
private void MyFormattedOuputSolutionOne() {
jPanel1 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
myFormattedOuput = new javax.swing.JEditorPane();
myFormattedOuput.setContentType("text/html");
//myFormattedOuput.setContentType("text/html; charset=UTF-8"); //Doesn't seem to work
myFormattedOuput.setEditable(false);
jScrollPane1.setViewportView(myFormattedOuput);
myFormattedOuput.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
try{
myFormattedOuput.setPage(getClass().getResource("resources/emailFormat2.html"));
//How can I edit/change html elements loaded in 'myFormattedOuput'?
}catch(Exception e){
}
}
}
MyFormattedOuputSolutionTwo.java:
public class MyFormattedOuputSolutionTwo extends javax.swing.JFrame {
private void MyFormattedOuputSolutionTwo() {
jPanel1 = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
myFormattedOuput = new javax.swing.JEditorPane();
myFormattedOuput.setContentType("text/html");
//myFormattedOuput.setContentType("text/html; charset=UTF-8"); //Doesn't seem to work
myFormattedOuput.setEditable(false);
jScrollPane1.setViewportView(myFormattedOuput);
HTMLEditorKit kit = new HTMLEditorKit();
HTMLDocument doc = new HTMLDocument();
myFormattedOuput.setEditorKit(kit);
myFormattedOuput.setDocument(doc);
myFormattedOuput.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
try{
// Tried to set the charset in <head> but it doesn't work!
//kit.insertHTML(doc, 1, "<meta http-equiv = \"Content-Type\" content = \"text/html; charset=UTF-8\">", 0, 0, HTML.Tag.META);
kit.insertHTML(doc, doc.getLength(), "<label> السلام عليكم ورحمة الله وبركاته ,,, </label>", 0, 0, null); //Encoding problem
kit.insertHTML(doc, doc.getLength(), "<br/>", 0, 0, null); // works fine
kit.insertHTML(doc, doc.getLength(), MainController.getCurrentTotalPayment(), 0, 0, null); // works fine
//How can I solve the Unicode problem above?
}catch(Exception e){
}
}
}
htmlFormatTable.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8">
</head>
<body>
<label> السلام عليكم ورحمة الله وبركاته ,,, </label>
<br/>
<label> الأخوة الكرام نفيدكم بتفاصيل المدفوعات لشهر </label> XX/143X </label> هـ كما هو موضح ادناه </label>
<br/>
<table align="right" border="1" width="600" cellpadding="5" cellspacing="0">
<tr char="utf-8" bgcolor="cccccc" align="center">
<td colspan="3"> <label> تفاصيل مدفوعات بنك الرياض </label> <img src="..\images\riyadh.gif" width="65" height="15"/> </td>
</tr>
<tr align="center">
<td></td>
<td id="cell1">0,000,000.00</td>
<td align="right"> معاشات </td>
</tr>
<tr align="center">
<td></td>
<td id="cell2">0,000,000.00</td>
<td align="right"> أخطار </td>
</tr>
<tr align="center">
<td bgcolor="cccccc"> المجموع </td>
<td bgcolor="cccccc"> 0,000,000.00 <label> ريال سعودي </label> </td>
<td></td>
</tr>
</table>
<br/>
<label> شاكرين لكم حسن تعاونكم ...... </label>
<br/>
<label> فريق العمليات بقسم الحاسب الآلي </label>
</body>
</html>
Thank you for reading my long multiple questions thread and cannot wait for your answer.
Update:
Thanks to #Howard for this insight, if I replace the arabic character with its corresponding unicode (e.g. ب = \u0628) it works fine but there must be a way to do it without the need to replace each character, right?
Solution One
It is possible to edit HTML loaded into JEditorPane. Here's the complete code based on your MyFormattedOuputSolutionOne.java:
import java.awt.ComponentOrientation;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JEditorPane;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
public class MyFormattedOuputSolutionOne extends javax.swing.JFrame {
private MyFormattedOuputSolutionOne() {
super("MyFormattedOuputSolutionOne");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
final JEditorPane myFormattedOuput = new javax.swing.JEditorPane();
getContentPane().add(jScrollPane1);
myFormattedOuput.setContentType("text/html");
//myFormattedOuput.setContentType("text/html; charset=UTF-8"); //Doesn't seem to work
myFormattedOuput.setEditable(false);
jScrollPane1.setViewportView(myFormattedOuput);
myFormattedOuput.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
try{
myFormattedOuput.setPage(getClass().getResource("htmlFormatTable.html"));
myFormattedOuput.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("page".equals(evt.getPropertyName())) {
Document doc = myFormattedOuput.getDocument();
Element html = doc.getRootElements()[0];
Element body = html.getElement(1);
Element table = body.getElement(1);
try {
Element tr2 = table.getElement(1);
Element tr2td1 = tr2.getElement(0);
doc.insertString(tr2td1.getStartOffset(), "1: 123,456",
SimpleAttributeSet.EMPTY);
Element tr3 = table.getElement(2);
Element tr3td1 = tr3.getElement(0);
doc.insertString(tr3td1.getStartOffset(), "2: 765.123",
SimpleAttributeSet.EMPTY);
} catch (BadLocationException e) {
e.printStackTrace();
}
myFormattedOuput.removePropertyChangeListener(this);
}
}
});
//How can I edit/change html elements loaded in 'myFormattedOuput'?
} catch(Exception e){
e.printStackTrace();
}
pack();
setSize(700, 400);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MyFormattedOuputSolutionOne();
}
});
}
}
It loads document asynchronously and waits for page to be loaded. When page is loaded, it accesses the elements of the document to search for elements and inserts text into the first <td> in the 2nd and 3rd row of the table.
By the way your HTML is not valid! You should clean it up. When you do it, the indexes of the document elements will change and you'll have to adjust code which finds the insertion points.
The window looks this way:
Solution Two
I've found no issues with encoding. The characters display correctly. Yet I had to set the encoding of Java files to UTF-8 in the Eclipse project.
Solution Three
Have you considered using JTable to display table of results in the UI?
The HTML might look this way:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8">
</head>
<body>
<p> السلام عليكم ورحمة الله وبركاته ,,, </p>
<p> الأخوة الكرام نفيدكم بتفاصيل المدفوعات لشهر </p>
<p>XX/143X </p>
<p> هـ كما هو موضح ادناه </p>
<table align="right" border="1" width="600" cellpadding="5" cellspacing="0">
<tr bgcolor="cccccc" align="center">
<td colspan="3">تفاصيل مدفوعات بنك الرياض <img src="..\images\riyadh.gif" width="65" height="15"/></td>
</tr>
<tr align="center">
<td></td>
<td id="cell1">0,000,000.00</td>
<td align="right">معاشات</td>
</tr>
<tr align="center">
<td></td>
<td id="cell2">0,000,000.00</td>
<td align="right">أخطار</td>
</tr>
<tr align="center">
<td bgcolor="cccccc">المجموع</td>
<td bgcolor="cccccc">0,000,000.00 ريال سعودي</td>
<td></td>
</tr>
</table>
<p> شاكرين لكم حسن تعاونكم ...... </p>
<p> فريق العمليات بقسم الحاسب الآلي </p>
</body>
</html>
Since I don't understand a word, I cannot propose a better formatting. First of all, <label> elements are allowed only in <form>. You had a sequence of three <label>s above the table where only one of them had opening <label> tag, there were three closing </label> tags. I made them all into <p>; however if you meant them to be headers for table columns, you should have used a table row with three <th> elements.
With this structure of the HTML, <table> element in the HTML tree would be at index 4, i.e. you should change the line
Element table = body.getElement(1);
to
Element table = body.getElement(4);
The indexes 0–3 are now <p> elements.
As a side note, instead of editing HTML after loading it into JEditorPane, which loads it into text model of HTMLDocument, you could edit your HTML document before passing to setPage so that it already contains the correct data in <td> elements. Since JEditorPane.setPage method accepts only URL, then your choice would be read which accepts an InputStream and Object which describes the model (should be instance of HTMLDocument in your case). StringBufferInputStream is the best candidate for this task yet it was deprecated because it cannot correctly read UTF-8 characters. Having this in mind, you would rather use String.getBytes("UTF-8") function (since J2SE 6), and ByteArrayInputStream, your HTML declares the encoding and JEditorPane would respect it when reading.