package com.bytezone.diskbrowser.gui; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.util.Enumeration; import java.util.List; import java.util.prefs.Preferences; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.bytezone.common.FontAction.FontChangeEvent; import com.bytezone.common.FontAction.FontChangeListener; import com.bytezone.diskbrowser.applefile.HiResImage; import com.bytezone.diskbrowser.applefile.Palette; import com.bytezone.diskbrowser.applefile.PaletteFactory.CycleDirection; import com.bytezone.diskbrowser.applefile.VisicalcFile; import com.bytezone.diskbrowser.disk.DiskAddress; import com.bytezone.diskbrowser.disk.SectorList; class DataPanel extends JTabbedPane implements DiskSelectionListener, FileSelectionListener, SectorSelectionListener, FileNodeSelectionListener, FontChangeListener { private static final int TEXT_WIDTH = 65; JTextArea hexText; JTextArea disassemblyText; // these two panes are interchangeable JScrollPane formattedPane; JScrollPane imagePane; JTextArea formattedText; ImagePanel imagePanel; // internal class boolean debug; boolean imageVisible = false; // used to determine whether the text has been set boolean formattedTextValid; boolean hexTextValid; boolean assemblerTextValid; DataSource currentDataSource; final MenuHandler menuHandler; public DataPanel (MenuHandler mh, Preferences prefs) { this.menuHandler = mh; setTabPlacement (SwingConstants.BOTTOM); formattedText = new JTextArea (10, TEXT_WIDTH); formattedPane = setPanel (formattedText, "Formatted"); formattedText.setLineWrap (menuHandler.lineWrapItem.isSelected ()); formattedText.setText ("Please use the 'File->Set HOME folder...' command to " + "\ntell DiskBrowser where your Apple disks are located." + "\n\nTo see the contents of a disk in more detail, double-click" + "\nthe disk. You will then be able to select individual files to " + "view completely."); hexText = new JTextArea (10, TEXT_WIDTH); setPanel (hexText, "Hex dump"); disassemblyText = new JTextArea (10, TEXT_WIDTH); setPanel (disassemblyText, "Disassembly"); imagePanel = new ImagePanel (); imagePane = new JScrollPane (imagePanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); imagePane.getVerticalScrollBar ().setUnitIncrement (50); imagePane.getHorizontalScrollBar ().setUnitIncrement (25); addChangeListener (new ChangeListener () { @Override public void stateChanged (ChangeEvent e) { switch (getSelectedIndex ()) { case 0: if (!formattedTextValid) { if (currentDataSource == null) formattedText.setText (""); else setText (formattedText, currentDataSource.getText ()); formattedTextValid = true; } break; case 1: if (!hexTextValid) { if (currentDataSource == null) hexText.setText (""); else setText (hexText, currentDataSource.getHexDump ()); hexTextValid = true; } break; case 2: if (!assemblerTextValid) { if (currentDataSource == null) disassemblyText.setText (""); else setText (disassemblyText, currentDataSource.getAssembler ()); assemblerTextValid = true; } break; default: System.out.println ("Invalid index selected in DataPanel"); } } }); menuHandler.lineWrapItem.setAction (new LineWrapAction (formattedText)); menuHandler.colourQuirksItem.setAction (new ColourQuirksAction (this)); menuHandler.monochromeItem.setAction (new MonochromeAction (this)); menuHandler.debuggingItem.setAction (new DebuggingAction (this)); // fill in the placeholders created by the MenuHandler List palettes = HiResImage.getPalettes (); ButtonGroup buttonGroup = menuHandler.paletteGroup; Enumeration enumeration = buttonGroup.getElements (); int ndx = 0; while (enumeration.hasMoreElements ()) { JCheckBoxMenuItem item = (JCheckBoxMenuItem) enumeration.nextElement (); item.setAction (new PaletteAction (this, palettes.get (ndx++))); } menuHandler.nextPaletteItem.setAction (new NextPaletteAction (this, buttonGroup)); menuHandler.prevPaletteItem.setAction (new PreviousPaletteAction (this, buttonGroup)); } public void selectPalette (Palette palette) { HiResImage.getPaletteFactory ().setCurrentPalette (palette); if (currentDataSource instanceof HiResImage) { HiResImage image = (HiResImage) currentDataSource; image.setPalette (); imagePanel.setImage (image.getImage ()); } } public Palette cyclePalette (CycleDirection direction) { Palette palette = HiResImage.getPaletteFactory ().cyclePalette (direction); if (currentDataSource instanceof HiResImage) { HiResImage image = (HiResImage) currentDataSource; image.setPalette (); imagePanel.setImage (image.getImage ()); } return palette; } public void setColourQuirks (boolean value) { if (currentDataSource instanceof HiResImage) { HiResImage image = (HiResImage) currentDataSource; image.setColourQuirks (value); imagePanel.setImage (image.getImage ()); } } public void setMonochrome (boolean value) { if (currentDataSource instanceof HiResImage) { HiResImage image = (HiResImage) currentDataSource; image.setMonochrome (value); imagePanel.setImage (image.getImage ()); } } public void setDebug (boolean value) { debug = value; if (currentDataSource instanceof VisicalcFile) { VisicalcFile visicalcFile = (VisicalcFile) currentDataSource; VisicalcFile.setDebug (value); setText (formattedText, visicalcFile.getText ()); } else if (currentDataSource instanceof HiResImage) { setDataSource (currentDataSource); // toggles text/image } } private void setTabsFont (Font font) { formattedText.setFont (font); hexText.setFont (font); disassemblyText.setFont (font); imagePane.getVerticalScrollBar ().setUnitIncrement (font.getSize ()); } public String getCurrentText () { int index = getSelectedIndex (); return index == 0 ? formattedText.getText () : index == 1 ? hexText.getText () : disassemblyText.getText (); } private JScrollPane setPanel (JTextArea outputPanel, String tabName) { outputPanel.setEditable (false); outputPanel.setMargin (new Insets (5, 5, 5, 5)); JScrollPane outputScrollPane = new JScrollPane (outputPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); outputScrollPane.setBorder (null); // remove the ugly default border add (outputScrollPane, tabName); return outputScrollPane; } private void setDataSource (DataSource dataSource) { currentDataSource = dataSource; if (dataSource == null) { formattedText.setText (""); hexText.setText (""); disassemblyText.setText (""); removeImage (); return; } switch (getSelectedIndex ()) { case 0: // Formated/Image try { setText (formattedText, dataSource.getText ()); } catch (Exception e) { setText (formattedText, e.toString ()); e.printStackTrace (); } hexTextValid = false; assemblerTextValid = false; break; case 1: // Hex Dump setText (hexText, dataSource.getHexDump ()); formattedTextValid = false; assemblerTextValid = false; break; case 2: // Disassembly setText (disassemblyText, dataSource.getAssembler ()); hexTextValid = false; formattedTextValid = false; break; default: System.out.println ("Invalid index selected in DataPanel"); } BufferedImage image = dataSource.getImage (); if (image == null || debug) removeImage (); else { if (dataSource instanceof HiResImage) { ((HiResImage) dataSource).checkPalette (); image = dataSource.getImage (); } imagePanel.setImage (image); imagePane.setViewportView (imagePanel); if (!imageVisible) { int selected = getSelectedIndex (); remove (formattedPane); add (imagePane, "Formatted", 0); setSelectedIndex (selected); imageVisible = true; } } } private void removeImage () { if (imageVisible) { int selected = getSelectedIndex (); remove (imagePane); add (formattedPane, "Formatted", 0); setSelectedIndex (selected); imageVisible = false; } } private void setText (JTextArea textArea, String text) { textArea.setText (text); textArea.setCaretPosition (0); } private class ImagePanel extends JPanel { private BufferedImage image; private int scale = 1; public ImagePanel () { this.setBackground (Color.gray); } private void setImage (BufferedImage image) { this.image = image; int width, height; if (image != null) { Graphics2D g2 = image.createGraphics (); g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); width = image.getWidth (); height = image.getHeight (); } else width = height = 0; if (true) { if (width < 400 && width > 0) scale = (400 - 1) / width + 1; else scale = 1; if (scale > 4) scale = 4; } setPreferredSize (new Dimension (width * scale, height * scale)); repaint (); } @Override public void paintComponent (Graphics g) { super.paintComponent (g); if (image != null) { Graphics2D g2 = ((Graphics2D) g); g2.transform (AffineTransform.getScaleInstance (scale, scale)); g2.drawImage (image, (getWidth () - image.getWidth () * scale) / 2 / scale, 4, this); } } } @Override public void diskSelected (DiskSelectedEvent event) { setSelectedIndex (0); setDataSource (null); if (event.getFormattedDisk () != null) setDataSource (event.getFormattedDisk ().getCatalog ().getDataSource ()); else System.out.println ("bollocks in diskSelected()"); } @Override public void fileSelected (FileSelectedEvent event) { setDataSource (event.file.getDataSource ()); } @Override public void sectorSelected (SectorSelectedEvent event) { List sectors = event.getSectors (); if (sectors == null || sectors.size () == 0) return; if (sectors.size () == 1) setDataSource (event.getFormattedDisk ().getFormattedSector (sectors.get (0))); else setDataSource (new SectorList (event.getFormattedDisk (), sectors)); } @Override public void fileNodeSelected (FileNodeSelectedEvent event) { setSelectedIndex (0); setDataSource (event.getFileNode ()); // FileNode node = event.getFileNode (); } @Override public void changeFont (FontChangeEvent fontChangeEvent) { setTabsFont (fontChangeEvent.font); } }