java - Java JEditorPane 内联表未按预期工作
问题描述
我JEditorPane
用来在我的“游戏构建器”中进行代码更正,这有助于为我的另一个游戏创建地图。
(然后内部使用HTMLEditorKit
.inline CSS 并<div>
用于格式化)
我希望获得像 IDE 一样的视觉效果:
[预期](我的 StackOverflow 排名太低,无法在此处发布图像)
然而,实际效果是:[实际]
下面是我的代码:(
其中strl[i]
是第i个子字符串,它在语法上是正确的。如果存在多个与部分输入的字符串匹配的可能函数,则在strl[i]
,它们都将存储在同一个字符串中,由$$
)分隔
...(some code related to IDE functionalities)...
String txt = "";
for(int i = 0; i < strl.length; i++){
String[] list; boolean cont = strl[i].contains("$$");
if(cont) {
list = strl[i].split("\\$\\$");
txt += "<table style=\"display:inline;vertical-align:top;\"><tr><td>";
}
else list = new String[]{strl[i]};
for(String elem : list){
switch(elem.charAt(0)){//assigning colours by the first character in the string
//error colour (red - orange)
case 'e': txt += "<span style=\"color:red;background-color:yellow;font-weight:bold;\">"; break;
//syntax component (green)
case 'g': txt += "<span style=\"color:green;font-weight:bold;\">"; break;
//recognized function (blue)
case 'b': txt += "<span style=\"color:blue;font-weight:bold;\">"; break;
//recognized function (cyan)
case 'c': txt += "<span style=\"color:cyan;font-weight:bold;\">"; break;
}
txt += elem.substring(elem.indexOf("|")+1);//you may interpret this as "getting the value of substring"
switch(elem.charAt(0)){
case 'e': case 'g': case 'b': case 'c':
txt += "</span>";
}
if(cont) txt += "<br>";
}
if(cont) txt += "</td></tr></table>";
}
if(tip.equals("<br><b>In this code:</b>")) tip += "<br>There is no syntax error.";
msg += txt + tip;
cmdaid.setText(msg); //cmdaid is the JEditorPane in question.
cmdaid.select(0,0);
对于输入if:{hav
,生成的 html 字符串为:
<table style="display:inline;vertical-align:top;"><tr><td>
<span style="color:blue;font-weight:bold;">have</span><br><span style="color:blue;font-weight:bold;">haved</span><br>
</td></tr></table>
<span style="color:red;background-color:yellow;font-weight:bold;">}</span><br>
<b>In this code:</b><br>The "if"-"then"-"else" structure should be in the form of: "if:{...}then:{...}else:{...}"
在 W3School 的 Tryit 编辑器中正确显示:https
://www.w3schools.com/code/tryit.asp?filename=GSTCQD0WF5WK
这表明我的代码在 HTML/CSS 中应该没问题,但它不能作为预期在JEditorPane
设置中:
JEditorPane cmdaid = new JEditorPane();
cmdaid.setEditable(false);
cmdaid.setOpaque(false);
cmdaid.setFont(new Font("Times New Roman", 0, 16));
cmdaid.setEditorKit(new HTMLEditorKit());
cmdaid.setPreferredSize(new Dimension(200, 100));
JScrollPane cmdp = new JScrollPane(cmdaid, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
由于其他格式完全没问题,我希望 JEditorPane 设置没有问题。然而,内联表无法按预期工作。
我的问题是,有什么办法可以解决这个问题,还是 JEditorPane 的内在问题?
虽然我认为当问题得到回答时,我可能已经在开发另一个游戏了 :|
不过,提前感谢您的详细解释。
解决方案
根据oracle文档和问题帖子中的评论,Java支持的HTMLEditorKit仅支持HTML 3.2,这是一个相当原始的版本。不支持某些高级 CSS。
在阅读了问题帖子中的评论后,我进行了以下修改:
txt = ""; ArrayList<String> txts = new ArrayList<String>(); int l = 0;
for(int i = 0; i < strl.length; i++){
String[] list; boolean cont = strl[i].contains("$$"); char ch = strl[i].charAt(0);
list = new String[]{strl[i].substring(strl[i].indexOf("|")+1)};
if(cont) list = list[0].split("\\$\\$");
switch(ch){
//error colour (red - orange)
case 'e': txt += "<span style=\"color:red;background-color:yellow;font-weight:bold;\">"; break;
//syntax component (green)
case 'g': txt += "<span style=\"color:green;font-weight:bold;\">"; break;
//recognized function (blue)
case 'b': txt += "<span style=\"color:blue;font-weight:bold;\">"; break;
//recognized function (cyan)
case 'c': txt += "<span style=\"color:cyan;font-weight:bold;\">"; break;
}
int maxl = -1;
for(String elem : list) if(elem.length() > maxl) maxl = elem.length();
txt += pad(list[0], maxl); l += maxl;
for(int I = 1; I < list.length; I++){
if(I <= txts.size()) txts.set(I-1, txts.get(I-1)+fpad(pad(list[I], maxl), l-txts.get(I-1).length()));
else txts.add(I-1, fpad(pad(list[I], maxl), l));
}
switch(ch){
case 'e': case 'g': case 'b': case 'c':
txt += "</span>";
}
}
if(tip.equals("<br><b>In this code:</b>")) tip += "<br>There is no syntax error.";
msg += txt + "<span style=\"color:blue;font-weight:bold;\">";
for(String subt : txts) msg += "<br>" + toHTML(subt);
msg += "</span>" + tip;
cmdaid.setText("<div style=\"font-family:monospace;\">"+msg+"</div>");
cmdaid.select(0,0);
和:
String fpad(String in, int l){return String.format("%1$" + l + "s", in);}
//does front padding from string in to string with length l
String pad(String in, int l){return String.format("%1$-" + l + "s", in);}
//does right padding from string in to string with length l
String toHTML(String in){return in.replace(" ", " ");}
//transform string to HTML form, as HTML eats multiple adjacent whitespaces
我添加了另一个数组来存储额外的字符串建议,问题得到解决(参见[NOW])。我曾经monospacing
确保字符之间有规律的间距,虽然FontRenderingContext
可以使用更复杂的,但我更愿意在我的应用程序中为这个(也许是次要的)组件保持简单。
[结案]
推荐阅读
- java - Android SmsManager.sendTextMessage 失败且没有错误
- css - 显示时如何使img居中:块不起作用?
- ruby-on-rails - ActiveRecord 忽略验证
- c# - 在这种情况下,EF Core 生成的 SQL 效率很低,有什么解决方法吗?
- arrays - Dart 上的 Google Kick Start Time Limited
- android - 有没有办法通过识别用户而不是设备来发送通知?
- docker - Windows 8 上的 Docker 安装问题
- reactjs - 我在使用反应路由器dom的反应应用程序中遇到问题,并且有像authaPage这样的页面路由,
- python - 为什么安装pygobject会出错并且无法进一步安装
- javascript - 如何在 npm 上发布 typescript ReactJS 组件?