【发布时间】:2015-11-01 15:54:20
【问题描述】:
我正在开发一个记事本程序,当用户键入时,如果键入某个单词(例如:public、void、private、protected、static),颜色会变为深红色(就像在 eclipse 中一样),但是如果用户打开一个文件,它不会改变颜色,即使用户键入,也不会发生任何事情。它仅在键入“新”文档时才有效。这是我的所有必要项目的简短版本:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
public class Test {
static JTabbedPane tabbedPane;
static JTextPane txt;
private static int findLastNonWordChar(String text, int index) {
while (--index >= 0) {
if (String.valueOf(text.charAt(index)).matches("\\W")) {
break;
}
}
return index;
}
private static int findFirstNonWordChar(String text, int index) {
while (index < text.length()) {
if (String.valueOf(text.charAt(index)).matches("\\W")) {
break;
}
index++;
}
return index;
}
private static void makeBold(SimpleAttributeSet sas) {
sas.addAttribute(StyleConstants.CharacterConstants.Bold, Boolean.TRUE);
}
private static void makeUnBold(SimpleAttributeSet sas) {
sas.addAttribute(StyleConstants.CharacterConstants.Bold, Boolean.FALSE);
}
private static JTextPane createEmptyDocument() {
final StyleContext cont = StyleContext.getDefaultStyleContext();
final AttributeSet attrRed = cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, new Color(127, 0, 85));
final AttributeSet attrBlack = cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, Color.BLACK);
SimpleAttributeSet sas = new SimpleAttributeSet();
DefaultStyledDocument document = new DefaultStyledDocument() {
public void insertString(int offset, String str, AttributeSet a) throws BadLocationException {
super.insertString(offset, str, a);
String text = getText(0, getLength());
int before = findLastNonWordChar(text, offset);
if (before < 0) before = 0;
int after = findFirstNonWordChar(text, offset + str.length());
int wordL = before;
int wordR = before;
while (wordR <= after) {
if (wordR == after || String.valueOf(text.charAt(wordR)).matches("\\W")) {
if (text.substring(wordL, wordR).matches("(\\W)*(public|static|void|main|private|protected)")) {
setCharacterAttributes(wordL, wordR - wordL, attrRed, false);
makeBold(sas);
setCharacterAttributes(wordL, wordR - wordL, sas, false);
} else {
setCharacterAttributes(wordL, wordR - wordL, attrBlack, false);
makeUnBold(sas);
setCharacterAttributes(wordL, wordR - wordL, sas, false);
}
wordL = wordR;
}
wordR++;
}
}
public void remove(int offs, int len) throws BadLocationException {
super.remove(offs, len);
String text = getText(0, getLength());
int before = findLastNonWordChar(text, offs);
if (before < 0) before = 0;
int after = findFirstNonWordChar(text, offs);
if (text.substring(before, after).matches("(\\W)*(public|static|void|private|protected)")) {
makeBold(sas);
setCharacterAttributes(before, after - before, attrRed, false);
setCharacterAttributes(before, after - before, sas, false);
} else {
makeUnBold(sas);
setCharacterAttributes(before, after - before, attrBlack, false);
setCharacterAttributes(before, after - before, sas, false);
}
}
};
return new JTextPane(document);
}
private static void readInFile(File file, JTextPane txt) {
try {
FileReader r = new FileReader(file);
txt.read(r, null);
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void createNewDocument(File file, JTabbedPane tabbedPane) {
txt = createEmptyDocument();
String fileName;
String theFile;
if (file == null) {
fileName = "Untitled";
theFile = "Untitled";
} else {
fileName = file.getName().toString();
theFile = file.toString();
readInFile(file, txt);
}
txt.setFont(new Font("Monospaced", Font.PLAIN, 14));
JScrollPane scrollPane = new JScrollPane(txt);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(scrollPane);
panel.setPreferredSize(new Dimension(800, 600));
tabbedPane.addTab(fileName, null, panel, theFile);
tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
tabbedPane.setFocusable(false);
txt.grabFocus();
}
private static JTabbedPane setupForTabs(JFrame frame) {
JPanel topPanel = new JPanel();
topPanel.setLayout(new BorderLayout());
tabbedPane = new JTabbedPane();
topPanel.add(tabbedPane);
frame.add(topPanel, BorderLayout.CENTER);
return tabbedPane;
}
static Action New = new AbstractAction("New") {
@Override
public void actionPerformed(ActionEvent e) {
createNewDocument(null, tabbedPane);
}
};
static Action Open = new AbstractAction("Open") {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
int result = chooser.showOpenDialog(tabbedPane);
if (result == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
createNewDocument(file, tabbedPane);
}
}
};
private static JMenuBar createMenuBar(JTabbedPane tabbedPane) {
JMenuBar menuBar = new JMenuBar();
JMenu file = new JMenu("File");
JMenuItem newDoc = new JMenuItem();
JMenuItem open = new JMenuItem();
New.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_DOWN_MASK));
newDoc.setAction(New);
Open.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK));
open.setAction(Open);
menuBar.add(file);
file.add(newDoc);
file.add(open);
return menuBar;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Notepad");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
tabbedPane = setupForTabs(frame);
createNewDocument(null, tabbedPane);
JMenuBar menuBar = createMenuBar(tabbedPane);
frame.setJMenuBar(menuBar);
frame.pack();
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
UIManager.put("swing.boldmetal", Boolean.FALSE);
createAndShowGui();
}
});
}
}
即使在打开文件时,我也需要更改这些关键字的颜色。现在我没有在打开文件后搜索单词的方法,但我担心当用户在打开的文档中键入时颜色会发生变化。如果有人可以提示我如何在打开文件后搜索单词并更改颜色,那也很棒。 :)
【问题讨论】:
-
1) 请参阅 Detection/fix for the hanging close bracket of a code block 了解我无法再费心修复的问题。 2) 曾经只需要源代码中的一个空白行。
{之后或}之前的空行通常也是多余的。 3) 使用逻辑一致的形式缩进代码行和块。缩进是为了让代码的流程更容易理解! -
没有意识到有一个悬挂支架。我很抱歉。
标签: java swing file jtextpane foreground