SwingDisplay.java 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. package gnu.kawa.swingviews;
  2. import gnu.kawa.models.*;
  3. import gnu.kawa.models.Box;
  4. import javax.swing.*;
  5. import javax.swing.text.*;
  6. import java.awt.Component;
  7. import java.awt.event.*;
  8. import gnu.mapping.Procedure;
  9. public class SwingDisplay extends Display
  10. {
  11. static final SwingDisplay instance = new SwingDisplay();
  12. public static Display getInstance() { return instance; }
  13. public Window makeWindow ()
  14. {
  15. SwingFrame window = new SwingFrame(null, null, null);
  16. window.display = this;
  17. return window;
  18. }
  19. public void addButton (Button model, Object where)
  20. {
  21. addView(new SwingButton(model), where);
  22. }
  23. public void addLabel (Label model, Object where)
  24. {
  25. addView(new SwingLabel(model), where);
  26. }
  27. public void addImage (DrawImage model, Object where)
  28. {
  29. addView(new JLabel(new ImageIcon(model.getImage())), where);
  30. }
  31. public void addText (Text model, Object where)
  32. {
  33. // It seems silly that we have to specify an initial value when
  34. // it's part of the Document, but otherwise Swing doesn't update the view.
  35. // This means that the text in model.buffer gets deleted and re-inserted,
  36. // which causes any existing positions to collapse. FIXME.
  37. addView(new JTextField(getSwingDocument(model), model.getText(), 50),
  38. where);
  39. }
  40. private static java.util.WeakHashMap documents = null;
  41. static synchronized javax.swing.text.Document getSwingDocument (Text model)
  42. {
  43. if (documents == null)
  44. documents = new java.util.WeakHashMap();
  45. Object existing = documents.get(model);
  46. if (existing != null)
  47. return (javax.swing.text.Document) existing;
  48. javax.swing.text.Document doc
  49. = new javax.swing.text.PlainDocument(new SwingContent(model.buffer));
  50. documents.put(model, doc);
  51. return doc;
  52. }
  53. public void addBox (Box model, Object where)
  54. {
  55. addView(new SwingBox(model, this), where);
  56. }
  57. public void addSpacer (Spacer model, Object where)
  58. {
  59. addView(new javax.swing.Box.Filler(model.getMinimumSize(),
  60. model.getPreferredSize(),
  61. model.getMaximumSize()),
  62. where);
  63. }
  64. public void addView (Object view, Object where)
  65. {
  66. ((java.awt.Container) where).add((Component) view);
  67. }
  68. public static ActionListener makeActionListener (Object command)
  69. {
  70. if (command instanceof ActionListener)
  71. return (ActionListener) command;
  72. return new ProcActionListener((Procedure) command);
  73. }
  74. public Model coerceToModel (Object component)
  75. {
  76. if (component instanceof Component)
  77. return new ComponentModel((Component) component);
  78. if (component instanceof Picture)
  79. // Kludge - should create a Viewable. FIXME.
  80. return new ComponentModel(new SwingPicture((Picture) component));
  81. return super.coerceToModel(component);
  82. }
  83. }
  84. class ProcActionListener implements ActionListener
  85. {
  86. Procedure proc;
  87. public ProcActionListener (Procedure proc) { this.proc = proc; }
  88. public void actionPerformed (ActionEvent e)
  89. {
  90. try
  91. {
  92. proc.apply1(e);
  93. }
  94. catch (Throwable ex)
  95. {
  96. gnu.mapping.WrappedException.rethrow(ex);
  97. }
  98. }
  99. }
  100. class SwingBox
  101. extends javax.swing.Box
  102. implements ModelListener
  103. {
  104. Box model;
  105. public SwingBox (Box model, Display display)
  106. {
  107. super(model.getAxis());
  108. model.addListener(this);
  109. Viewable cellSpacing = model.getCellSpacing();
  110. int n = model.getComponentCount();
  111. for (int i = 0; i < n; i++)
  112. {
  113. if (i > 0 && cellSpacing != null)
  114. cellSpacing.makeView(display, this);
  115. model.getComponent(i).makeView(display, this);
  116. }
  117. }
  118. public void modelUpdated (Model model, Object key)
  119. {
  120. }
  121. }
  122. class SwingLabel
  123. extends JLabel
  124. implements ModelListener
  125. {
  126. Label model;
  127. public SwingLabel (Label model)
  128. {
  129. this.model = model;
  130. String text = model.getText();
  131. if (text != null)
  132. super.setText(text);
  133. model.addListener(this);
  134. }
  135. public void modelUpdated (Model model, Object key)
  136. {
  137. if (key == "text" && model == this.model)
  138. super.setText(this.model.getText());
  139. }
  140. public void setText(String text)
  141. {
  142. if (model == null)
  143. super.setText(text);
  144. else
  145. model.setText(text);
  146. }
  147. }
  148. /** A Model wrapper around a Swing/AWT Component. */
  149. class ComponentModel extends Model
  150. {
  151. Component component;
  152. public ComponentModel (Component component)
  153. {
  154. this.component = component;
  155. }
  156. public void makeView (Display display, Object where)
  157. {
  158. display.addView(component, where);
  159. }
  160. }