怎样让JavaSwing创建的JTextArea里的内容中的java关键字用不同的字体和颜色显示
判断java关键字,如果是的话,给个不一样的设置颜色
直接将JTextArea放进JScrollPane,再将JScrollPane加到JFrame里
JFrame frame = new JFrame();//创建一个JFrame窗体
frame.setBounds(100, 100, 400, 200);//自定义Jframe位置并设置大小为100*50
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//用于关闭窗体
frame.getContentPane().setLayout(null);//设置为绝对布局
JTextArea text1= new JTextArea("置换结果显示区域");//创建一个JTextArea,这里不必设置大小
JScrollPane scrollpane=new JScrollPane();//创建滚动条面板
scrollpane.setBounds(20,20,100,50);//自定义该面板位置并设置大小为100*50
scrollpane.setViewportView(text1);//(这是关键!不是用add)把text1组件放到滚动面板里
frame.add(scrollpane);//将滚动条面板加到窗体
frame.setVisible(true);//放在最后,让整个窗体可视
△下面是JScrollPane.setViewportView(Component view)的API:
Creates a viewport if necessary and then sets its view. Applicationsthat don’t provide the view directly to the JScrollPaneconstructorshould use this method to specify the scrollable child that’s goingto be displayed in the scrollpane. For example:
JScrollPane scrollpane = new JScrollPane();
scrollpane.setViewportView(myBigComponentToScroll);
Applications should not add children directly to the scrollpane.
也就是:不直接为JScrollPane构造方法提供视图的应用程序,应使用setViewportView()这种方法,指定将显示在滚动窗格中的滚动组件子级。应用程序不应将子级直接添加到滚动窗格。
△不能用JScrollPane.add(JTextArea),这是无法将JTextArea真正加入到滚动条面板中去的。下面是JScrollPane.add(comp)的API:
Appends the specified component to the end of this container.This is a convenience method for addImpl.
This method changes layout-related information, and therefore,invalidates the component hierarchy. If the container has already beendisplayed, the hierarchy must be validated thereafter in order todisplay the added component.
也就是:将指定的组件附加到此容器的末尾。这是AddImpl的一种方便方法。此方法更改布局相关信息,因此使组件层次结构无效。如果容器已被禁用,则必须在此后验证层次结构,以便显示添加的组件。
问题解答:
在JTextArea中对Java关键字进行特殊显示,需要用到Java的JTextPane组件,而不是JTextArea,因为JTextArea只支持unstyled text,不能进行样式定制。下面是具体的解决方案:
Step 1: 导入所需的类库
import javax.swing.*;
import javax.swing.text.*;
import java.util.regex.Pattern;
Step 2: 创建JTextPane
JTextPane textPane = new JTextPane();
textPane.setEditable(false);
textPane.setPreferredSize(new Dimension(400, 200)); // 设置JTextPane的大小
Step 3: 创建样式
Style style = textPane.addStyle("myStyle", null);
StyleConstants.setForeground(style, Color.RED); // 设置字体颜色
StyleConstants.setBold(style, true); // 设置字体是否加粗
Step 4: 添加文本到JTextPane中
StyledDocument doc = textPane.getStyledDocument();
try {
doc.insertString(0, "public class MyClass {", doc.getStyle("myStyle"));
doc.insertString(doc.getLength(), "\n public static void main(String[] args) {", null);
doc.insertString(doc.getLength(), "\n System.out.println(\"Hello World!\");", null);
doc.insertString(doc.getLength(), "\n }", null);
doc.insertString(doc.getLength(), "\n}", doc.getStyle("myStyle"));
} catch (BadLocationException ex) {
ex.printStackTrace();
}
可以看到,使用doc.insertString方法向JTextPane中添加文本,其中第一个参数是文本的起始位置,第三个参数可以指定样式,如果是null,则表示使用默认样式。
Step 5: 对Java关键字进行特殊处理
为了对Java关键字进行特殊处理,需要先在文本中找出所有的Java关键字,然后再将其设置为特殊样式。
String text = "public class MyClass {\n public static void main(String[] args) {\n System.out.println(\"Hello World!\");\n }\n}";
String[] keywords = {"abstract", "assert", "boolean", "break", "byte",
"case", "catch", "char", "class", "const", "continue", "default",
"do", "double", "else", "enum", "extends", "final", "finally",
"float", "for", "if", "implements", "import", "instanceof",
"int", "interface", "long", "native", "new", "package", "private",
"protected", "public", "return", "short", "static", "strictfp",
"super", "switch", "synchronized", "this", "throw", "throws",
"transient", "try", "void", "volatile", "while"};
Pattern pattern = Pattern.compile("\\b(" + String.join("|", keywords) + ")\\b");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) { // 找出所有的Java关键字
int startIndex = matcher.start();
int endIndex = matcher.end();
doc.setCharacterAttributes(startIndex, endIndex-startIndex, doc.getStyle("myStyle"), false);
}
其中,第一步是定义Java关键字的数组,第二步是编译正则表达式,用于匹配Java关键字。第三步是使用Matcher.find方法找出所有的Java关键字,并将其设置为特殊样式。
完整代码如下:
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Demo {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
JTextPane textPane = new JTextPane();
textPane.setEditable(false);
textPane.setPreferredSize(new Dimension(400, 200));
Style style = textPane.addStyle("myStyle", null);
StyleConstants.setForeground(style, Color.RED);
StyleConstants.setBold(style, true);
StyledDocument doc = textPane.getStyledDocument();
String text = "public class MyClass {\n public static void main(String[] args) {\n System.out.println(\"Hello World!\");\n }\n}";
doc.setCharacterAttributes(0, text.length(), doc.getStyle(StyleContext.DEFAULT_STYLE), true);
doc.insertString(0, text, null);
String[] keywords = {"abstract", "assert", "boolean", "break", "byte",
"case", "catch", "char", "class", "const", "continue", "default",
"do", "double", "else", "enum", "extends", "final", "finally",
"float", "for", "if", "implements", "import", "instanceof",
"int", "interface", "long", "native", "new", "package", "private",
"protected", "public", "return", "short", "static", "strictfp",
"super", "switch", "synchronized", "this", "throw", "throws",
"transient", "try", "void", "volatile", "while"};
Pattern pattern = Pattern.compile("\\b(" + String.join("|", keywords) + ")\\b");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
int startIndex = matcher.start();
int endIndex = matcher.end();
doc.setCharacterAttributes(startIndex, endIndex-startIndex, doc.getStyle("myStyle"), false);
}
JScrollPane scrollPane = new JScrollPane(textPane);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}