How to load local html file in java swing? - java

I have a tree list which will open a specific html file when I click at a node. I try loading my html into a Jeditorpanel but it can't seem to work.
Here's my code from main file:
private void treeItemMouseClicked(java.awt.event.MouseEvent evt) {
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) treeItem.getSelectionPath().getLastPathComponent();
String checkLeaf = selectedNode.getUserObject().toString();
if (checkLeaf == "Java Turtorial 1") {
String htmlURL = "/htmlFILE/javaTurtorial1.html";
new displayHTML(htmlURL).setVisible(true);
}
}
Where I wanna display it:
public displayHTML(String htmlURL) {
initComponents();
try {
//Display html file
editorHTML.setPage(htmlURL);
} catch (IOException ex) {
Logger.getLogger(displayHTML.class.getName()).log(Level.SEVERE, null, ex);
}
}
My files:

One simple way to render HTML with JEditorPane is using it's setText method:
JEditorPane editorPane =...
editorPane.setContentType( "text/html" );
editorPane.setText( "<html><body><h1>I'm an html to render</h1></body></html>" );
Note that only certain HTML pages (relatively simple ones) can be rendered with this JEditoPane, if you need something more complicated you'll have to use thirdparty components
Based on OP's comment, I'm adding an update to the answer:
Update
Since the HTMLs that you're trying to load are files inside the JAR, you should read the file into some string variable and use the aforementioned method setText
Note that you shouldn't use java.io.File because it used to identify resources at the filesystem, and you're trying to access something inside the artifact:
Reading the resource like this can be done with the following construction:
InputStream is = getClass().getResourceAsStream("/htmls/myhtml.html");
// and then read with the help of variety of ways, depending on Java Version of your choice and by the availaility by auxiliary thirdparties
// here is the most simple way IMO for Java 9+
String htmlString = new String(input.readAllBytes(), StandardCharsets.UTF_8);
Read Here about many different ways to read InputStream into String

Related

Parse data from webpage to android app using Jsoup

