Java JEditorPane 内联 table 未按预期工作
Java JEditorPane inline table not working as expected
我正在使用 JEditorPane
在我的“游戏构建器”中进行代码更正,这有助于为我的另一个游戏创建地图。
(这在内部使用 HTMLEditorKit
。内联 CSS 和 <div>
用于格式化)
我希望获得像 IDE:
这样的 visual 效果
[EXPECTED](我的 Whosebug 排名太低,无法在此处 post 图片)
然而,实际效果是:[ACTUAL]
下面是我的代码:
(其中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 设置没有问题。然而,内联 table 无法按预期工作。
我的问题是,有什么方法可以解决这个问题,还是 JEditorPane 的固有问题?
虽然我认为当问题得到回答时,我可能已经在开发另一个游戏了:|
不过,还是先谢谢你的详细解释。
根据oracle documentations和问题post中的评论,HTMLJava支持的EditorKit仅支持HTML 3.2,这是一个相当原始的版本。不支持某些高级CSS。
阅读问题post中的评论后,我做了以下修改:
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
,但我更愿意在我的应用程序中对这个(可能是次要的)组件保持简单。
[结案]
我正在使用 JEditorPane
在我的“游戏构建器”中进行代码更正,这有助于为我的另一个游戏创建地图。
(这在内部使用 HTMLEditorKit
。内联 CSS 和 <div>
用于格式化)
我希望获得像 IDE:
这样的 visual 效果
[EXPECTED](我的 Whosebug 排名太低,无法在此处 post 图片)
然而,实际效果是:[ACTUAL]
下面是我的代码:
(其中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 设置没有问题。然而,内联 table 无法按预期工作。
我的问题是,有什么方法可以解决这个问题,还是 JEditorPane 的固有问题?
虽然我认为当问题得到回答时,我可能已经在开发另一个游戏了:|
不过,还是先谢谢你的详细解释。
根据oracle documentations和问题post中的评论,HTMLJava支持的EditorKit仅支持HTML 3.2,这是一个相当原始的版本。不支持某些高级CSS。
阅读问题post中的评论后,我做了以下修改:
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
,但我更愿意在我的应用程序中对这个(可能是次要的)组件保持简单。
[结案]