/* * AboutDialog.java - About jEdit dialog box * :tabSize=4:indentSize=4:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 2000, 2001, 2002 Slava Pestov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.gjt.sp.jedit.gui; //{{{ Imports import javax.swing.*; import java.awt.event.*; import java.awt.*; import java.awt.geom.*; import java.awt.image.BufferedImage; import java.util.*; import java.util.List; import org.gjt.sp.jedit.*; import org.gjt.sp.util.Log; //}}} /** "About jEdit" dialog */ public class AboutDialog extends JDialog implements ActionListener { //{{{ AboutDialog constructor public AboutDialog(View view) { super(view,jEdit.getProperty("about.title"), true); setResizable(false); JButton closeBtn = new JButton(jEdit.getProperty("common.close")); closeBtn.addActionListener(this); getRootPane().setDefaultButton(closeBtn); JPanel p = new JPanel(new BorderLayout()); final AboutPanel aboutPanel = new AboutPanel(); JPanel flowP = new JPanel(new FlowLayout()); flowP.add(closeBtn); flowP.add(Box.createRigidArea(new Dimension(40, 40))); Dimension dim = new Dimension(10, 0); p.add(BorderLayout.WEST, Box.createRigidArea(dim)); p.add(BorderLayout.EAST, Box.createRigidArea(dim)); p.add(BorderLayout.NORTH, Box.createRigidArea(new Dimension(10, 10))); p.add(BorderLayout.SOUTH, flowP); p.add(BorderLayout.CENTER, aboutPanel); closeBtn.setToolTipText(jEdit.getProperty("about.navigate")); closeBtn.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { aboutPanel.handleKeyEvent(e); } }); setContentPane(p); pack(); setLocationRelativeTo(jEdit.getActiveView()); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { closeDialog(); } }); setVisible(true); } //}}} //{{{ actionPerformed() method public void actionPerformed(ActionEvent e) { closeDialog(); } //}}} //{{{ closeDialog() method private void closeDialog() { AboutPanel.stopThread(); dispose(); } //}}} //{{{ AboutPanel class private static class AboutPanel extends JComponent implements Runnable { private BufferedImage bufImage; private Graphics2D g; private static final Font defaultFont = UIManager.getFont("Label.font"); private final Font bottomLineFont = defaultFont.deriveFont(9.8f); private final String sBottomLine; private final ImageIcon image; private final List<String> vLines; private static boolean doWork; private Thread th; private final FontMetrics fm; private int iLineHeight = 0, iListHeight, iLineCount = 0, iBottomLineXOffset = 0, iBottomLineYOffset = 0, iPipeLineCount = 0, w = 0, h = 0, y = 0; private static final int SLEEP_TIME = 30, iBottomPadding = 36, iTopPadding = 120; private static Rectangle2D.Float rectangle; private static GradientPaint gradientPaint; private boolean skipDrain = false; AboutPanel() { String mode; if (jEdit.getEditServer() != null) { if (jEdit.isBackgroundModeEnabled()) mode = jEdit.getProperty("about.mode.server-background"); else mode = jEdit.getProperty("about.mode.server"); } else mode = jEdit.getProperty("about.mode.standalone"); String[] args = { jEdit.getVersion(), mode, System.getProperty("java.vendor"), System.getProperty("java.version") }; sBottomLine = jEdit.getProperty("about.version",args); setFont(defaultFont); fm = getFontMetrics(defaultFont); FontMetrics fmBottom = getFontMetrics(bottomLineFont); iLineHeight = fm.getHeight(); image = (ImageIcon)GUIUtilities.loadIcon("about.png"); MediaTracker tracker = new MediaTracker(this); tracker.addImage(image.getImage(), 0); try { tracker.waitForID(0); } catch(Exception exc) { tell("AboutPanel: " + exc); } Dimension d = new Dimension(image.getIconWidth(), image.getIconHeight()); setSize(d); setPreferredSize(d); w = d.width; h = d.height; iBottomLineXOffset = (w / 2) - (fmBottom.stringWidth(sBottomLine) / 2); iBottomLineYOffset = h-iLineHeight/2; String aboutText = jEdit.getProperty("about.text.prefix") + "\n \n" + jEdit.getProperty("about.text.contributors") + "\n \n" + jEdit.getProperty("about.text.suffix"); String[] contributors = aboutText.split("\n"); vLines = Arrays.asList(contributors); iLineCount = vLines.size(); iListHeight = iLineCount * iLineHeight; startThread(); updateUI(); } private void handleKeyEvent(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_DOWN) { skipDrain = false; Collections.rotate(vLines, -1); } else if (e.getKeyCode() == KeyEvent.VK_UP) { skipDrain = false; Collections.rotate(vLines, 1); } else if ((e.getKeyCode() == KeyEvent.VK_LEFT) || (e.getKeyCode() == KeyEvent.VK_RIGHT) || (e.getKeyCode() == KeyEvent.VK_SPACE)) { skipDrain = ! skipDrain; e.consume(); } else if ((e.getKeyCode()) == KeyEvent.VK_ESCAPE) { e.consume(); JDialog d = GUIUtilities.getParentDialog(this); stopThread(); d.dispose(); } } private void drain() { if (skipDrain) return; if (bufImage == null) { //pre-computing all data that can be known at this time Dimension d = getSize(); bufImage = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_RGB); g = bufImage.createGraphics(); rectangle = new Rectangle2D.Float(0, iTopPadding, d.width, d.height-iBottomPadding-iTopPadding); //"+1" makes sure every new line from below comes up smoothly //cause it gets pre-painted and clipped as needed iPipeLineCount = 1 + (int)Math.ceil(rectangle.height/iLineHeight); y = d.height+iBottomPadding; g.setFont(defaultFont); gradientPaint = new GradientPaint( rectangle.width/2, iTopPadding+80, new Color(80, 80, 80), rectangle.width/2, iTopPadding, new Color(205, 205, 205) ); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } g.drawImage(image.getImage(), 0, 0, w, h, this); g.setFont(bottomLineFont); g.setPaint(new Color(55, 55, 55)); g.drawString(sBottomLine, iBottomLineXOffset, iBottomLineYOffset); // Draw a highlight effect g.setPaint(new Color(255, 255, 255, 50)); g.drawString(sBottomLine, iBottomLineXOffset + 1, iBottomLineYOffset + 1); g.setFont(defaultFont); g.setPaint(Color.black); g.drawRect(0, 0, w-1, h-1); g.clip(rectangle); g.setPaint(gradientPaint); int iDrawnLinesCount = 0, yCoor = 0; for (int i=0; i<iLineCount; i++) { //check whether the text line is above the canvas, if so, the code skips it yCoor = y+ i * iLineHeight; if (yCoor < iTopPadding) { continue; } //good to go, now draw only iPipeLineCount lines and get out from loop String sLine = vLines.get(i); int x = (w - fm.stringWidth(sLine))/2; g.drawString(sLine, x, yCoor); if (++iDrawnLinesCount >= iPipeLineCount) { break; } } y--; paint(getGraphics()); //check if the end of the list has been reached, //if so rewind if ((y + iListHeight) < iTopPadding) { y = h+iBottomPadding; } } @Override public void update(Graphics g) { paint(g); } @Override public void paint(Graphics panelGraphics) { if (panelGraphics != null && bufImage != null) { panelGraphics.drawImage(bufImage, 0, 0, w, h, this); } } public void run() { try { while(doWork) { drain(); Thread.sleep(SLEEP_TIME); } } catch(Exception exc) { Log.log(Log.ERROR, this, exc); } doWork = false; th = null; } public void startThread() { if (th == null) { th = new Thread(this); doWork = true; th.start(); } } public static void stopThread() { doWork = false; } public static void tell(Object obj) { String str = obj == null ? "NULL" : obj.toString(); JOptionPane.showMessageDialog(jEdit.getActiveView(), str, "Title", 1); } } //}}} }