I am trying to implement a view only HTML pane for some specific project. I am using JTextPane to render HTML using content type as "text/html". I was having tables in my input HTML so in order to give these tables border, i thought of using css styling, but unfortunately it did not work out.
If I put border property as part of table itself then it works but not
with css styling.
Here is the sample code i created to recreate issue. content1 does not creates border for my table but content2 creates it. I want to use content1 approach as i have plenty of html files with tables. Thanks for your time, any help will be much appreciated.
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
public class TestTextPane {
private static int X = 200;
private static int Y = 200;
private static int W = 600;
private static int H = 400;
public static final String content1 = "<html>\r\n" +
" <head>\r\n" +
" <style type=\"text/css\">\r\n" +
" <!--\r\n" +
" table,th, td { border: 1px solid black }\r\n" +
" body, p { font-family: Courier; font-size: 14 }\r\n" +
" -->\r\n" +
" </style>\r\n" +
" \r\n" +
" </head>\r\n" +
" <body>\r\n" +
" <div align=\"left\">\r\n" +
" <b>Q: What is the difference between GET and POST method? </b>\r\n" +
" </div>\r\n" +
" <p>\r\n" +
" A:\r\n" +
" </p>\r\n" +
" <table>\r\n" +
" <tr>\r\n" +
" <th width=\"50%\">\r\n" +
" GET\r\n" +
" </th>\r\n" +
" <th>\r\n" +
" POST\r\n" +
" </th>\r\n" +
" </tr>\r\n" +
" <tr>\r\n" +
" <td>\r\n" +
" GET is a safe method (idempotent)\r\n" +
" </td>\r\n" +
" <td>\r\n" +
" POST is non-idempotent method\r\n" +
" </td>\r\n" +
" </tr>\r\n" +
" <tr>\r\n" +
" <td>\r\n" +
" We can send limited data with GET method and it’s sent in the header \r\n" +
" request URL\r\n" +
" </td>\r\n" +
" <td>\r\n" +
" we can send large amount of data with POST because it’s part of the \r\n" +
" body.\r\n" +
" </td>\r\n" +
" </tr>\r\n" +
" </table>\r\n" +
" <br>\r\n" +
" <br>\r\n" +
" \r\n" +
" </body>\r\n" +
"</html>";
public static final String content2 = "<html>\r\n" +
" <head>\r\n" +
" <style type=\"text/css\">\r\n" +
" <!--\r\n" +
" body, p { font-family: Courier; font-size: 14 }\r\n" +
" -->\r\n" +
" </style>\r\n" +
" \r\n" +
" </head>\r\n" +
" <body>\r\n" +
" <div align=\"left\">\r\n" +
" <b>Q: What is the difference between GET and POST method? </b>\r\n" +
" </div>\r\n" +
" <p>\r\n" +
" A:\r\n" +
" </p>\r\n" +
" <table border=1>\r\n" +
" <tr>\r\n" +
" <th width=\"50%\">\r\n" +
" GET\r\n" +
" </th>\r\n" +
" <th>\r\n" +
" POST\r\n" +
" </th>\r\n" +
" </tr>\r\n" +
" <tr>\r\n" +
" <td>\r\n" +
" GET is a safe method (idempotent)\r\n" +
" </td>\r\n" +
" <td>\r\n" +
" POST is non-idempotent method\r\n" +
" </td>\r\n" +
" </tr>\r\n" +
" <tr>\r\n" +
" <td>\r\n" +
" We can send limited data with GET method and it’s sent in the header \r\n" +
" request URL\r\n" +
" </td>\r\n" +
" <td>\r\n" +
" we can send large amount of data with POST because it’s part of the \r\n" +
" body.\r\n" +
" </td>\r\n" +
" </tr>\r\n" +
" </table>\r\n" +
" <br>\r\n" +
" <br>\r\n" +
" \r\n" +
" </body>\r\n" +
"</html>";
/**
* #param args
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setBounds(X, Y, W, H);
JTextPane pane = new JTextPane();
pane.setContentType("text/html");
pane.setEditable(false);
JScrollPane scrollPane = new JScrollPane(pane);
scrollPane.setBounds(X,Y,W,H);
frame.getContentPane().add(scrollPane);
pane.setText(content2); // change content here
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
I removed the comment notation from the style and added units for the size of the font.
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
public class TestTextPane {
private static int X = 200;
private static int Y = 200;
private static int W = 600;
private static int H = 400;
public static final String content1 = "<html>\r\n" +
" <head>\r\n" +
" <style type=\"text/css\">\r\n" +
" table, th, td { border: 2px solid #FF0000; }\r\n" +
// be sure to add a unit to the font size, otherwise it is invalid
" body, p { font-family: Courier; font-size: 14px; }\r\n" +
" </style>\r\n" +
" \r\n" +
" </head>\r\n" +
" <body>\r\n" +
" <div align=\"left\">\r\n" +
" <b>Q: What is the difference between GET and POST method? </b>\r\n" +
" </div>\r\n" +
" <p>\r\n" +
" A:\r\n" +
" </p>\r\n" +
" <table>\r\n" +
" <tr>\r\n" +
" <th width=\"50%\">\r\n" +
" GET\r\n" +
" </th>\r\n" +
" <th>\r\n" +
" POST\r\n" +
" </th>\r\n" +
" </tr>\r\n" +
" <tr>\r\n" +
" <td>\r\n" +
" GET is a safe method (idempotent)\r\n" +
" </td>\r\n" +
" <td>\r\n" +
" POST is non-idempotent method\r\n" +
" </td>\r\n" +
" </tr>\r\n" +
" <tr>\r\n" +
" <td>\r\n" +
" We can send limited data with GET method and it’s sent in the header \r\n" +
" request URL\r\n" +
" </td>\r\n" +
" <td>\r\n" +
" we can send large amount of data with POST because it’s part of the \r\n" +
" body.\r\n" +
" </td>\r\n" +
" </tr>\r\n" +
" </table>\r\n" +
" <br>\r\n" +
" <br>\r\n" +
" \r\n" +
" </body>\r\n" +
"</html>";
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setBounds(X, Y, W, H);
JTextPane pane = new JTextPane();
pane.setContentType("text/html");
pane.setEditable(false);
JScrollPane scrollPane = new JScrollPane(pane);
scrollPane.setBounds(X,Y,W,H);
frame.getContentPane().add(scrollPane);
pane.setText(content1); // change content here
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
This is what I tried for content1 and its working fine.
I added this line
body table { border: 1px solid red }
sample code:
public static final String content1 = "<html>\r\n"
+ " <head>\r\n"
+ " <style type=\"text/css\">\r\n"
+ " <!--\r\n"
+ " table, th, td { border: 1px solid black }\r\n"
+ " body table { border: 1px solid red }\r\n"
+ " body, p { font-family: Courier; font-size: 14; }\r\n"
+ " -->\r\n"
+ " </style>\r\n"
I tried all the above solutions but unfortunately any of these did not work for me. I was searching for the solution and i got into this post
And i tried table, th, td { border-width: 1px solid black } voila it worked for me. I dont know why the plain border property did not work for me but it worked for others.
Thanks a lot for all you help Guys.
Related
I'm developing an app with Tradingview widget on Android 6.0 (Marshmallow)
I am running the tradingview code in WebView but it is not showing the chart.
This is my TradingView Widget code;
WebView webView = findViewById(R.id.webviewer);
String symbol = getIntent().getStringExtra("symbol");
String interval = getIntent().getStringExtra("interval");
String data = "<!-- TradingView Widget BEGIN -->\n" +
"<div class=\"tradingview-widget-container\">\n" +
" <div id=\"tradingview_357eb\"></div>\n" +
" <div class=\"tradingview-widget-copyright\"><span class=\"blue-text\">"+symbol+" Chart</span></div>\n" +
" <script type=\"text/javascript\" src=\"https://s3.tradingview.com/tv.js\"></script>\n" +
" <script type=\"text/javascript\">\n" +
" new TradingView.widget(\n" +
" {\n" +
" \"width\": 300,\n" +
" \"height\": 200,\n" +
" \"symbol\": \"BINANCE:"+symbol+"\",\n" +
" \"interval\": \""+interval+"\",\n" +
" \"timezone\": \"Europe/Istanbul\",\n" +
" \"theme\": \"light\",\n" +
" \"style\": \"1\",\n" +
" \"locale\": \"en\",\n" +
" \"toolbar_bg\": \"#f1f3f6\",\n" +
" \"enable_publishing\": false,\n" +
" \"hide_side_toolbar\": false,\n" +
" \"save_image\": false,\n" +
" \"studies\": [\n" +
" \"BB#tv-basicstudies\",\n" +
" \"RSI#tv-basicstudies\",\n" +
" \"StochasticRSI#tv-basicstudies\"\n" +
" ],\n" +
" \"container_id\": \"tradingview_357eb\"\n" +
"}\n" +
" );\n" +
" </script>\n" +
"</div>\n" +
"<!-- TradingView Widget END -->";
webView.getSettings().setJavaScriptEnabled(true);
webView.loadData(data, "text/html", "utf-8");
I tried it on Android 8.0 and it works but not on 6.0. Why? Am I missing something?
I created an app that uses Leaflet in it.
In the screen where the map is, there is also a progressBar where I allow uses to search in a specific radius.
The moment they change the value in the progressBar, it changes the size of the circle marker inside the map.
I had like that my map will change its zoom to fit that circle in it.
My code for loading the map is:
String Map_HTML = "<html>\n" +
"<head>\n" +
"\n" +
" <title>Quick Start - Leaflet</title>\n" +
"\n" +
" <meta charset=\"utf-8\" />\n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
"\n" +
" <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"docs/images/favicon.ico\" />\n" +
"\n" +
" <link rel=\"stylesheet\" href=\"https://unpkg.com/leaflet#1.4.0/dist/leaflet.css\" integrity=\"sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==\" crossorigin=\"\"/>\n" +
" <script src=\"https://unpkg.com/leaflet#1.4.0/dist/leaflet.js\" integrity=\"sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg==\" crossorigin=\"\"></script>\n" +
"\n" +
"\n" +
"\n" +
"<style>\n" +
"body {\n" +
"padding: 0;\n" +
"margin: 0;\n" +
"}\n" +
"html, body, #map {\n" +
"height: 100%;\n" +
"width: 100%;\n" +
"}\n" +
"</style>\n" +
"</head>\n" +
"<body>\n" +
"\n" +
"\n" +
"\n" +
"<div id=\"mapid\" style=\"width: " + dpWidth + "px; height: " + dpHeight * 0.3 + "px;\"></div>\n" +
"<script>\n" +
"\n" +
"var mymap = L.map('mapid',{zoomControl: false}).setView([" + Lat + ", " + Lon + "], 10);\n" +
"\n" +
" L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {\n" +
" minZoom: 7,\n" +
" maxZoom: 17,\n" +
" attribution: '© OpenStreetMap contributors' \n" +
" }).addTo(mymap);\n" +
"\n" +
"mymap.attributionControl.setPosition('topleft')\n" +
"L.control.zoom({\n" +
"position: 'bottomright'\n" +
"}).addTo(mymap);\n" +
"L.marker([" + Lat + ", " + Lon + "]).addTo(mymap)\n" +
" .bindPopup(\"<b>My Location</b>\").openPopup();\n" +
"\n" +
"L.circle([" + Lat + ", " + Lon + "], " + Radius + ", {\n" +
" color: 'red',\n" +
" fillColor: '#8275FE',\n" +
" fillOpacity: 0.4,\n" +
" weight: '0'\n" +
"}).addTo(mymap);\n" +
"\n" +
"\n" +
"var popup = L.popup();\n" +
"\n" +
"</script>\n" +
"\n" +
"</body>\n" +
"</html>";
where Radius is a parameter I insert based on the value of the progressBar.
Right now it always initializes the map with zoom: 10 because I don't know how to change it dynamically as I want.
Any way to do so?
Thank you
the map can fit to the bounds of the circle with mymap.fitBounds(circle.getBounds());.
Change your code to:
"var circle = L.circle([" + Lat + ", " + Lon + "], " + Radius + ", {\n" +
" color: 'red',\n" +
" fillColor: '#8275FE',\n" +
" fillOpacity: 0.4,\n" +
" weight: '0'\n" +
"}).addTo(mymap);\n" +
"mymap.fitBounds(circle.getBounds());\n" +
I'm trying to do a hover effect on an: <a href... class.
I have 2 <a href, one is a standard link and the other one has to be a button.
.btnMail:hover
#btn:hover
This works on GMAIL, but not on Outlook Web. The only way I got the :hover effect to work on outlook was doing just an a:hover but this affects all <a tags.
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, false, "utf-8");
String htmlMsg = ""
+ "<style type=\"text/css\">" +
" .btnMail {\r\n" +
" background-color: #007bff;\r\n" +
" cursor: pointer;\r\n" +
" border: none;\r\n" +
" border-radius: 4px;\r\n" +
" text-decoration: none;\r\n" +
" text-decoration-color: white !important;" +
" color: white !important;\r\n" +
" padding: 15px 32px;\r\n" +
" text-align: center;\r\n" +
" display: inline-block;\r\n" +
" font-size: 18px;\r\n" +
" }\r\n" +
" .btnMail:hover{\r\n" +
" background-color: #0069d9 !important;\r\n" +
" }\r\n"
+ "</style>"
+ "<div style=\"width:100%;height:100%;\">"
+ "<div style=\"margin-left:auto;margin-right:auto;width:550px;\">"
+ "<h3>" + messages.getMessage("mail.reset", null, locale) + "</h3>"
+ "<div>" + messages.getMessage("mail.hello", null, locale) + " " + restoreUser.getUsername() + ", <br><br>"
+ messages.getMessage("mail.body", null, locale) + "</div><br>"
+ "<a id=\"btn\" class=\"btnMail\" style=\"cursor: pointer;\" href=\"" + tokenLink +"\">"
+ messages.getMessage("mail.button", null, locale) + "</a><br>"
+ "<div>" + messages.getMessage("mail.validtime", null, locale) + "<br><br>"
+ messages.getMessage("mail.thanks", null, locale) + "<br>"
+ messages.getMessage("header.companyname", null, locale) +"</div>"
+ "<br>"
+ "<hr/>"
+ "<div style=\"font-size:12px;\">" + messages.getMessage("mail.link", null, locale) +"<br>"
+ "" + tokenLink +"</div>"
+ "</div>"
+ "</div>"
+ "";
mimeMessage.setContent(htmlMsg, "text/html");
https://gyazo.com/e8f3a7105b66e6da61ed957e2437cc4d
There are many css elements that do not perform well in email clients.
Hover is one if the elements without a broad support.
This element along with support information for other ones can be found here, amongst other resources.
As for your html in your example. Keep in mind that many spam filters are looking for poor html syntax as a sign of spammy content. You should consider adding html, head and body tags to your message.
I am trying to drag & drop 2 elements into my workspace but they are dropped over each other, how can i specify the position of dropping the elements?
I am using dragAndDrop() function
Actions act=new Actions(driver);
act.dragAndDrop(From, To).build().perform();
enter image description here
Using dragAndDrop() method you can perform drag and drop operations on only one location at a time. it is usually used to perform operations on web element which is capable of dropping. please find the reference http://demoqa.com/droppable/ for various types of dropable elements.
To implement drag and drop operation -
Example:
WebElement From=driver.findElement(By.xpath( <<source xpath>> ));
WebElement To=driver.findElement(By.xpath( <<destination xpath>> ));
Actions actions=new Actions(driver);
actions.dragAndDrop(From, To).build().perform();
to drag and drop another element, you need to perform above all steps again.
Hope this helps :)
Try Using below code :
public static void dragAndDropViaJQueryHelper(WebDriver driver, String dragSourceJQuerySelector, String dropTargetJQuerySelector) {
String jqueryScript = "(function( jquery ) {\r\n" +
" jquery.fn.simulateDragDrop = function(options) {\r\n" +
" return this.each(function() {\r\n" +
" new jquery.simulateDragDrop(this, options);\r\n" +
" });\r\n" +
" };\r\n" +
" jquery.simulateDragDrop = function(elem, options) {\r\n" +
" this.options = options;\r\n" +
" this.simulateEvent(elem, options);\r\n" +
" };\r\n" +
" jquery.extend(jquery.simulateDragDrop.prototype, {\r\n" +
" simulateEvent: function(elem, options) {\r\n" +
" /*Simulating drag start*/\r\n" +
" var type = 'dragstart';\r\n" +
" var event = this.createEvent(type);\r\n" +
" this.dispatchEvent(elem, type, event);\r\n" +
"\r\n" +
" /*Simulating drop*/\r\n" +
" type = 'drop';\r\n" +
" var dropEvent = this.createEvent(type, {});\r\n" +
" dropEvent.dataTransfer = event.dataTransfer;\r\n" +
" this.dispatchEvent(jquery(options.dropTarget)[0], type, dropEvent);\r\n" +
"\r\n" +
" /*Simulating drag end*/\r\n" +
" type = 'dragend';\r\n" +
" var dragEndEvent = this.createEvent(type, {});\r\n" +
" dragEndEvent.dataTransfer = event.dataTransfer;\r\n" +
" this.dispatchEvent(elem, type, dragEndEvent);\r\n" +
" },\r\n" +
" createEvent: function(type) {\r\n" +
" var event = document.createEvent(\"CustomEvent\");\r\n" +
" event.initCustomEvent(type, true, true, null);\r\n" +
" event.dataTransfer = {\r\n" +
" data: {\r\n" +
" },\r\n" +
" setData: function(type, val){\r\n" +
" this.data[type] = val;\r\n" +
" },\r\n" +
" getData: function(type){\r\n" +
" return this.data[type];\r\n" +
" }\r\n" +
" };\r\n" +
" return event;\r\n" +
" },\r\n" +
" dispatchEvent: function(elem, type, event) {\r\n" +
" if(elem.dispatchEvent) {\r\n" +
" elem.dispatchEvent(event);\r\n" +
" }else if( elem.fireEvent ) {\r\n" +
" elem.fireEvent(\"on\"+type, event);\r\n" +
" }\r\n" +
" }\r\n" +
" });\r\n" +
"})(jQuery);";
((JavascriptExecutor) driver).executeScript(jqueryScript);
String dragAndDropScript = "jQuery('" + dragSourceJQuerySelector + "').simulateDragDrop({ dropTarget: '" + dropTargetJQuerySelector + "'});";
((JavascriptExecutor) driver).executeScript(dragAndDropScript);
}
Just pass css or xpath selectors in parameters.
Hope that helps you.
If that does not help you I can help you out with some other solutions also.
I am trying to build a Google Maps application in a JSwing application using JXBrowser. I am using a API key provided by Google.
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.BrowserFactory;
import javax.swing.*;
import java.awt.*;
public class GAPIJXBrowser {
public static void main(String[] args) {
final Browser browser = BrowserFactory.create();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(browser.getView().getComponent(), BorderLayout.CENTER);
frame.setSize(700, 500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
browser.executeJavaScript("<!DOCTYPE html>\n" +
"<html>\n" +
" <head>\n" +
" <title>Simple Map</title>\n" +
" <meta name=\"viewport\" content=\"initial-scale=1.0, user-scalable=no\">\n" +
" <meta charset=\"utf-8\">\n" +
" <style>\n" +
" html, body, #map-canvas {\n" +
" height: 100%;\n" +
" margin: 0px;\n" +
" padding: 0px\n" +
" }\n" +
" </style>\n" +
" <script src=\"https://maps.googleapis.com/maps/api/js?key=MyKey\"></script>\n" +
" <script>\n" +
"var map;\n" +
"function initialize() {\n" +
" var mapOptions = {\n" +
" zoom: 8,\n" +
" center: new google.maps.LatLng(-34.397, 150.644)\n" +
" };\n" +
" map = new google.maps.Map(document.getElementById('map-canvas'),\n" +
" mapOptions);\n" +
"}\n" +
"\n" +
"google.maps.event.addDomListener(window, 'load', initialize);\n" +
"\n" +
" </script>\n" +
" </head>\n" +
" <body>\n" +
" <div id=\"map-canvas\"></div>\n" +
" </body>\n" +
"</html>");
}
}
Page loads but getting the following error while executing:
stating : google has disabled uso of the Maps api for this application.
I even tried a new key.
What wrong am I doing it over here?
This error message indicates that you use wrong API Key. Please make sure that you generate API Key correctly and you put it into the following line instead of the MyKey:
<script src=\"https://maps.googleapis.com/maps/api/js?key=MyKey\"></script>