Java tutorial
/* Copyright (c) 2010, Carl Burch. License information is located in the * com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */ package com.cburch.logisim.gui.start; import android.graphics.Color; import android.support.v4.view.ScrollingView; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Paint; import java.net.URL; import java.util.ArrayList; import javax.swing.JComponent; class AboutCredits extends ScrollingView { /** Time to spend freezing the credits before after after scrolling */ private static final int MILLIS_FREEZE = 1000; /** Speed of how quickly the scrolling occurs */ private static final int MILLIS_PER_PIXEL = 20; /** Path to Hendrix College's logo - if you want your own logo included, * please add it separately rather than replacing this. */ private static final String HENDRIX_PATH = "resources/logisim/hendrix.png"; private static final int HENDRIX_WIDTH = 50; private static class CreditsLine { private int y; private int type; private String text; private Image img; private int imgWidth; public CreditsLine(int type, String text) { this(type, text, null, 0); } public CreditsLine(int type, String text, Image img, int imgWidth) { this.y = 0; this.type = type; this.text = text; this.img = img; this.imgWidth = imgWidth; } } private Color[] colorBase; private Paint[] paintSteady; private Font[] font; private int scroll; private float fadeStop; private ArrayList<CreditsLine> lines; private int initialLines; // number of lines to show in initial freeze private int initialHeight; // computed in code based on above private int linesHeight; // computed in code based on above public AboutCredits() { scroll = 0; setOpaque(false); int prefWidth = About.IMAGE_WIDTH + 2 * About.IMAGE_BORDER; int prefHeight = About.IMAGE_HEIGHT / 2 + About.IMAGE_BORDER; setPreferredSize(new Dimension(prefWidth, prefHeight)); fadeStop = (float) (About.IMAGE_HEIGHT / 4.0); colorBase = new Color[] { new Color(143, 0, 0), new Color(48, 0, 96), new Color(48, 0, 96), }; font = new Font[] { new Font("Sans Serif", Font.ITALIC, 20), new Font("Sans Serif", Font.BOLD, 24), new Font("Sans Serif", Font.BOLD, 18), }; paintSteady = new Paint[colorBase.length]; for (int i = 0; i < colorBase.length; i++) { Color hue = colorBase[i]; paintSteady[i] = new GradientPaint(0.0f, 0.0f, derive(hue, 0), 0.0f, fadeStop, hue); } URL url = AboutCredits.class.getClassLoader().getResource(HENDRIX_PATH); Image hendrixLogo = null; if (url != null) { hendrixLogo = getToolkit().createImage(url); } // Logisim's policy concerning who is given credit: // Past contributors are not acknowledged in the About dialog for the current // version, but they do appear in the acknowledgements section of the User's // Guide. Current contributors appear in both locations. lines = new ArrayList<CreditsLine>(); linesHeight = 0; // computed in paintComponent lines.add(new CreditsLine(1, "www.cburch.com/logisim/")); lines.add(new CreditsLine(0, Strings.get("creditsRoleLead"), hendrixLogo, HENDRIX_WIDTH)); lines.add(new CreditsLine(1, "Carl Burch")); lines.add(new CreditsLine(2, "Hendrix College")); initialLines = lines.size(); lines.add(new CreditsLine(0, Strings.get("creditsRoleGerman"))); lines.add(new CreditsLine(1, "Uwe Zimmerman")); lines.add(new CreditsLine(2, "Uppsala universitet")); lines.add(new CreditsLine(0, Strings.get("creditsRoleGreek"))); lines.add(new CreditsLine(1, "Thanos Kakarountas")); lines.add(new CreditsLine(2, "\u03A4.\u0395.\u0399 \u0399\u03BF\u03BD\u03AF\u03C9\u03BD \u039D\u03AE\u03C3\u03C9\u03BD")); lines.add(new CreditsLine(0, Strings.get("creditsRolePortuguese"))); lines.add(new CreditsLine(1, "Theldo Cruz Franqueira")); lines.add(new CreditsLine(2, "PUC Minas")); lines.add(new CreditsLine(0, Strings.get("creditsRoleRussian"))); lines.add(new CreditsLine(1, "Ilia Lilov")); lines.add(new CreditsLine(2, "\u041C\u043E\u0441\u043A\u043E\u0432\u0441\u043A\u0438\u0439 \u0433\u043E\u0441\u0443\u0434\u0430\u0440\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439")); lines.add(new CreditsLine(2, "\u0443\u043D\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442 \u043F\u0435\u0447\u0430\u0442\u0438")); lines.add(new CreditsLine(0, Strings.get("creditsRoleTesting"))); lines.add(new CreditsLine(1, "Ilia Lilov")); lines.add(new CreditsLine(2, "\u041C\u043E\u0441\u043A\u043E\u0432\u0441\u043A\u0438\u0439 \u0433\u043E\u0441\u0443\u0434\u0430\u0440\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439")); lines.add(new CreditsLine(2, "\u0443\u043D\u0438\u0432\u0435\u0440\u0441\u0438\u0442\u0435\u0442 \u043F\u0435\u0447\u0430\u0442\u0438")); /* If you fork Logisim, feel free to change the above lines, but * please do not change these last four lines! */ lines.add(new CreditsLine(0, Strings.get("creditsRoleOriginal"), hendrixLogo, HENDRIX_WIDTH)); lines.add(new CreditsLine(1, "Carl Burch")); lines.add(new CreditsLine(2, "Hendrix College")); lines.add(new CreditsLine(1, "www.cburch.com/logisim/")); } public void setScroll(int value) { scroll = value; repaint(); } private int derive(int baseColor, int alpha) { return Color.argb(alpha, Color.red(baseColor), Color.green(baseColor), Color.blue(baseColor)); } @Override protected void paintComponent(Graphics g) { FontMetrics[] fms = new FontMetrics[font.length]; for (int i = 0; i < fms.length; i++) { fms[i] = g.getFontMetrics(font[i]); } if (linesHeight == 0) { int y = 0; int index = -1; for (CreditsLine line : lines) { index++; if (index == initialLines) initialHeight = y; if (line.type == 0) y += 10; FontMetrics fm = fms[line.type]; line.y = y + fm.getAscent(); y += fm.getHeight(); } linesHeight = y; } Paint[] paint = paintSteady; int yPos = 0; int height = getHeight(); int initY = Math.min(0, initialHeight - height + About.IMAGE_BORDER); int maxY = linesHeight - height - initY; int totalMillis = 2 * MILLIS_FREEZE + (linesHeight + height) * MILLIS_PER_PIXEL; int offs = scroll % totalMillis; if (offs >= 0 && offs < MILLIS_FREEZE) { // frozen before starting the credits scroll int a = 255 * (MILLIS_FREEZE - offs) / MILLIS_FREEZE; if (a > 245) { paint = null; } else if (a < 15) { paint = paintSteady; } else { paint = new Paint[colorBase.length]; for (int i = 0; i < paint.length; i++) { Color hue = colorBase[i]; paint[i] = new GradientPaint(0.0f, 0.0f, derive(hue, a), 0.0f, fadeStop, hue); } } yPos = initY; } else if (offs < MILLIS_FREEZE + maxY * MILLIS_PER_PIXEL) { // scrolling through credits yPos = initY + (offs - MILLIS_FREEZE) / MILLIS_PER_PIXEL; } else if (offs < 2 * MILLIS_FREEZE + maxY * MILLIS_PER_PIXEL) { // freezing at bottom of scroll yPos = initY + maxY; } else if (offs < 2 * MILLIS_FREEZE + (linesHeight - initY) * MILLIS_PER_PIXEL) { // scrolling bottom off screen yPos = initY + (offs - 2 * MILLIS_FREEZE) / MILLIS_PER_PIXEL; } else { // scrolling next credits onto screen int millis = offs - 2 * MILLIS_FREEZE - (linesHeight - initY) * MILLIS_PER_PIXEL; paint = null; yPos = -height + millis / MILLIS_PER_PIXEL; } int width = getWidth(); int centerX = width / 2; maxY = getHeight(); for (CreditsLine line : lines) { int y = line.y - yPos; if (y < -100 || y > maxY + 50) continue; int type = line.type; if (paint == null) { g.setColor(colorBase[type]); } else { ((Graphics2D) g).setPaint(paint[type]); } g.setFont(font[type]); int textWidth = fms[type].stringWidth(line.text); g.drawString(line.text, centerX - textWidth / 2, line.y - yPos); Image img = line.img; if (img != null) { int x = width - line.imgWidth - About.IMAGE_BORDER; int top = y - fms[type].getAscent(); g.drawImage(img, x, top, this); } } } }