My android app has a part were i need to parse data from wikipedia.com and use that in application. when i go to https://en.wikipedia.org/wiki/Template:COVID-19_pandemic_data I can see the covid19 cases. I want to retrieve the number from the table
I am using Jsoup. I am able to get html data by using this https://en.wikipedia.org/w/api.php?format=xml&action=parse&page=Template:COVID-19_pandemic_data .If you can guide me how can i extract the india cases and deaths from html file. as the html doc is huge and there no attr for tr. There's not much information about this on internet. What i have tried so far...
private void getWebsite() {
new Thread(new Runnable() {
#Override
public void run() {
final StringBuilder builder = new StringBuilder();
String web_link = "https://en.wikipedia.org/w/api.php?format=xml&action=parse&page=Template:COVID-19_pandemic_data";
try {
Document doc = Jsoup.connect(web_link).get();
String title = doc.title();
Elements links = doc.select("tr");
builder.append(title).append("\n");
for(Element link : links){
builder.append(link);
}
} catch (IOException e) {
builder.append("Error : ").append(e.getMessage()).append("\n");
}
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(builder.toString());
}
});
}
}).start();
}
The problem is related to the format of the data (XML). When you navigate down the XML elements, you find what's displayed in the document, when viewed via your browser, is:
<someTag>...</someTag>
But what's actually present is the xml encoded version of the string:
<someTag>...</someTag>
JSoup won't work well with this and you'll need further processing to convert the output to more XML to get it working I'd imagine. You can test this yourself by viewing the result of:
doc.getElementsByTag("text")
And you'd need to replace all < and > tokens with <, > respectively.
Here's what I tried, plus some minor edits after failing to be able to pull tbody/thead/th.. I then started trying to pull from the top level tag, starting with api, moving deeper into the DOM.
final StringBuilder builder = new StringBuilder();
String url = "https://en.wikipedia.org/w/api.php?format=xml&action=parse&page=Template:COVID-19_pandemic_data";
try {
Document doc = Jsoup.connect(url).get();
String title = doc.getElementsByTag("parse").attr("title");
Also worth mentioning there are some really good examples in the documents here: https://jsoup.org/cookbook/extracting-data/dom-navigation
And finally, for what it's worth, I'd change the URL used to: https://en.wikipedia.org/wiki/Template:COVID-19_pandemic_data to make life easier for use with JSoup so you can just pull the relevant bits of data from HTML rather than XML.
In my view, if you have the choice, HtmlUnit would be a better tool for this since you can simply specify an XPath for the HTML element you want to extract without having to use multiple method calls to get what you want... the more concise format means there's less room for errors to hide.

Domino app - how to access the source document in java during custom file attachment routine

This is a non-xpages application.
I have inherited some code that I need to tweak....this code is used in a drag&drop file attachment subform. Normally, this will create a document in a separate dedicated .nsf that stores only attachments, and uses the main document's universalid as a reference to link the two....I need to change what the reference is to the value in a field already on the main document (where the subform is).
Java is challenging to me, but all I need to do is GET the value of the field from the main document (which has not necessarily been saved yet) and write that string value onto the attachment doc in that storage database, so I think I am just needing help with one line of code.
I will paste the relevant function here and hopefully someone can tell me how I get that value, or what else they need to see what is going on here.
You can see my commented-out attempt to write the field 'parentRef' in this code
...
private void storeUploadedFile( UploadedFile uploadedFile, Database dbTarget) {
File correctedFile = null;
RichTextItem rtFiles = null;
Document doc = null;
String ITEM_NAME_FILES = "file";
try {
if (uploadedFile==null) {
return;
}
doc = dbTarget.createDocument();
doc.replaceItemValue("form", "frmFileUpload");
doc.replaceItemValue("uploadedBy", dbTarget.getParent().getEffectiveUserName() );
Utils.setDate(doc, "uploadedAt", new Date() );
doc.replaceItemValue("parentUnid", parentUnid);
//doc.replaceItemValue("parentRef", ((Document) dbTarget.getParent()).getItemValue("attachmentDocKey"));
//get uploaded file and attach it to the document
fileName = uploadedFile.getClientFileName();
File tempFile = uploadedFile.getServerFile(); //the uploaded file with a cryptic name
fileSize = tempFile.length();
targetUnid = doc.getUniversalID();
correctedFile = new java.io.File( tempFile.getParentFile().getAbsolutePath() + java.io.File.separator + fileName );
//rename the file on the OS so we can embed it with the correct (original) name
boolean success = tempFile.renameTo(correctedFile);
if (success) {
//embed original file in target document
rtFiles = doc.createRichTextItem(ITEM_NAME_FILES);
rtFiles.embedObject(lotus.domino.EmbeddedObject.EMBED_ATTACHMENT, "", correctedFile.getAbsolutePath(), null);
success = doc.save();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
com.gadjj.Utils.recycle(rtFiles, doc);
try {
if (correctedFile != null) {
//rename the temporary file back to its original name so it's automatically
//removed from the os' file system.
correctedFile.renameTo(uploadedFile.getServerFile());
}
} catch(Exception ee) { ee.printStackTrace(); }
}
}
}
...
dbTarget.getParent does not do what you think it does. It returns a Session object that is the parent session containing all your objects. Casting it to (Document) won't give you your main document.
I don't see the declaration for it, but you appear to have a variable available called parentUNID. You can use it to get a handle on the main document.
You need to use the parentUNID value in a call to getDocumentByUNID() in order to retrieve the Document object representing your main document. But in order to do that, you need the Database object for the nsf file containing the main document, and if I understand you correctly, that is a different database than targetDb.
I'm going to have to assume that you already have that Database object in a variable called parentDb, or that you know the path to the NSF and can open it. In either case, your code would look like this (without error handling):
Document parentDoc = parentDb.getDocumentByUNID(parentUNID);
doc.replaceItemvalue("parentRef", parentDoc.getItemValue("attachmentDocKey"));

Change id3 tag version programatically (pref java)

I need a way to change id3 tag version of mp3 files to some id3v2.x programatically, preferably using java though anything that works is better than nothing. Bonus points if it converts the existing tag so that already existing data isn't destroyed, rather than creating a new tag entirely.
Edit: Jaudiotagger worked, thanks. Sadly I had to restrict it to mp3 files and only saving data contained in previous tags if they were id3. I decided to convert the tag to ID3v2.3 since windows explorer can't handle v2.4, and it was a bit tricky since the program was a bit confused about whether to use the copy constructor or the conversion constructor.
MP3File mf = null;
try {
mf = (MP3File)AudioFileIO.read(new File(pathToMp3File));
} catch (Exception e) {}
ID3v23Tag tag;
if (mf.hasID3v2Tag()) tag = new ID3v23Tag(mf.getID3v2TagAsv24());
else if (mf.hasID3v1Tag()) tag = new ID3v23Tag(mf.getID3v1Tag());
else tag = new ID3v23Tag();
My application must be able to read id3v1 or id3v11, but shall only write v23, so I needed a little bit longer piece of code:
AudioFile mf;
Tag mTagsInFile;
...
mf = ... // open audio file the usual way
...
mTagsInFile = mf.getTag();
if (mTagsInFile == null)
{
//contrary to getTag(), getTagOrCreateAndSetDefault() ignores id3v1 tags
mTagsInFile = mf.getTagOrCreateAndSetDefault();
}
// mp3 id3v1 and id3v11 are suboptimal, convert to id3v23
if (mf instanceof MP3File)
{
MP3File mf3 = (MP3File) mf;
if (mf3.hasID3v1Tag() && !mf3.hasID3v2Tag())
{
// convert ID3v1 tag to ID3v23
mTagsInFile = new ID3v23Tag(mf3.getID3v1Tag());
mf3.setID3v1Tag(null); // remove v1 tags
mf3.setTag(mTagsInFile); // add v2 tags
}
}
Basically we have to know that getTagOrCreateAndSetDefault() and similar unfortunately ignores id3v1, so we first have to call getTag(), and only if this fails, we call the mentioned function.
Additionally, the code must also deal with flac and mp4, so we make sure to do our conversion only with mp3 files.
Finally there is a bug in JaudioTagger. You may replace this line
String genre = "(" + genreId + ") " + GenreTypes.getInstanceOf().getValueForId(genreId);
in "ID3v24Tag.java" with this one
String genre = GenreTypes.getInstanceOf().getValueForId(genreId);
Otherwise genre 12 from idv1 will get "(12) Other" which later is converted to "Other Other" and this is not what we would expect. Maybe someone has a more elegant solution.
You can use different libraries for this purpose, for example this or this.

Textscreen in Codename One, how to read text file?

I want to add a help screen to my Codename One App.
As the text is longer as other strings, I would like put it in a separate file and add it to the app-package.
How do I do this? Where do I put the text file, and how can I easily read it in one go into a string?
(I already know how to put the string into a text area inside a form)
In the Codename One Designer go to the data section and add a file.
You can just add the text there and fetch it using myResFile.getData("name");.
You can also store the file within the src directory and get it using Display.getInstance().getResourceAsStream("/filename.txt");
I prefer to have the text file in the filesystem instead of the resource editor, because I can just edit the text with the IDE. The method getResourceAsStream is the first part of the solution. The second part is to load the text in one go. There was no support for this in J2ME, you needed to read, handle buffers etc. yourself. Fortunately there is a utility method in codename one. So my working method now looks like this:
final String HelpTextFile = "/helptext.txt";
...
InputStream in = Display.getInstance().getResourceAsStream(
Form.class, HelpTextFile);
if (in != null){
try {
text = com.codename1.io.Util.readToString(in);
in.close();
} catch (IOException ex) {
System.out.println(ex);
text = "Read Error";
}
}
The following code worked for me.
//Gets a file system storage instance
FileSystemStorage inst = FileSystemStorage.getInstance();
//Gets CN1 home`
final String homePath = inst.getAppHomePath();
final char sep = inst.getFileSystemSeparator();
// Getting input stream of the file
InputStream is = inst.openInputStream(homePath + sep + "MyText.txt");
// CN1 Util class, readInputStream() returns byte array
byte[] b = Util.readInputStream(is);
String myString = new String(b);

Jmock Mockery, mocking a file system object

I want to be able to mock the File object in java using Mockery. I seems like we may not be able to create an interface for the File in java. Is this possible?
EDIT:
I need to test the indexDoc function in Indexer Class.
#Test
public void testindexDocs()
{
final File f = mockFile.mock(File.class);
File file = new File("test");
mockFile.setImposteriser(ClassImposteriser.INSTANCE);
final String[] files = {
"C:\\test\\",
"C:\\test\\test1.html",
"C:\\test\\test2",
"C:\\test\\test3.html"};
mockFile.checking(new Expectations(){
{
one(f).list();will(returnValue(files));
}
});
//TODO test if list() how many time i have called
//Document doc = HTMLDocument.Document(file); in function indexDocs
}
Index Docs function in Indexer class
private static void indexDocs(File file) throws Exception{
//Check for file to be a directory or file to be indexed look for html files and add to document
if(file.isDirectory()){
String[] files = file.list();
Arrays.sort(files);
for (int i = 0; i < files.length; i++) // recursively index them
indexDocs(new File(file, files[i]));
} else if(file.getPath().endsWith(".html") || file.getPath().endsWith("htm")){
// Get the document from HTMLDocument class which takes care of stripping of HTML tag, get the path
// of HTML file and title of HTML document.
Document doc = HTMLDocument.Document(file);
// TODO Get the book of HTML, it can be a part of HTML document class.
writer.addDocument(doc);
}
}
Don't mock the file system. We tried to do this in the early days and it diverted us from using tests to guide the design.
From a quick look at your code, there are two things going on, one is file navigation, the other is html stripping. Perhaps one option would be to introduce a html stripping object (passed in as a collaborator) and mock that, then write tests against examples in a real file system.
Jmock can mock concrete classes. Just do
Mockery context = new Mockery();
context.setImposteriser(ClassImposteriser.INSTANCE);
The problems your having are the exact reason, one should use abstractions rather than concrete classes.

Categories