We are trying to render both HTML and plain text using JTextPane. Basically the actual content is hosted on remote server, this content can contain some degree of HTML tags or none at all. In my JTextPane I have it defined as shown:
JTextPane jText = new JTextPane();
jText.setEditable(false);
jText.setContentType("text/html");
String content = "Please view article <a href=mydomain.com/content.txt>Link..</a>";
jText.setText(content);
And then using HyperlinkListener wants to be able to render the content when the link is clicked. I am doing so using the syntax below;
jText.addHyperlinkListener(new HyperlinkListener()
{
public void hyperlinkUpdate(final HyperlinkEvent he)
{
//Render the page
try{
setPage(he.getURL()); //Error on this line
}catch(Exception e){e.printStackTrace();}
}
});
Unfurtunately when we click on the link to render the content, we end up with the exception:
java.lang.IllegalArgumentException: Must be StyledEditorKit
at javax.swing.JTextPane.setEditorKit(JTextPane.java:474)
at javax.swing.JEditorPane.setContentType(JEditorPane.java:888)
at javax.swing.JEditorPane.getStream(JEditorPane.java:713)
at javax.swing.JEditorPane.setPage(JEditorPane.java:408)
This looks like when the content has no HTML tag available. Can someone help us resolve this issue so we can render both plain text and HTML.
Thanks in advance.
EDITED.
It sounds like what you're saying is that since you want to support both HTML and plain-text from your JTextPane as input, then not receiving a URL isn't really considered a problem. In that case, you should consider logging/eating the exception:
jText.addHyperlinkListener(new HyperlinkListener()
{
public void hyperlinkUpdate(final HyperlinkEvent he)
{
try {
//Render the page
setPage(he.getURL()); //Error on this line
} catch (IllegalArgumentException e) {
// either log the argument here, or just eat it and do nothing with it. logger.error() recommended
}
}
});
Related
Iv'e created an app in Xamarin.Forms and then created a custom lable with a custom renderer for android. The renderer's job is to make the label text selectable. And it works, the label text is now selectable. The problem is, while it works perfectly with regular lables, when i try to select text in a label which has both Hebrew and English (RTL and LTR) text, the app crashes and I get this error:
Java.Lang.ArrayIndexOutOfBoundsException: 'length=35; index=35' (indexes and length vary between crashes but are always equal to each other).
I looked online for a solution and couldn't find one... I also tried other implementations of the renderer and they all had the same error. (I think it might be a problem with Android/Xamarin)
Can someone help me?
Code for renderer:
class CustomLabelRenderer : LabelRenderer
{
public CustomLabelRenderer(Context context) : base(context) {}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
Control.SetTextIsSelectable(true);
}
}
(Custom label (SELabel) has no code, it just inherits from the regular Label)
Device Logs:
Log.txt
I use google translation "Welcome to Xamarin.Forms" to Hebrew "ברוך הבא ל - Xamarin.Forms.". And make a code sample to test on my side. It works well. Please check my code.
SELabel:
public class SELabel:Label
{
}
CustomLabelRenderer:
[assembly: ExportRenderer(typeof(SELabel), typeof(CustomLabelRenderer))]
namespace SelectableLabel.Droid
{
public class CustomLabelRenderer : LabelRenderer
{
public CustomLabelRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
Control.SetTextIsSelectable(true);
}
}
}
Usage:
<StackLayout>
<!-- Place new controls here -->
<local:SELabel
HorizontalOptions="Center"
Text="Welcome to Xamarin.Forms! Hebrew: ברוך הבא ל - Xamarin.Forms."
VerticalOptions="CenterAndExpand" />
</StackLayout>
Screenshot:
You could download the source file from the GitHub for reference.
https://github.com/WendyZang/Test/tree/master/SelectableLabel
i would like to know if its possible to have a clickable link for a dynamic text.
I have tried by using the anchor tag with some wicket id and adding an onclick behavior to it, i could see the text with link on my screen but the onclick call of t he link was never triggered.
What could possibly be the issue?
i did something like this:
String someTextMessage = "Hey!!! <a wicket:id='printLink'>Click Here</a> now.";
Lable message = new Lable("messageLable", someTextMessage);
message.setEscapeModelStrings(true);
Link printLink = new Link("printLink") {
#Override
public void onClick() {
System.out.println("inside onClick");
}
};
this.add(printLink);
this.add(message);
i used this wicket id and added it to the page and attached an onclick behavior to this.
I have checked t he firebug console but there was no onclick call made for the link's click.
Thanks.
You want to use the Link.setAnchor(Component) method.
Don't forget to setOutputMarkupId to true for the component you want to jump to.
Label message = new Label("messageLable", "Anchor!");
message.setOutputMarkupId(true);
this.add(message);
Link printLink = new Link("printLink") {
#Override
public void onClick() {
System.out.println("inside onClick");
}
};
printLink.setAnchor(message);
this.add(printLink);
Don't try to add wicket components by appending html with "wicket:id" in some kind of component. It won't work.
I cannot seem to figure out how to view a PDF Page using PDFBox and its PDFPagePanel component.
So it seems that using PDFBox my options are to either create a List of PDPage objects or PDDocument objects, I've gone with the PDPage list (as opposed to using Splitter() for PDDocument objects)
The following code creates a PDPage object named testPage
File PDF_Path = new File("C:\\PDF.PDF");
PDDocument inputPDF = PDDocument.load(PDF_Path);
List<PDPage> allPages = inputPDF.getDocumentCatalog().getAllPages();
inputPDF.close();
PDPage testPage = (PDPage)allPages.get(0);
From here I would like to create a PDFPagePanel and use its setPage() method to place the PDPage into the component. From here I want to add the component to a JFrame. When I do this I just see whitespace.
JFrame testFrame = new JFrame();
testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
PDFPagePanel pdfPanel = new PDFPagePanel();
pdfPanel.setPage(testPage);
testFrame.add(pdfPanel);
testFrame.setBounds(40, 40, pdfPanel.getWidth(), pdfPanel.getHeight());
testFrame.setVisible(true);
I found one 'solution' which suggest converting the PDF to an image and displaying it as a buffered image, and while this works it doesn't seem like the correct way to do this. Am I incorrect in trying to use PDFBox's PDFPagePanel as a means to displaying a PDF?
When I comment out the inputPDF.close call, it works okay. What if you move the close to after you are finished displaying the pdf? Something like this...
testFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
testFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
try {
inputPDF.close();
testFrame.setVisible(false);
} catch (IOException e1) {
// TODO: implement error handling
e1.printStackTrace();
}
}
});
For the record, I also implemented a PDFBox viewer as a BufferedImage wrapped in a Component wrapped in a JPanel. Then, I was able to customize the panel with additional buttons to change pages, change documents, "zoom" or resize the image, etc.
I have a JTable which uses JTextPane as editor and renderer. I added a keyListener to the editor, that listens for "space" character and checks if the last word is URL and if it is, adds it to the editor as a hyperlink using this attribute: attrs.addAttribute(HTML.Attribute.HREF, url);. I soon figured that this won't convert URLs to hyperlinks when I paste text so I decided I need to do this using DocumentFilter.
How can I create a DocumentFilter that checks if the text about to be inserted/replaced contains URLs and if it does inserts/replaces thoose URLs with the HTML.Attribute.HREF attribute and the rest of the text as it is?
See the example http://java-sl.com/tip_autocreate_links.html
It's not necessary to use a DocumentFilter. LIstener is enough.
Just mark inserted content with a dummy attribute and then replace it with hyperlink html.
// somewhere add text reformated as html link
setText("<HTML>Click the <FONT color=\"#000099\"><U>link</U></FONT>"
+ " to go to the Java website.</HTML>");
// somewhere add a listener for clicks
addActionListener(new OpenUrlAction());
// Define uri and open action
final URI uri = new URI("http://java.sun.com");
class OpenUrlAction implements ActionListener {
#Override public void actionPerformed(ActionEvent e) {
open(uri);
}
}
// Define open uri method
private static void open(URI uri) {
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().browse(uri);
} catch (IOException e) { /* TODO: error handling */ }
} else { /* TODO: error handling */ }
I have Java Desktop application that displays some information in a JTable that may contain URLs with some text in some cells. How can I make only the URL click-able and allow the user to open it in a default browser if he/she clicks on it.
You can use the approach shown here in a custom TableCellEditor. Once selected, you can browse() the URI.
Addendum: You can use JEditorPane for your editor component and addHyperlinkListener() to listen for events related to the link.
JEditorPane jep = new JEditorPane();
jep.addHyperlinkListener(new HyperlinkListener() {
#Override
public void hyperlinkUpdate(HyperlinkEvent e) {
HyperlinkEvent.EventType type = e.getEventType();
final URL url = e.getURL();
if (type == HyperlinkEvent.EventType.ENTERED) {
// do desired highlighting
} else if (type == HyperlinkEvent.EventType.ACTIVATED) {
// open browser
}
}
});
here is a sample about displaying text as hyperlink: HyperLink in JTable Cell