package org.vorthmann.zome.ui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import org.vorthmann.ui.Controller;
public class LessonPanel extends JPanel implements PropertyChangeListener
{
private static final Logger logger = Logger.getLogger( "org.vorthmann.zome.ui" );
private final Controller mController;
private final JTextArea titleArea, contentArea;
private final TextEvents titleEvents = new TextEvents( "title" );
private final TextEvents contentEvents = new TextEvents( "content" );
private final boolean isEditor;
public LessonPanel( final Controller controller )
{
mController = controller;
mController .addPropertyListener( this );
this.isEditor = controller .userHasEntitlement( "lesson.edit" ) && ! controller .propertyIsTrue( "reader.preview" );
this .setLayout( new BorderLayout() );
{
JPanel pagelistPanel = new PagelistPanel( controller );
this .add( pagelistPanel, BorderLayout.LINE_START );
// here's the containment hierarchy
JPanel pagePanel = new JPanel( new BorderLayout() );
if ( ! this .isEditor )
{
pagePanel .setBorder( BorderFactory .createEmptyBorder( 10, 12, 10, 12 ) );
pagePanel .setBackground( Color .WHITE );
}
{
{
JPanel titlePanel = new JPanel( new BorderLayout() );
titleArea = new JTextArea( 1, 15 );
titleArea .setBorder( BorderFactory .createLineBorder( Color.GRAY ) );
titleArea .setLineWrap( true );
titleArea .setWrapStyleWord( true );
// titleArea .setMaximumSize( new Dimension( 500, 20 ) );
// titleArea .setMinimumSize( new Dimension( 500, 20 ) );
if ( this.isEditor )
titlePanel .setBorder( BorderFactory .createTitledBorder( "page title" ) );
else
{
// titlePanel .setBorder( BorderFactory .createEmptyBorder( 4, 4, 4, 4 ) );
Font biggestFont = titleArea .getFont() .deriveFont( Font.BOLD, 16f );
titleArea .setBorder( BorderFactory .createEmptyBorder() );
titleArea .setFont( biggestFont );
titleArea .setEditable( false );
}
titlePanel .add( titleArea, BorderLayout.CENTER );
pagePanel .add( titlePanel, BorderLayout.NORTH );
}
{
JPanel panel = new JPanel( new BorderLayout() );
// panel .setMinimumSize( new Dimension( 500, 800 ) );
// panel .setPreferredSize( new Dimension( 500, 800 ) );
{
contentArea = new JTextArea( 20, 15 );
// no border necessary with scroller
// contentArea .setBorder( BorderFactory .createLineBorder( Color.GRAY ) );
contentArea .setLineWrap( true );
contentArea .setWrapStyleWord( true );
contentArea .setMaximumSize( new Dimension( 170, 800 ) );
if ( this.isEditor )
{
panel .setBorder( BorderFactory .createTitledBorder( "page content" ) );
contentArea .getDocument() .addUndoableEditListener( new UndoableEditListener() {
@Override
public void undoableEditHappened( UndoableEditEvent e )
{
e .getEdit();
}
} );
}
else
{
panel .setBorder( BorderFactory .createEmptyBorder() );
contentArea .setBorder( BorderFactory .createEmptyBorder() );
contentArea .setEditable( false );
}
JScrollPane contentScroller = new JScrollPane( contentArea );
contentScroller .setBorder( BorderFactory .createEmptyBorder() );
panel .add( contentScroller, BorderLayout.CENTER );
}
pagePanel .add( panel, BorderLayout.CENTER );
}
if ( mController .propertyIsTrue( "has.pages" ) )
updatePageState();
}
this .add( pagePanel, BorderLayout.CENTER );
}
}
public void updatePageState()
{
Document title = new PlainDocument();
Document content = new PlainDocument();
String titleString = mController .getProperty( "title" );
try {
title .insertString( 0, titleString, null );
content .insertString( 0, mController .getProperty( "content" ), null );
} catch ( BadLocationException e ) {
logger .log( Level.SEVERE, "Bad textArea location", e );
}
title .addDocumentListener( titleEvents );
content .addDocumentListener( contentEvents );
titleArea .setDocument( title );
contentArea .setDocument( content );
}
protected static JButton createButton( String actionCommand, ActionListener listener )
{
String iconPath = "/org/vorthmann/zome/ui/" + actionCommand + ".gif";
JButton button = new JButton();
java.net.URL imgURL = LessonPanel.class .getResource( iconPath );
if ( imgURL != null )
button .setIcon( new ImageIcon( imgURL ) );
else
logger .warning( "Couldn't find resource: " + iconPath );
button .addActionListener( listener );
button .setActionCommand( actionCommand );
return button;
}
// DocumentListener methods
private class TextEvents implements DocumentListener
{
private final String whichField;
public TextEvents( String whichField )
{
this.whichField = whichField;
}
@Override
public void changedUpdate( DocumentEvent e )
{}
@Override
public void insertUpdate( DocumentEvent e )
{
int start = e .getOffset();
int len = e .getLength();
Document doc = e .getDocument();
try {
String text = doc .getText( start, len );
mController .doAction( "insertUpdateEvent " + whichField + " " + start + " " + text, null );
} catch ( BadLocationException e1 ) {
logger .log( Level.SEVERE, "Bad textArea location", e1 );
} catch ( Exception e2 ) {
logger .log( Level.SEVERE, "unable to insert text", e2 );
}
}
@Override
public void removeUpdate( DocumentEvent e )
{
int start = e .getOffset();
int len = e .getLength();
try {
mController .doAction( "removeUpdateEvent " + whichField + " " + start + " " + len, null );
} catch ( Exception e1 ) {
logger .log( Level.SEVERE, "unable to remove text", e1 );
}
}
}
@Override
public void propertyChange( PropertyChangeEvent e )
{
if ( e .getPropertyName() .equals( "currentPage" ) )
{
updatePageState();
}
}
}