faster repaint for large source files

This commit is contained in:
fros4943 2009-09-23 08:16:06 +00:00
parent fc34a4572b
commit 25767a1f0f

View file

@ -26,21 +26,35 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: CodeUI.java,v 1.7 2009/06/12 15:11:22 fros4943 Exp $ * $Id: CodeUI.java,v 1.8 2009/09/23 08:16:06 fros4943 Exp $
*/ */
package se.sics.cooja.mspmote.plugins; package se.sics.cooja.mspmote.plugins;
import java.awt.*; import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import javax.swing.*;
import javax.swing.AbstractListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import se.sics.mspsim.extutil.highlight.CScanner; import se.sics.mspsim.extutil.highlight.CScanner;
@ -188,7 +202,7 @@ public class CodeUI extends JPanel {
* @param codeData Source code * @param codeData Source code
* @param lineNr Line numer * @param lineNr Line numer
*/ */
public void displayNewCode(final File codeFile, final String[] codeData, final int lineNr) { public void displayNewCode(File codeFile, String[] codeData, final int lineNr) {
displayedFile = codeFile; displayedFile = codeFile;
if (codeData == null || codeData.length == 0) { if (codeData == null || codeData.length == 0) {
@ -196,14 +210,16 @@ public class CodeUI extends JPanel {
return; return;
} }
SwingUtilities.invokeLater(new Runnable() { logger.info("Opening " + codeFile + " (" + codeData.length + " lines)");
public void run() {
// Display code /* Create new list */
codeList = new JList(new CodeListModel(codeData)); final JList newList = new JList(new CodeListModel(codeData));
codeList.setBackground(Color.WHITE); newList.setBackground(Color.WHITE);
codeList.setFont(new Font("courier", 0, 12)); newList.setFont(new Font("courier", 0, 12));
codeList.setCellRenderer(new CodeCellRenderer(lineNr)); newList.setCellRenderer(new CodeCellRenderer(lineNr));
codeList.addMouseListener(new MouseListener() { ((CodeCellRenderer)newList.getCellRenderer()).setNice(false);
newList.setFixedCellHeight(12);
newList.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) { public void mousePressed(MouseEvent e) {
handleMouseEvent(e); handleMouseEvent(e);
} }
@ -220,10 +236,14 @@ public class CodeUI extends JPanel {
handleMouseEvent(e); handleMouseEvent(e);
} }
}); });
panel.removeAll();
panel.add(codeList);
createTokens(codeData); createTokens(codeData);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
panel.removeAll();
codeList = newList;
panel.add(codeList);
panel.validate();
displayLine(lineNr); displayLine(lineNr);
} }
}); });
@ -231,29 +251,32 @@ public class CodeUI extends JPanel {
/** /**
* Mark given line number in shown source code. * Mark given line number in shown source code.
* Should be called from AWT thread.
* *
* @param lineNumber Line number * @param lineNumber Line number
*/ */
public void displayLine(final int lineNumber) { public void displayLine(int lineNumber) {
if (codeList == null || lineNumber < 0) { if (codeList == null) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
codeList.updateUI();
}
});
return; return;
} }
SwingUtilities.invokeLater(new Runnable() { ((CodeCellRenderer) codeList.getCellRenderer()).setNice(false);
public void run() {
((CodeCellRenderer) codeList.getCellRenderer()).changeCurrentLine(lineNumber); ((CodeCellRenderer) codeList.getCellRenderer()).changeCurrentLine(lineNumber);
((CodeCellRenderer) codeList.getCellRenderer()).validate();
if (lineNumber > 0) {
int index = lineNumber - 1; int index = lineNumber - 1;
codeList.setSelectedIndex(index); codeList.setSelectedIndex(index);
codeList.ensureIndexIsVisible(Math.max(0, index-3)); codeList.ensureIndexIsVisible(Math.max(0, index-3));
codeList.ensureIndexIsVisible(Math.min(index+3, codeList.getModel().getSize())); codeList.ensureIndexIsVisible(Math.min(index+3, codeList.getModel().getSize()));
codeList.ensureIndexIsVisible(index); codeList.ensureIndexIsVisible(index);
}
codeList.updateUI(); codeList.updateUI();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
((CodeCellRenderer) codeList.getCellRenderer()).setNice(true);
codeList.repaint();
} }
}); });
} }
@ -268,11 +291,7 @@ public class CodeUI extends JPanel {
} }
final int currentLine = codeList.locationToIndex(new Point(event.getX(), event.getY())) + 1; final int currentLine = codeList.locationToIndex(new Point(event.getX(), event.getY())) + 1;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
codeList.setSelectedIndex(currentLine - 1); codeList.setSelectedIndex(currentLine - 1);
}
});
JPopupMenu popupMenu = createPopupMenu(displayedFile, currentLine); JPopupMenu popupMenu = createPopupMenu(displayedFile, currentLine);
popupMenu.setLocation(menuLocation); popupMenu.setLocation(menuLocation);
@ -397,26 +416,36 @@ public class CodeUI extends JPanel {
private class CodeCellRenderer extends JLabel implements ListCellRenderer { private class CodeCellRenderer extends JLabel implements ListCellRenderer {
private int currentIndex; private int currentIndex;
private boolean nice = true;
public CodeCellRenderer(int currentLineNr) { public CodeCellRenderer(int currentLineNr) {
this.currentIndex = currentLineNr - 1; this.currentIndex = currentLineNr - 1;
} }
public void setNice(boolean b) {
nice = b;
}
public void changeCurrentLine(int currentLineNr) { public void changeCurrentLine(int currentLineNr) {
this.currentIndex = currentLineNr - 1; this.currentIndex = currentLineNr - 1;
} }
private String getColoredLabelText(int lineNr, int lineStartPos, Token[] tokens, String code) { private String getColoredLabelText(int lineNr, int lineStartPos, Token[] tokens, String code) {
String html = "<html>"; StringBuilder sb = new StringBuilder();
sb.append("<html>");
/* Add line number */ /* Add line number */
String lineString = "0000" + Integer.toString(lineNr); String lineString = "0000" + Integer.toString(lineNr);
lineString = lineString.substring(lineString.length() - 4); lineString = lineString.substring(lineString.length() - 4);
html += "<font color=\"333333\">" + lineString + ": </font>"; sb.append("<font color=\"333333\">");
sb.append(lineString);
sb.append(": </font>");
/* Add code */ /* Add code */
if (tokens == null || tokens.length == 0 || lineStartPos < 0) { if (tokens == null || tokens.length == 0 || lineStartPos < 0) {
html += "<font color=\"000000\">" + code + "</font>"; sb.append("<font color=\"000000\">");
sb.append(code);
sb.append("</font>");
} else { } else {
for (int i=tokens.length-1; i >= 0; i--) { for (int i=tokens.length-1; i >= 0; i--) {
Token subToken = tokens[i]; Token subToken = tokens[i];
@ -466,11 +495,11 @@ public class CodeUI extends JPanel {
} }
code = code.replace(" ", " &nbsp;"); code = code.replace(" ", " &nbsp;");
html += code; sb.append(code);
} }
html += "</html>"; sb.append("</html>");
return html; return sb.toString();
} }
public Component getListCellRendererComponent( public Component getListCellRendererComponent(
@ -481,8 +510,9 @@ public class CodeUI extends JPanel {
boolean cellHasFocus) boolean cellHasFocus)
{ {
int lineNr = index + 1; int lineNr = index + 1;
if (!nice) {
if (tokensArray != null && index < tokensArray.length && tokensArray[index] != null) { setText((String) value);
} else if (tokensArray != null && index < tokensArray.length && tokensArray[index] != null) {
setText(getColoredLabelText(lineNr, tokensStartPos[index], tokensArray[index], (String) value)); setText(getColoredLabelText(lineNr, tokensStartPos[index], tokensArray[index], (String) value));
} else { } else {
setText(getColoredLabelText(lineNr, 0, null, (String) value)); setText(getColoredLabelText(lineNr, 0, null, (String) value));