//
// @(#)PressDialog.java 9/2003
//
// Copyright 2003 Zachary DelProposto. All rights reserved.
// Use is subject to license terms.
//
//
// 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
// (at your option) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
// Or from http://www.gnu.org/
//
package dip.gui.dialog;
import dip.world.Phase;
import dip.gui.swing.XJScrollPane;
import dip.net.message.PressMessage;
import dip.net.message.MID;
import cz.autel.dmi.HIGConstraints;
import cz.autel.dmi.HIGLayout;
import dip.gui.*;
import dip.misc.Utils;
import dip.misc.Help;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.border.*;
import dip.net.message.*;
import java.util.*;
import java.text.*;
public class PressDialog extends XDialog
{
// i18n constants
//
private static final String PD_GETMAIL_ICON = "press.button.getmail.icon";
private static final String PD_WRITEMAIL_ICON = "press.button.writemail.icon";
private static final String PD_REPLYMAIL_ICON = "press.button.replymail.icon";
private static final String PD_PRINTMAIL_ICON = "press.button.printmail.icon";
private static final String PD_GETMAIL_LABEL = "press.button.getmail.label";
private static final String PD_WRITEMAIL_LABEL = "press.button.writemail.label";
private static final String PD_REPLYMAIL_LABEL = "press.button.replymail.label";
private static final String PD_PRINTMAIL_LABEL = "press.button.printmail.label";
private static final String LABEL_REPLY = "press.label.reply";
private static final String LABEL_SUBJECT = "press.label.subject";
private static final String LABEL_SENDER = "press.label.sender";
private static final String LABEL_DATE = "press.label.date";
private static final String LABEL_PHASE = "press.label.phase";
private static final String LABEL_FROM = "press.label.from";
private static final String LABEL_TO = "press.label.to";
private static final String DIALOG_TITLE = "press.dialog.title";
// column headers
private final static String[] HEADERS = {
Utils.getLocalString(LABEL_REPLY),
Utils.getLocalString(LABEL_SUBJECT),
Utils.getLocalString(LABEL_SENDER),
Utils.getLocalString(LABEL_DATE),
Utils.getLocalString(LABEL_PHASE)
};
// instance variables
//
private JToolBar toolBar;
private JSplitPane splitPane;
private JTable msgTable;
private MessagePanel msgPanel;
private SortedPressTM tableModel;
private Dimension optBtnSize = new Dimension();
private JButton getMail;
private JButton printMail;
private JButton writeMail;
private JButton replyMail;
public static void main(String[] adsf)
{
JFrame frame = new JFrame("test");
frame.setVisible(true);
displayDialog(frame);
}
public static void displayDialog(JFrame cf)
{
PressDialog pd = new PressDialog(cf);
pd.setup();
pd.pack();
pd.setVisible(true);
}// showPressDialog()
private PressDialog(JFrame cf)
{
super(cf, Utils.getLocalString(DIALOG_TITLE), false);
// create toolBar
toolBar = new JToolBar();
// create empty message window
msgPanel = new MessagePanel();
// create splitpane
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
}// PressDialog()
/** Setup and Layout the dialog. Could be made protected for extensibility. */
private void setup()
{
// toolbar button setup
getMail = makeButton(PD_GETMAIL_LABEL, PD_GETMAIL_ICON);
printMail = makeButton(PD_PRINTMAIL_LABEL, PD_PRINTMAIL_ICON);
writeMail = makeButton(PD_WRITEMAIL_LABEL, PD_WRITEMAIL_ICON);
replyMail = makeButton(PD_REPLYMAIL_LABEL, PD_REPLYMAIL_ICON);
// optimally size buttons
getMail.setMinimumSize(optBtnSize);
getMail.setMaximumSize(optBtnSize);
printMail.setMinimumSize(optBtnSize);
printMail.setMaximumSize(optBtnSize);
writeMail.setMinimumSize(optBtnSize);
writeMail.setMaximumSize(optBtnSize);
replyMail.setMinimumSize(optBtnSize);
replyMail.setMaximumSize(optBtnSize);
// toolBar setup
toolBar.setMargin(new Insets(5,5,5,5));
toolBar.setFloatable(false);
toolBar.setRollover(true);
toolBar.add(getMail);
toolBar.addSeparator();
toolBar.add(printMail);
toolBar.addSeparator();
toolBar.add(writeMail);
toolBar.addSeparator();
toolBar.add(replyMail);
// table setup
setupTable();
JScrollPane tableScroll = new XJScrollPane(msgTable);
tableScroll.getViewport().setBackground(msgTable.getBackground());
// splitPane setup
splitPane.setOneTouchExpandable(true);
splitPane.setTopComponent(tableScroll);
splitPane.setBottomComponent(msgPanel);
splitPane.setResizeWeight(0.5f);
// layout
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(toolBar, BorderLayout.NORTH);
mainPanel.add(splitPane, BorderLayout.CENTER);
setContentPane(mainPanel);
pack();
}// setup()
/** Make a toolbar button */
private JButton makeButton(String i18nKey, String i18nIconKey)
{
JButton button = new JButton(Utils.getLocalString(i18nKey));
button.setIcon(Utils.getIcon(Utils.getLocalString(i18nIconKey)));
button.setHorizontalTextPosition(SwingConstants.CENTER);
button.setHorizontalAlignment(SwingConstants.CENTER);
button.setVerticalTextPosition(SwingConstants.BOTTOM);
button.setVerticalAlignment(SwingConstants.CENTER);
button.setMargin( new Insets(0, 0, 0, 0) );
Dimension size = button.getPreferredSize();
optBtnSize.height = (size.height > optBtnSize.height) ? size.height : optBtnSize.height;
optBtnSize.width = (size.width > optBtnSize.width) ? size.width : optBtnSize.width;
return button;
}// makeButton()
/** Setup the Message Header Table. Could be made protected for extensibility. */
private void setupTable()
{
tableModel = new SortedPressTM();
msgTable = new JTable(tableModel);
msgTable.setDragEnabled(false);
msgTable.setRowSelectionAllowed(true);
msgTable.setColumnSelectionAllowed(false);
msgTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
msgTable.setShowGrid(false);
msgTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
PMCellRenderer cellRenderer = new PMCellRenderer(msgTable);
msgTable.setDefaultRenderer(Object.class, cellRenderer);
SortHeaderRenderer renderer = new SortHeaderRenderer();
TableColumnModel model = msgTable.getColumnModel();
for(int i=0; i<HEADERS.length; i++)
{
model.getColumn(i).setHeaderRenderer(renderer);
}
final JTableHeader header = msgTable.getTableHeader();
header.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
int col = header.columnAtPoint(e.getPoint());
tableModel.sortByColumn(col);
}// mouseClicked()
});
ListSelectionModel rowSM = msgTable.getSelectionModel();
rowSM.addListSelectionListener(new ListSelectionListener()
{
public void valueChanged(ListSelectionEvent e)
{
//Ignore extra messages.
if(e.getValueIsAdjusting())
{
return;
}
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
if(lsm.isSelectionEmpty())
{
msgPanel.setMessage(null);
}
else
{
int selectedRow = lsm.getMinSelectionIndex();
PressMessage pm = tableModel.getRow(selectedRow);
msgPanel.setMessage(pm);
}
}
});
System.out.println("TESTING: adding example data");
Phase phase = new Phase(Phase.SeasonType.FALL, 1914, Phase.PhaseType.MOVEMENT);
tableModel.addMessage(new PMT(
"Hello there",
"this is the body of the message",
new MID("user","user"),
new MID("hello","kitty"),
phase,
true,
false
));
phase = phase.getNext();
tableModel.addMessage(new PMT(
"Hello there, assface",
"<html>This one is in HTML! <b>see what i mean?</b><p><u>this is the body of the message</u>",
new MID("hello","kitty"),
new MID("user","user"),
phase,
true,
true
));
phase = phase.getNext();
tableModel.addMessage(new PMT(
"YO! Hello there",
"this is the body of the message\nline\nline\nline\nEND",
new MID("fred","fred@fredo.com"),
new MID("jon","johnson@johnson.com"),
phase,
false,
true
));
// test
msgPanel.setMessage(new PMT(
"Hello there, assface",
"this is the body of the message.\n How do you like it? \n I thought so.",
new MID("hello","kitty"),
new MID("user","user"),
phase,
true,
true
));
System.out.println("END of example data");
}// setupTable()
// TESTING ONLY
private class PMT implements PressMessage
{
String subj;
String body;
MID from;
MID to;
Phase phase;
boolean isReplied;
boolean isRead;
public PMT(String subj, String body, MID from, MID to, Phase phase, boolean isReplied, boolean isRead)
{
this.subj = subj;
this.body = body;
this.from = from;
this.to = to;
this.phase = phase;
this.isReplied = isReplied;
this.isRead = isRead;
}
/** Message sender. May never be null. */
public MID getFrom() { return from; }
/** Message recipients. Never null. May be zero-length if broadcast. */
public MID[] getTo() { return new MID[] {to, to}; }
/** Message subject. May be null if there is no subject. */
public String getSubject() { return subj; }
/** Message body. Never null; may be empty (""). */
public String getMessage() { return body; }
/**
* Phase during which message was sent.
* May be null if sent before a game has started, or after
* a game has ended.
*/
public Phase getPhase() { return phase; }
/** Time when message arrived. 0 if unknown. */
public long getTimeReceived() { return System.currentTimeMillis(); }
/** Time when message was sent. 0 if unknown. */
public long getTimeSent() { return System.currentTimeMillis(); }
/** True if this message has been read */
public boolean isRead() { return isRead; }
/** True if this message has been replied to */
public boolean isRepliedTo() { return isReplied; }
/** Set whether this message has been read */
public void setRead(boolean value) {}
/** Set whether this message has been replied to */
public void setRepliedTo(boolean value){}
}
// END TESTING
/**
* Inner TableModel class that takes PressMessages
* columnizes them, and handles sorting. It is not
* editable.
* <p>
* Columns are:
* <ol>
* <li>Reply-indicator: Boolean</li>
* <li>Subject: String</li>
* <li>Sender: MID</li>
* <li>Date/Time: Long</li>
* <li>Phase: Phase</li>
* </ol>
*
*/
private class SortedPressTM extends AbstractTableModel
{
private final int NUM_COLS = 5;
private final java.util.List data;
private int lastSortedCol = -1;
private boolean isLastSortedAscending = false;
/** Create a Sorted Press Table Model */
public SortedPressTM()
{
data = Collections.synchronizedList(new ArrayList(50));
}// SortedPressTM
/** Add a single PressMessage. */
public void addMessage(PressMessage pm)
{
data.add(pm);
resort();
}// addMessage()
/** Add multiple PressMessages */
public void addMessages(PressMessage[] pms)
{
for(int i=0; i<pms.length; i++)
{
data.add(pms[i]);
}
resort();
}// addMessages()
/** Remove a single PressMessage */
public void removeMessage(PressMessage pm)
{
data.remove(pm);
resort();
}// removeMessage()
/** Remove multiple PressMessages */
public void removeMessages(PressMessage[] pms)
{
data.removeAll( Arrays.asList(pms) );
resort();
}// removeMessages()
/** Get the PressMessage for a Row */
public PressMessage getRow(int row)
{
return (PressMessage) data.get(row);
}// getRow()
/** Get the value at the corresponding row and column. */
public Object getValueAt(int row, int col)
{
PressMessage pm = (PressMessage) data.get(row);
switch(col)
{
case 0:
return Boolean.valueOf(pm.isRepliedTo());
case 1:
return pm.getSubject();
case 2:
return pm.getFrom();
case 3:
return new Date(pm.getTimeSent());
case 4:
return pm.getPhase();
default:
throw new IllegalArgumentException("Invalid column: "+col);
}
}// getValueAt()
/** Return the column name */
public String getColumnName(int column)
{
return HEADERS[column];
}// getColumnName()
/** Always returns Object.class so we can use our fancy cell renderer */
public Class getColumnClass(int columnIndex)
{
return Object.class;
}// getColumnClass()
/** Returns the number of rows */
public int getRowCount()
{
return data.size();
}// getRowCount()
/** Returns the number of columns (constant) */
public int getColumnCount()
{
return NUM_COLS;
}// getColumnCount()
/**
* Returns the currently sorted column, or -1 if
* no column is being sorted.
*/
public int getCurrentSortedColumn()
{
return lastSortedCol;
}// getCurrentSortedColumn()
/** Returns the currently-sorted-column direction */
public boolean isCurrentSortAscending()
{
return isLastSortedAscending;
}// isCurrentSortAscending()
/**
* Resort the table, according the the last sorted
* column and order (ascending/descending).
*/
public void resort()
{
if(lastSortedCol >= 0)
{
sortByColumn(lastSortedCol, isLastSortedAscending);
}
}// resort()
/**
* Sort the table by the given column, but determines the
* direction all by itself.
*/
public void sortByColumn(int column)
{
if(column < 0 || column >= getColumnCount())
{
return;
}
if(lastSortedCol == column)
{
isLastSortedAscending = !isLastSortedAscending;
sort(column, isLastSortedAscending);
}
else
{
// new sort; make it ascending
isLastSortedAscending = true;
lastSortedCol = column;
sort(column, isLastSortedAscending);
}
}// sortByColumn()
/**
* Sort the table by the given column, in the given direction.
* This assumes the given column is, in fact, Comparable or
* sortable. If it is not, this will do nothing.
*/
public void sortByColumn(int column, boolean isAscending)
{
lastSortedCol = column;
isLastSortedAscending = isAscending;
sort(column, isAscending);
}// sortByColumn()
/** Sort implementation */
private void sort(int col, boolean isAscending)
{
Comparator comparator = new PressMessageComparator(col, isAscending);
Collections.sort(data, comparator);
}// sort()
}// inner class SortedPressTM
/** Render the sorted columns with an up/down arrow. */
private class SortHeaderRenderer extends DefaultTableCellRenderer
{
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
JLabel c = (JLabel) super.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
final JTableHeader header = table.getTableHeader();
c.setHorizontalAlignment(SwingConstants.CENTER);
c.setHorizontalTextPosition(SwingConstants.LEFT);
c.setForeground(header.getForeground());
c.setBackground(header.getBackground());
c.setFont(header.getFont());
c.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
c.setBackground(UIManager.getColor("control"));
if(column == tableModel.getCurrentSortedColumn())
{
// paint an arrow, in the proper direction
if(tableModel.isCurrentSortAscending())
{
setIcon(BevelArrowIcon.UP);
}
else
{
setIcon(BevelArrowIcon.DOWN);
}
}
else
{
// paint NO arrow
c.setIcon(null);
}
return c;
}// getTableCellRendererComponent()
}// inner class SortHeaderRenderer
/**
* Table Cell Renderer
* handles read/unread message flag
* can do more, too...
*/
private class PMCellRenderer extends DefaultTableCellRenderer
{
private final Font boldFont;
private final DateFormat dtInstance;
/** Create the PMCellRenderer */
public PMCellRenderer(JTable table)
{
boldFont = table.getFont().deriveFont(Font.BOLD);
dtInstance = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
}// PMCellRenderer()
/** Render. Assumes tableModel is a SortedPressTM, and knows the columns, too. */
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
{
PressMessage pm = ((SortedPressTM) table.getModel()).getRow(row);
// for when we add color
Color fgColor = null;
Color bgColor = null;
if(isSelected)
{
setForeground((fgColor == null) ? table.getForeground() : fgColor);
setBackground(table.getSelectionBackground());
}
else
{
setForeground((fgColor == null) ? table.getForeground() : fgColor);
setBackground((bgColor == null) ? table.getBackground() : bgColor);
}
// set Boldness if read or unread.
setFont( (pm.isRead()) ? table.getFont() : boldFont );
// set text
setTextValue(value);
return this;
}// getTableCellRendererComponent()
/** Handle any null values and special objects. */
private void setTextValue(Object value)
{
String text = "";
if(value instanceof Date)
{
// format date
text = dtInstance.format((Date) value);
}
else if(value instanceof Boolean)
{
if(value == Boolean.TRUE)
{
text = " + ";
}
}
else
{
text = (value != null) ? value.toString() : text;
}
setText(text);
}// setTextValue()
}// inner class PMCellRenderer
/** Generic Reversible Comparator, with null handling. */
private class PressMessageComparator implements Comparator
{
private int col = -1;
private boolean isAscending = false;
public PressMessageComparator(int column, boolean isAscending)
{
this.col = column;
this.isAscending = isAscending;
}// PressMessageComparator()
/** Compare! */
public int compare(Object o1, Object o2)
{
int val = 0;
PressMessage pm1 = (PressMessage) o1;
PressMessage pm2 = (PressMessage) o2;
Object cmp1 = null;
Object cmp2 = null;
switch(col)
{
case 0:
// special boolean handling
if(pm1.isRepliedTo() == pm2.isRepliedTo())
{
val = 0;
}
else if(pm1.isRepliedTo())
{
val = 1;
}
else
{
val = -1;
}
if(!isAscending)
{
val = -val;
}
return val;
case 1:
cmp1 = pm1.getSubject();
cmp2 = pm2.getSubject();
break;
case 2:
cmp1 = pm1.getFrom().getNick();
cmp2 = pm2.getFrom().getNick();
break;
case 3:
cmp1 = new Date(pm1.getTimeSent());
cmp2 = new Date(pm2.getTimeSent());
break;
case 4:
cmp1 = pm1.getPhase();
cmp2 = pm2.getPhase();
break;
default:
throw new IllegalStateException();
}
// handle nulls
if(cmp1 == null && cmp2 == null)
{
val = 0;
}
else if(cmp1 == null)
{
val = -1;
}
else if(cmp2 == null)
{
val = 1;
}
else
{
val = ((Comparable) cmp1).compareTo(cmp2);
}
if(!isAscending)
{
val = -val;
}
return val;
}// compare()
/**
* Indicates if the *Comparator* is equal to another Comparator
*/
public boolean equals(Object obj)
{
return false; // for safety.
}// equals()
}// inner class PressMessageComparator()
/** Draws a beveled arrow as an Icon */
private static class BevelArrowIcon implements Icon
{
/** UP icon */
public static final BevelArrowIcon UP = new BevelArrowIcon(true);
/** DOWN icon */
public static final BevelArrowIcon DOWN = new BevelArrowIcon(false);
private static final int DEFAULT_SIZE = 11;
private Color edge1;
private Color edge2;
private Color fill;
private int size;
private boolean isUp;
/** Create a BevelArrowIcon */
public BevelArrowIcon(boolean isUp)
{
this.edge1 = UIManager.getColor("controlHighlight");
this.edge2 = UIManager.getColor("controlShadow");
this.fill = UIManager.getColor("control");
this.size = DEFAULT_SIZE;
this.isUp = isUp;
}
/** Paint the Icon */
public void paintIcon(Component c, Graphics g, int x, int y)
{
if(isUp)
{
drawDownArrow(g, x, y);
}
else
{
drawUpArrow(g, x, y);
}
}// paintIcon()
/** Width */
public int getIconWidth()
{
return size;
}// getIconWidth()
/** Height */
public int getIconHeight()
{
return size;
}// getIconHeight()
/** Down-arrow */
private void drawDownArrow(Graphics g, int xo, int yo)
{
g.setColor(edge1);
g.drawLine(xo, yo, xo+size-1, yo);
g.drawLine(xo, yo+1, xo+size-3, yo+1);
g.setColor(edge2);
g.drawLine(xo+size-2, yo+1, xo+size-1, yo+1);
int x = xo+1;
int y = yo+2;
int dx = size-6;
while (y+1 < yo+size)
{
g.setColor(edge1);
g.drawLine(x, y, x+1, y);
g.drawLine(x, y+1, x+1, y+1);
if (0 < dx)
{
g.setColor(fill);
g.drawLine(x+2, y, x+1+dx, y);
g.drawLine(x+2, y+1, x+1+dx, y+1);
}
g.setColor(edge2);
g.drawLine(x+dx+2, y, x+dx+3, y);
g.drawLine(x+dx+2, y+1, x+dx+3, y+1);
x += 1;
y += 2;
dx -= 2;
}
g.setColor(edge1);
g.drawLine(xo+(size/2), yo+size-1, xo+(size/2), yo+size-1);
}// drawDownArrow()
private void drawUpArrow(Graphics g, int xo, int yo)
{
g.setColor(edge1);
int x = xo+(size/2);
g.drawLine(x, yo, x, yo);
x--;
int y = yo+1;
int dx = 0;
while (y+3 < yo+size)
{
g.setColor(edge1);
g.drawLine(x, y, x+1, y);
g.drawLine(x, y+1, x+1, y+1);
if (0 < dx)
{
g.setColor(fill);
g.drawLine(x+2, y, x+1+dx, y);
g.drawLine(x+2, y+1, x+1+dx, y+1);
}
g.setColor(edge2);
g.drawLine(x+dx+2, y, x+dx+3, y);
g.drawLine(x+dx+2, y+1, x+dx+3, y+1);
x -= 1;
y += 2;
dx += 2;
}
g.setColor(edge1);
g.drawLine(xo, yo+size-3, xo+1, yo+size-3);
g.setColor(edge2);
g.drawLine(xo+2, yo+size-2, xo+size-1, yo+size-2);
g.drawLine(xo, yo+size-1, xo+size, yo+size-1);
}// drawUpArrow()
}// inner class BevelArrowIcon
/**
* Display a Message
* <p>
* Once created, the message can be changed via setMessage().
* setMessage(null) will clear the panel.
*/
private class MessagePanel extends JPanel
{
private JEditorPane body;
private JTextField subject;
private JTextField from;
private JTextField date;
private JTextField to;
public MessagePanel()
{
JPanel top = setupTop();
setupBody();
JScrollPane jsp = new XJScrollPane(body);
jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
setLayout(new BorderLayout());
add(top, BorderLayout.NORTH);
add(jsp, BorderLayout.CENTER);
}// MessagePanel()
public void setMessage(PressMessage pm)
{
if(pm == null)
{
subject.setText("");
from.setText("");
date.setText("");
to.setText("");
body.setText("");
}
else
{
// subject
subject.setText(pm.getSubject());
// from
from.setText(pm.getFrom().getNickAndName());
// to (may be multiple); separate by commas.
// format: nick (name), nick2 (name2). Omit name if null.
// if none, indicate broadcast.
//
if(pm.getTo().length > 0)
{
StringBuffer sb = new StringBuffer(128);
for(int i=0; i<pm.getTo().length; i++)
{
MID mid = pm.getTo()[i];
// print nick+name
sb.append(mid.getNickAndName());
// append a comma+space, if not the last.
if(i < pm.getTo().length - 1)
{
sb.append(", ");
}
}
to.setText(sb.toString());
}
else
{
to.setText("All Players [Broadcast]"); // I18N this!!!!
}
// set date and phase
StringBuffer dt = new StringBuffer(80);
if(pm.getTimeSent() != 0)
{
dt.append(DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.SHORT).format(new Date(pm.getTimeSent())));
}
dt.append(" ");
if(pm.getPhase() != null)
{
dt.append("(");
dt.append(pm.getPhase().getSeasonType());
dt.append(" ");
dt.append(pm.getPhase().getYearType());
dt.append(", ");
dt.append(pm.getPhase().getPhaseType());
dt.append(")");
}
else
{
dt.append("(sent before or after game)"); // i18n this too!!
}
date.setText(dt.toString());
// set body content type depending upon if starts with <html>
// or not.
String msg = pm.getMessage();
if(msg.startsWith("<html>") || msg.startsWith("<HTML>"))
{
body.setContentType("text/html");
}
else
{
body.setContentType("text/plain");
}
body.setText(pm.getMessage());
}
}// setMessage()
/** Basic layout of top panel */
private JPanel setupTop()
{
JPanel top = new JPanel();
final int w1[] = { 20, 0, 5, 0, 5 };
final int h1[] = { 5, 0, 0, 0, 0, 5 };
HIGLayout hl = new HIGLayout(w1, h1);
hl.setColumnWeight(4, 1);
top.setLayout(hl);
HIGConstraints c = new HIGConstraints();
// add ":" after labels
top.add(new JLabel(Utils.getLocalString(LABEL_SUBJECT)+":"), c.rcwh(2,2,1,1,"r"));
top.add(new JLabel(Utils.getLocalString(LABEL_FROM)+":"), c.rcwh(3,2,1,1,"r"));
top.add(new JLabel(Utils.getLocalString(LABEL_DATE)+":"), c.rcwh(4,2,1,1,"r"));
top.add(new JLabel(Utils.getLocalString(LABEL_TO)+":"), c.rcwh(5,2,1,1,"r"));
subject = makeTextField();
from = makeTextField();
date = makeTextField();
to = makeTextField();
// subject font is always bold.
subject.setFont( subject.getFont().deriveFont(Font.BOLD) );
top.add(subject, c.rcwh(2,4,1,1,"l"));
top.add(from, c.rcwh(3,4,1,1,"l"));
top.add(date, c.rcwh(4,4,1,1,"l"));
top.add(to, c.rcwh(5,4,1,1,"l"));
return top;
}// setupTop()
private void setupBody()
{
body = new JEditorPane();
body.setEditable(false);
}// setupBody()
private JTextField makeTextField()
{
JTextField jtf = new JTextField(40);
jtf.setBackground(UIManager.getColor("Label.text"));
jtf.setEditable(false);
jtf.setBorder(null);
return jtf;
}// makeTextField()
}// inner class MessagePanel
}// class PressDialog